commit d397789bb7661536f5edb844ba00a26160433050 Author: Phantop Date: Thu Dec 14 17:21:22 2023 -0500 initial commit diff --git a/Base/Basics.cs b/Base/Basics.cs new file mode 100644 index 0000000..863a013 --- /dev/null +++ b/Base/Basics.cs @@ -0,0 +1,17 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace ProjectZ.Base +{ + internal class Basics + { + public static void DrawStringCenter(SpriteFont font, string text, Rectangle position, Color color) + { + var textSize = font.MeasureString(text); + var drawPosition = new Vector2( + (int)(position.X + position.Width / 2 - textSize.X / 2), + (int)(position.Y + position.Height / 2 - textSize.Y / 2)); + Game1.SpriteBatch.DrawString(font, text, drawPosition, color); + } + } +} diff --git a/Base/Box.cs b/Base/Box.cs new file mode 100644 index 0000000..ea2c392 --- /dev/null +++ b/Base/Box.cs @@ -0,0 +1,73 @@ +using Microsoft.Xna.Framework; + +namespace ProjectZ.Base +{ + public struct Box + { + public static readonly Box Empty = new Box(); + + public float X; + public float Y; + public float Z; + + public float Width; + public float Height; + public float Depth; + + public float Left => X; + public float Right => X + Width; + + public float Back => Y; + public float Front => Y + Height; + + public float Top => Z + Depth; + public float Bottom => Z; + + public Vector2 Center => new Vector2(X + Width / 2, Y + Height / 2); + + public RectangleF Rectangle() => new RectangleF(X, Y, Width, Height); + + public Box(float x, float y, float z, float width, float height, float depth) + { + X = x; + Y = y; + Z = z; + + Width = width; + Height = height; + Depth = depth; + } + + public bool Intersects(Box value) + { + return value.Left < Right && Left < value.Right && + value.Back < Front && Back < value.Front && + value.Bottom < Top && Bottom < value.Top; + } + + public bool Contains(Box value) + { + return Left <= value.Left && value.Right <= Right && + Back <= value.Back && value.Front <= Front && + Bottom <= value.Bottom && value.Top <= Top; + } + + public bool Contains(Vector2 value) + { + return Left <= value.X && value.X <= Right && + Back <= value.Y && value.Y <= Front; + } + + public static bool operator ==(Box a, Box b) + { + return a.X == b.X && a.Y == b.Y && a.Z == b.Z && + a.Width == b.Width && a.Height == b.Height && a.Depth == b.Depth; + } + + public static bool operator !=(Box a, Box b) + { + return a.X != b.X || a.Y != b.Y || a.Z != b.Z && + a.Width != b.Width || a.Height != b.Height || a.Depth != b.Depth; + } + } +} diff --git a/Base/DoubleAverage.cs b/Base/DoubleAverage.cs new file mode 100644 index 0000000..ee6f4f5 --- /dev/null +++ b/Base/DoubleAverage.cs @@ -0,0 +1,28 @@ +using System.Linq; + +namespace ProjectZ.Base +{ + public class DoubleAverage + { + public double Average; + + private readonly double[] _timeCounts; + private int _currentIndex; + + public DoubleAverage(int size) + { + _timeCounts = new double[size]; + } + + public void AddValue(double value) + { + _timeCounts[_currentIndex] = value; + + _currentIndex++; + if (_currentIndex >= _timeCounts.Length) + _currentIndex = 0; + + Average = _timeCounts.Average(); + } + } +} diff --git a/Base/InputHandler.cs b/Base/InputHandler.cs new file mode 100644 index 0000000..debf8d2 --- /dev/null +++ b/Base/InputHandler.cs @@ -0,0 +1,376 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; + +namespace ProjectZ.Base +{ + #region InputCharacter + + internal class InputCharacter + { + private readonly string _upper; + private readonly string _lower; + private readonly string _alt; + + private readonly Keys _code; + + public InputCharacter(string upper, string lower, string alt, Keys code) + { + _upper = upper; + _lower = lower; + _alt = alt; + _code = code; + } + + public InputCharacter(string upper, string lower, Keys code) : + this(upper, lower, lower, code) + { } + + public string ReturnCharacter(bool shiftDown, bool altDown) + { + return altDown ? _alt : shiftDown ? _upper : _lower; + } + + public Keys ReturnKey() + { + return _code; + } + } + #endregion + + internal class InputHandler : GameComponent + { + private static List _alphabet; + + public static KeyboardState KeyboardState => _keyboardState; + + public static KeyboardState LastKeyboardState => _lastKeyboardState; + + public static MouseState MouseState => _mouseState; + + public static MouseState LastMousState => _lastMouseState; + + private static KeyboardState _keyboardState; + private static KeyboardState _lastKeyboardState; + + private static MouseState _mouseState; + private static MouseState _lastMouseState; + + private static GamePadState _gamePadState; + private static GamePadState _lastGamePadState; + private static float _gamePadAccuracy = 0.2f; + + #region Constructor Region + + public InputHandler(Game game) + : base(game) + { + _keyboardState = Keyboard.GetState(); + _mouseState = Mouse.GetState(); + + _alphabet = new List(); + + // TODO_End: Important! Replace this method to support different keyboard layouts + /* Alphabet. */ + _alphabet.Add(new InputCharacter("A", "a", Keys.A)); + _alphabet.Add(new InputCharacter("B", "b", Keys.B)); + _alphabet.Add(new InputCharacter("C", "c", Keys.C)); + _alphabet.Add(new InputCharacter("D", "d", Keys.D)); + _alphabet.Add(new InputCharacter("E", "e", "€", Keys.E)); + _alphabet.Add(new InputCharacter("F", "f", Keys.F)); + _alphabet.Add(new InputCharacter("G", "g", Keys.G)); + _alphabet.Add(new InputCharacter("H", "h", Keys.H)); + _alphabet.Add(new InputCharacter("I", "i", Keys.I)); + _alphabet.Add(new InputCharacter("J", "j", Keys.J)); + _alphabet.Add(new InputCharacter("K", "k", Keys.K)); + _alphabet.Add(new InputCharacter("L", "l", Keys.L)); + _alphabet.Add(new InputCharacter("M", "m", "µ", Keys.M)); + _alphabet.Add(new InputCharacter("N", "n", Keys.N)); + _alphabet.Add(new InputCharacter("O", "o", Keys.O)); + _alphabet.Add(new InputCharacter("P", "p", Keys.P)); + _alphabet.Add(new InputCharacter("Q", "q", "@", Keys.Q)); + _alphabet.Add(new InputCharacter("R", "r", Keys.R)); + _alphabet.Add(new InputCharacter("S", "s", Keys.S)); + _alphabet.Add(new InputCharacter("T", "t", Keys.T)); + _alphabet.Add(new InputCharacter("U", "u", Keys.U)); + _alphabet.Add(new InputCharacter("V", "v", Keys.V)); + _alphabet.Add(new InputCharacter("W", "w", Keys.W)); + _alphabet.Add(new InputCharacter("X", "x", Keys.X)); + _alphabet.Add(new InputCharacter("Y", "y", Keys.Y)); + _alphabet.Add(new InputCharacter("Z", "z", Keys.Z)); + + /* Dezimalzahlen. */ + _alphabet.Add(new InputCharacter("!", "1", Keys.D1)); + _alphabet.Add(new InputCharacter("\"", "2", "²", Keys.D2)); + _alphabet.Add(new InputCharacter("§", "3", "³", Keys.D3)); + _alphabet.Add(new InputCharacter("$", "4", Keys.D4)); + _alphabet.Add(new InputCharacter("%", "5", Keys.D5)); + _alphabet.Add(new InputCharacter("&", "6", "|", Keys.D6)); + _alphabet.Add(new InputCharacter("/", "7", "{", Keys.D7)); + _alphabet.Add(new InputCharacter("(", "8", "[", Keys.D8)); + _alphabet.Add(new InputCharacter(")", "9", "]", Keys.D9)); + _alphabet.Add(new InputCharacter("=", "0", "}", Keys.D0)); + + + /* Sonderelemente. */ + _alphabet.Add(new InputCharacter(" ", " ", Keys.Space)); + //InputHandler.alphabet.Add(new InputCharacter("Ü", "ü", Keys.OemSemicolon)); + //InputHandler.alphabet.Add(new InputCharacter("Ö", "ö", Keys.OemTilde)); + //InputHandler.alphabet.Add(new InputCharacter("Ä", "ä", Keys.OemQuotes)); + _alphabet.Add(new InputCharacter(";", ",", Keys.OemComma)); + _alphabet.Add(new InputCharacter("*", "+", "~", Keys.OemPlus)); + _alphabet.Add(new InputCharacter("'", "#", Keys.OemQuestion)); + _alphabet.Add(new InputCharacter(":", ".", Keys.OemPeriod)); + _alphabet.Add(new InputCharacter("_", "-", Keys.OemMinus)); + _alphabet.Add(new InputCharacter("?", "", Keys.OemOpenBrackets)); + _alphabet.Add(new InputCharacter(">", "<", "|", Keys.OemBackslash)); + //InputHandler.alphabet.Add(new InputCharacter("`", "´", Keys.OemCloseBrackets)); + + //InputHandler.alphabet.Add(new InputCharacter("°", "^", Keys.OemPipe)); + } + + #endregion + + public override void Update(GameTime gameTime) + { + _lastKeyboardState = _keyboardState; + _keyboardState = Keyboard.GetState(); + + _lastMouseState = _mouseState; + _mouseState = Mouse.GetState(); + + _lastGamePadState = _gamePadState; + _gamePadState = GamePad.GetState(0); + + // if the game was not active the last mousestate is uninteresting + if (!Game1.WasActive) + ResetInputState(); + } + + /// + /// set the last input state to the current state + /// + public static void ResetInputState() + { + _lastKeyboardState = _keyboardState; + _lastMouseState = _mouseState; + _lastGamePadState = _gamePadState; + } + + public static bool LastKeyDown(Keys key) + { + return _lastKeyboardState.IsKeyDown(key); + } + + public static bool KeyDown(Keys key) + { + return _keyboardState.IsKeyDown(key); + } + + public static bool KeyPressed(Keys key) + { + return _keyboardState.IsKeyDown(key) && + _lastKeyboardState.IsKeyUp(key); + } + + public static bool KeyReleased(Keys key) + { + return _keyboardState.IsKeyUp(key) && + _lastKeyboardState.IsKeyDown(key); + } + + public static List GetPressedKeys() + { + var pressedKeys = new List(); + var downKeys = _keyboardState.GetPressedKeys(); + + for (var i = 0; i < downKeys.Length; i++) + { + if (KeyPressed(downKeys[i])) + pressedKeys.Add(downKeys[i]); + } + + return pressedKeys; + } + + public static List GetPressedButtons() + { + var pressedKeys = new List(); + + foreach (Buttons button in Enum.GetValues(typeof(Buttons))) + { + if (GamePadPressed(button)) + pressedKeys.Add(button); + } + + return pressedKeys; + } + + public static bool LastGamePadDown(Buttons button) + { + return _lastGamePadState.IsButtonDown(button); + } + + public static bool GamePadDown(Buttons button) + { + return _gamePadState.IsButtonDown(button); + } + + public static bool GamePadPressed(Buttons button) + { + return _gamePadState.IsButtonDown(button) && + _lastGamePadState.IsButtonUp(button); + } + + public static bool GamePadReleased(Buttons button) + { + return _gamePadState.IsButtonUp(button) && + _lastGamePadState.IsButtonDown(button); + } + + + public static bool GamePadLeftStick(Vector2 dir) + { + return ((dir.X < 0 && _gamePadState.ThumbSticks.Left.X < -_gamePadAccuracy) || (dir.X > 0 && _gamePadState.ThumbSticks.Left.X > _gamePadAccuracy) || + (dir.Y < 0 && _gamePadState.ThumbSticks.Left.Y < -_gamePadAccuracy) || (dir.Y > 0 && _gamePadState.ThumbSticks.Left.Y > _gamePadAccuracy)); + } + public static bool LastGamePadLeftStick(Vector2 dir) + { + return ((dir.X < 0 && _lastGamePadState.ThumbSticks.Left.X < -_gamePadAccuracy) || (dir.X > 0 && _lastGamePadState.ThumbSticks.Left.X > _gamePadAccuracy) || + (dir.Y < 0 && _lastGamePadState.ThumbSticks.Left.Y < -_gamePadAccuracy) || (dir.Y > 0 && _lastGamePadState.ThumbSticks.Left.Y > _gamePadAccuracy)); + } + + public static bool GamePadRightStick(Vector2 dir) + { + return ((dir.X < 0 && _gamePadState.ThumbSticks.Right.X < -_gamePadAccuracy) || (dir.X > 0 && _gamePadState.ThumbSticks.Right.X > _gamePadAccuracy) || + (dir.Y < 0 && _gamePadState.ThumbSticks.Right.Y < -_gamePadAccuracy) || (dir.Y > 0 && _gamePadState.ThumbSticks.Right.Y > _gamePadAccuracy)); + } + + #region Mouse Region + + //scroll + public static bool MouseWheelUp() + { + return _mouseState.ScrollWheelValue > _lastMouseState.ScrollWheelValue; + } + public static bool MouseWheelDown() + { + return _mouseState.ScrollWheelValue < _lastMouseState.ScrollWheelValue; + } + + //down + public static bool MouseLeftDown() + { + return _mouseState.LeftButton == ButtonState.Pressed; + } + public static bool MouseLeftDown(Rectangle rectangle) + { + return MouseIntersect(rectangle) && MouseLeftDown(); + } + public static bool MouseRightDown() + { + return _mouseState.RightButton == ButtonState.Pressed; + } + public static bool MouseMiddleDown() + { + return _mouseState.MiddleButton == ButtonState.Pressed; + } + + //start + public static bool MouseLeftStart() + { + return _mouseState.LeftButton == ButtonState.Pressed && _lastMouseState.LeftButton == ButtonState.Released; + } + public static bool MouseRightStart() + { + return _mouseState.RightButton == ButtonState.Pressed && _lastMouseState.RightButton == ButtonState.Released; + } + public static bool MouseMiddleStart() + { + return _mouseState.MiddleButton == ButtonState.Pressed && _lastMouseState.MiddleButton == ButtonState.Released; + } + + //released + public static bool MouseLeftReleased() + { + return _mouseState.LeftButton == ButtonState.Released && _lastMouseState.LeftButton == ButtonState.Pressed; + } + public static bool MouseRightReleased() + { + return _mouseState.RightButton == ButtonState.Released && _lastMouseState.RightButton == ButtonState.Pressed; + } + + //pressed + public static bool MouseLeftPressed() + { + return _mouseState.LeftButton == ButtonState.Pressed && _lastMouseState.LeftButton == ButtonState.Released; + } + public static bool MouseLeftPressed(Rectangle rectangle) + { + return rectangle.Contains(MousePosition()) && MouseLeftPressed(); + } + + public static bool MouseRightPressed() + { + return _mouseState.RightButton == ButtonState.Pressed && _lastMouseState.RightButton == ButtonState.Released; + } + public static bool MouseRightPressed(Rectangle rectangle) + { + return MouseIntersect(rectangle) && MouseRightPressed(); + } + + public static bool MouseIntersect(Rectangle rectangle) + { + return rectangle.Contains(MousePosition()); + } + + public static Point MousePosition() + { + return _mouseState.Position; + } + public static Point LastMousePosition() + { + return _lastMouseState.Position; + } + + #endregion + + #region return text + return number + + /// + /// returns the pressed keys if they are in the InputHandler.alphabet + /// only returns one key at a time + /// + /// + public static string ReturnCharacter() + { + var shiftDown = _keyboardState.IsKeyDown(Keys.LeftShift) || _keyboardState.IsKeyDown(Keys.RightShift); + var altDown = _keyboardState.IsKeyDown(Keys.LeftAlt) || _keyboardState.IsKeyDown(Keys.RightAlt); + + //var pressedKeys = _keyboardState.GetPressedKeys(); + + foreach (var character in _alphabet) + { + if (KeyPressed(character.ReturnKey())) + return character.ReturnCharacter(shiftDown, altDown); + } + + return ""; + } + + /// + /// returns pressed number from d0-d9 and numpad0-numpad9 + /// + /// + public static int ReturnNumber() + { + for (var i = 0; i < 10; i++) + if (KeyPressed(Keys.D0 + i) || KeyPressed(Keys.NumPad0 + i)) + return i; + + return -1; + } + #endregion + } +} diff --git a/Base/ObjActivator.cs b/Base/ObjActivator.cs new file mode 100644 index 0000000..0d0b7e2 --- /dev/null +++ b/Base/ObjActivator.cs @@ -0,0 +1,47 @@ +using System; +using System.Linq.Expressions; +using System.Reflection; + +namespace ProjectZ.Base +{ + public class ObjActivator + { + public delegate T ObjectActivator(params object[] args); + + public static ObjectActivator GetActivator(ConstructorInfo ctor) + { + var paramsInfo = ctor.GetParameters(); + + //create a single param of type object[] + var param = Expression.Parameter(typeof(object[]), "args"); + + var argsExp = new Expression[paramsInfo.Length]; + + //pick each arg from the params array + //and create a typed expression of them + for (var i = 0; i < paramsInfo.Length; i++) + { + Expression index = Expression.Constant(i); + Type paramType = paramsInfo[i].ParameterType; + + Expression paramAccessorExp = Expression.ArrayIndex(param, index); + + Expression paramCastExp = Expression.Convert(paramAccessorExp, paramType); + + argsExp[i] = paramCastExp; + } + + //make a NewExpression that calls the + //ctor with the args we just created + var newExp = Expression.New(ctor, argsExp); + + //create a lambda with the New + //Expression as body and our param object[] as arg + var lambda = Expression.Lambda(typeof(ObjectActivator), newExp, param); + + //compile it + ObjectActivator compiled = (ObjectActivator)lambda.Compile(); + return compiled; + } + } +} diff --git a/Base/RectangleF.cs b/Base/RectangleF.cs new file mode 100644 index 0000000..8cc3787 --- /dev/null +++ b/Base/RectangleF.cs @@ -0,0 +1,69 @@ +using System; +using Microsoft.Xna.Framework; + +namespace ProjectZ.Base +{ + public struct RectangleF + { + public static readonly RectangleF Empty = new RectangleF(); + + public float X; + + public float Y; + + public float Width; + + public float Height; + + public float Left => X; + + public float Right => X + Width; + + public float Top => Y; + + public float Bottom => Y + Height; + + public Vector2 Center => new Vector2(X + Width / 2, Y + Height / 2); + + public RectangleF(float x, float y, float width, float height) + { + X = x; + Y = y; + Width = width; + Height = height; + } + + public bool Intersects(RectangleF second) + { + return second.Left < Right && Left < second.Right && + second.Top < Bottom && Top < second.Bottom; + } + + public bool Contains(RectangleF second) + { + return Left <= second.Left && second.Right <= Right && + Top <= second.Top && second.Bottom <= Bottom; + } + + public bool Contains(Vector2 position) + { + return Left <= position.X && position.X <= Right && + Top <= position.Y && position.Y <= Bottom; + } + + public RectangleF GetIntersection(RectangleF second) + { + var left = Math.Max(Left, second.Left); + var right = Math.Min(Right, second.Right); + var top = Math.Max(Top, second.Top); + var down = Math.Min(Bottom, second.Bottom); + + return new RectangleF(left, top, right - left, down - top); + } + + public static implicit operator RectangleF(Rectangle rectangle) + { + return new RectangleF(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height); + } + } +} diff --git a/Base/SimpleFps.cs b/Base/SimpleFps.cs new file mode 100644 index 0000000..277674e --- /dev/null +++ b/Base/SimpleFps.cs @@ -0,0 +1,47 @@ +using Microsoft.Xna.Framework; + +namespace ProjectZ.Base +{ + // source: + // http://community.monogame.net/t/a-simple-monogame-fps-display-class/10545 + + public class SimpleFps + { + public double MsgFrequency = 1.0f; + public string Msg = ""; + + private double _frames; + private double _updates; + private double _elapsed; + private double _last; + private double _now; + + /// + /// The msgFrequency here is the reporting time to update the message. + /// + public void Update(GameTime gameTime) + { + _now = gameTime.TotalGameTime.TotalSeconds; + _elapsed = _now - _last; + + if (_elapsed > MsgFrequency) + { + Msg = $"fps: {_frames / _elapsed,7:N3}" + + $"\nupdates: {_updates,3:N0}" + + $"\nframes: {_frames,3:N0}" + + $"\nelapsed time: {_elapsed,7:N3}"; + + _frames = 0; + _updates = 0; + _last = _now; + } + + _updates++; + } + + public void CountDraw() + { + _frames++; + } + } +} \ No newline at end of file diff --git a/Base/StopWatchTracker.cs b/Base/StopWatchTracker.cs new file mode 100644 index 0000000..25109c7 --- /dev/null +++ b/Base/StopWatchTracker.cs @@ -0,0 +1,56 @@ +using System.Collections.Generic; +using System.Diagnostics; + +namespace ProjectZ.Base +{ + public class StopWatchTracker + { + private readonly Dictionary _timespans = new Dictionary(); + private readonly Stopwatch _stopWatch = new Stopwatch(); + + private string _timespanName; + private readonly int _averageSize; + + public StopWatchTracker(int averageSize) + { + _averageSize = averageSize; + } + + public void Start(string timespanName) + { + if (_timespanName != null) + Stop(); + + _timespanName = timespanName; + + _stopWatch.Reset(); + _stopWatch.Start(); + } + + public void Stop() + { + if (_timespanName == null) + return; + + _stopWatch.Stop(); + + // add a new entry if the counter does not already exists + if (!_timespans.ContainsKey(_timespanName)) + _timespans.Add(_timespanName, new TickCounter(_averageSize)); + + _timespans[_timespanName].AddTick(_stopWatch.ElapsedTicks); + + _timespanName = null; + } + + public string GetString() + { + var strCounter = ""; + + foreach (var tickCounter in _timespans) + strCounter += (strCounter == "" ? "" : "\n") + tickCounter.Key + ":\t" + tickCounter.Value.AverageTime; + + return strCounter; + } + } +} diff --git a/Base/TickCount.cs b/Base/TickCount.cs new file mode 100644 index 0000000..289cce1 --- /dev/null +++ b/Base/TickCount.cs @@ -0,0 +1,28 @@ +using System.Linq; + +namespace ProjectZ.Base +{ + public class TickCounter + { + public int AverageTime; + + private readonly int[] _timeCounts; + private int _currentIndex; + + public TickCounter(int average) + { + _timeCounts = new int[average]; + } + + public void AddTick(long tick) + { + _timeCounts[_currentIndex] = (int)tick; + + _currentIndex++; + if (_currentIndex >= _timeCounts.Length) + _currentIndex = 0; + + AverageTime = (int)_timeCounts.Average(); + } + } +} diff --git a/Base/UI/UIManager.cs b/Base/UI/UIManager.cs new file mode 100644 index 0000000..4e73e2e --- /dev/null +++ b/Base/UI/UIManager.cs @@ -0,0 +1,76 @@ +using System.Collections.Generic; +using System.Linq; +using Microsoft.Xna.Framework.Graphics; + +namespace ProjectZ.Base.UI +{ + public class UiManager + { + public string CurrentScreen + { + get => _currentScreen; + set => _currentScreen = value.ToUpper(); + } + + private readonly List _elementList = new List(); + + private string _currentScreen; + + public void Update() + { + //remove elements + _elementList.RemoveAll(element => element.Remove); + + foreach (var element in _elementList) + if (element.Screens.Contains(_currentScreen)) + element.Update(); + } + + public void Draw(SpriteBatch spriteBatch) + { + for (var i = 0; i < _elementList.Count; i++) + if (_elementList[i].Screens.Contains(_currentScreen)) + if (_elementList[i].IsVisible) + _elementList[i].Draw(spriteBatch); + } + + public void DrawBlur(SpriteBatch spriteBatch) + { + for (var i = 0; i < _elementList.Count; i++) + if (_elementList[i].Screens.Contains(_currentScreen)) + if (_elementList[i].IsVisible) + _elementList[i].DrawBlur(spriteBatch); + } + + public void SizeChanged() + { + foreach (var uiElement in _elementList) + uiElement.SizeUpdate?.Invoke(uiElement); + } + + public UiElement AddElement(UiElement element) + { + if (element != null) + _elementList.Add(element); + + return element; + } + + public UiElement GetElement(string elementId) + { + //search for the elementId + for (var i = 0; i < _elementList.Count; i++) + if (_elementList[i].ElementId == elementId) + return _elementList[i]; + + return null; + } + + public void RemoveElement(string elementId, string screenId) + { + for (var i = 0; i < _elementList.Count; i++) + if (_elementList[i].ElementId.Contains(elementId) && _elementList[i].Screens.Contains(screenId)) + _elementList[i].Remove = true; + } + } +} diff --git a/Base/UI/UiButton.cs b/Base/UI/UiButton.cs new file mode 100644 index 0000000..dbca8fa --- /dev/null +++ b/Base/UI/UiButton.cs @@ -0,0 +1,71 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Things; + +namespace ProjectZ.Base.UI +{ + public class UiButton : UiElement + { + public Texture2D ButtonIcon + { + get => _buttonIcon; + set + { + _buttonIcon = value; + UpdateIconRectangle(); + } + } + public bool Marked; + + private Texture2D _buttonIcon; + private Rectangle _iconRectangle; + + public UiButton(Rectangle rectangle, SpriteFont font, string text, string elementId, string screen, UiFunction update, UiFunction click) + : base(elementId, screen) + { + Rectangle = rectangle; + Label = text; + UpdateFunction = update; + ClickFunction = click; + + Font = font; + } + + public override void Update() + { + base.Update(); + + if (!Selected || ClickFunction == null || !InputHandler.MouseLeftPressed()) return; + + ClickFunction(this); + InputHandler.ResetInputState(); + } + + private void UpdateIconRectangle() + { + var widthScale = (float)Rectangle.Width / ButtonIcon.Width; + var heightScale = (float)Rectangle.Height / ButtonIcon.Height; + + var imageScale = MathHelper.Min(widthScale, heightScale); + _iconRectangle = new Rectangle(Rectangle.X, Rectangle.Y, + (int)(ButtonIcon.Width * imageScale), (int)(ButtonIcon.Height * imageScale)); + } + + public override void Draw(SpriteBatch spriteBatch) + { + // draw the button background + spriteBatch.Draw(Resources.SprWhite, Rectangle, (Selected || Marked) ? FontColor : BackgroundColor); + + var labelSize = Font.MeasureString(Label); + var textLeft = ButtonIcon != null ? _iconRectangle.Right : Rectangle.X; + var textPosition = new Vector2( + (int)(textLeft + (Rectangle.Width - _iconRectangle.Width) / 2 - labelSize.X / 2), + (int)(Rectangle.Y + Rectangle.Height / 2 - labelSize.Y / 2)); + + spriteBatch.DrawString(Font, Label, textPosition, (Selected || Marked) ? BackgroundColor : FontColor); + + if (ButtonIcon != null) + spriteBatch.Draw(ButtonIcon, _iconRectangle, (Selected || Marked) ? BackgroundColor : FontColor); + } + } +} \ No newline at end of file diff --git a/Base/UI/UiCheckBox.cs b/Base/UI/UiCheckBox.cs new file mode 100644 index 0000000..015ead4 --- /dev/null +++ b/Base/UI/UiCheckBox.cs @@ -0,0 +1,65 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Things; + +namespace ProjectZ.Base.UI +{ + public class UiCheckBox : UiElement + { + public bool CurrentState; + + private readonly Rectangle _checkBox; + private readonly Rectangle _checkBoxFill; + private readonly Vector2 _textBoxPosition; + private int _border = 4; + + public UiCheckBox(Rectangle rectangle, SpriteFont font, string text, string elementId, string screen, bool currentState, UiFunction update, UiFunction click) + : base(elementId, screen) + { + Rectangle = new Rectangle(rectangle.X + rectangle.Height + 5, rectangle.Y, rectangle.Width - rectangle.Height - 5, rectangle.Height); + _checkBox = new Rectangle(rectangle.X, rectangle.Y, rectangle.Height, rectangle.Height); + + _checkBoxFill = new Rectangle( + _checkBox.X + _border, _checkBox.Y + _border, + _checkBox.Width - _border * 2, _checkBox.Height - _border * 2); + + Label = text; + CurrentState = currentState; + UpdateFunction = update; + ClickFunction = click; + + Font = font; + + var labelSize = Font.MeasureString(Label); + _textBoxPosition = new Vector2( + (int)(Rectangle.X + Rectangle.Width / 2 - labelSize.X / 2), + (int)(Rectangle.Y + Rectangle.Height / 2 - labelSize.Y / 2)); + } + + public override void Update() + { + base.Update(); + + if (ClickFunction != null && InputHandler.MouseLeftPressed() && Selected) + { + CurrentState = !CurrentState; + ClickFunction(this); + } + } + + public override void Draw(SpriteBatch spriteBatch) + { + // draw the background + spriteBatch.Draw(Resources.SprWhite, Rectangle, Selected ? FontColor : BackgroundColor); + + spriteBatch.Draw(Resources.SprWhite, _checkBox, BackgroundColor); + + // draw the selection + if (CurrentState) + spriteBatch.Draw(Resources.SprWhite, _checkBoxFill, FontColor); + + // draw the label + spriteBatch.DrawString(Font, Label, _textBoxPosition, Selected ? BackgroundColor : FontColor); + } + } +} \ No newline at end of file diff --git a/Base/UI/UiEditList.cs b/Base/UI/UiEditList.cs new file mode 100644 index 0000000..895af67 --- /dev/null +++ b/Base/UI/UiEditList.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Things; + +namespace ProjectZ.Base.UI +{ + public class UiEditList : UiElement + { + public int SelectedEntry; + + private readonly List _list; + + private const int Padding = 5; + private const int ButtonDistance = 1; + private const int ButtonHeight = 16; + + private int _currentSelection = -1; + private int _startSelection = -1; + + private int _scrollPosition; + + private bool _isSwapping; + + public UiEditList(Rectangle rectangle, SpriteFont font, List list, string elementId, string screen, UiFunction update) + : base(elementId, screen) + { + Rectangle = rectangle; + _list = list; + + UpdateFunction = update; + + Font = font; + } + + public override void Update() + { + var listEntrySize = (ButtonHeight + ButtonDistance); + + _currentSelection = -1; + if (InputHandler.MouseIntersect(Rectangle)) + { + // scroll through the list + { + if (InputHandler.MouseWheelUp()) + _scrollPosition--; + if (InputHandler.MouseWheelDown()) + _scrollPosition++; + + var maxVisibleEntries = Rectangle.Height / listEntrySize; + var maxScrollPosition = maxVisibleEntries >= _list.Count ? 0 : _list.Count - maxVisibleEntries; + + _scrollPosition = Math.Clamp(_scrollPosition, 0, maxScrollPosition); + } + + _currentSelection = (InputHandler.MouseState.Y - Rectangle.Y + _scrollPosition * listEntrySize) / listEntrySize; + + if (_currentSelection < _list.Count && InputHandler.MouseLeftStart()) + { + _isSwapping = true; + SelectedEntry = _currentSelection; + _startSelection = _currentSelection; + } + + if (_isSwapping && InputHandler.MouseLeftDown()) + { + // swap entries? + if (_startSelection != _currentSelection && _currentSelection < _list.Count) + { + var copy = _list[_startSelection]; + _list[_startSelection] = _list[_currentSelection]; + _list[_currentSelection] = copy; + + _startSelection = _currentSelection; + SelectedEntry = _currentSelection; + } + } + } + + if (!InputHandler.MouseLeftDown()) + _isSwapping = false; + + base.Update(); + } + + public override void Draw(SpriteBatch spriteBatch) + { + var posY = Rectangle.Y; + for (var i = _scrollPosition; i < _list.Count; i++) + { + var marked = _currentSelection == i || SelectedEntry == i; + + // draw the background + var buttonRectangle = new Rectangle(Rectangle.X + Padding, posY + Padding, Rectangle.Width - Padding * 2, ButtonHeight); + spriteBatch.Draw(Resources.SprWhite, buttonRectangle, marked ? FontColor : BackgroundColor); + + // draw the text + var text = _list[i].ToString(); + var labelSize = Font.MeasureString(text); + var textPosition = new Vector2((int)(Rectangle.X + Rectangle.Width / 2 - labelSize.X / 2), (int)(posY + ButtonDistance + ButtonHeight / 2 - labelSize.Y / 2 + 2)); + spriteBatch.DrawString(Font, text, textPosition, marked ? BackgroundColor : FontColor); + + posY += ButtonHeight + ButtonDistance; + } + + // draw the scrollbar + if(_list.Count > 0) + { + var listEntrySize = (ButtonHeight + ButtonDistance); + var maxVisibleEntries = Rectangle.Height / listEntrySize; + var maxScrollPosition = maxVisibleEntries >= _list.Count ? 0 : _list.Count - maxVisibleEntries; + var scrollBarHeight = (int)((maxVisibleEntries / (float)_list.Count) * Rectangle.Height); + + if (maxScrollPosition > 0) + { + // draw the bar background + spriteBatch.Draw(Resources.SprWhite, + new Rectangle(Rectangle.Right - Padding + 1, Rectangle.Y, Padding - 2, Rectangle.Height), Values.ColorBackgroundLight); + + // draw the bar + spriteBatch.Draw(Resources.SprWhite, + new Rectangle(Rectangle.Right - Padding + 1, + Rectangle.Y + (int)((_scrollPosition / (float)maxScrollPosition) * (Rectangle.Height - scrollBarHeight)), Padding - 2, scrollBarHeight), BackgroundColor); + } + } + } + } +} \ No newline at end of file diff --git a/Base/UI/UiElement.cs b/Base/UI/UiElement.cs new file mode 100644 index 0000000..62f1423 --- /dev/null +++ b/Base/UI/UiElement.cs @@ -0,0 +1,46 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Things; + +namespace ProjectZ.Base.UI +{ + public class UiElement + { + public delegate void UiFunction(UiElement uiElement); + + public UiFunction ClickFunction; + public UiFunction UpdateFunction; + public UiFunction SizeUpdate; + + public SpriteFont Font; + public Rectangle Rectangle; + public Color BackgroundColor = Values.ColorUiEditor; + public Color FontColor = new Color(255, 255, 255); + + public string[] Screens; + public string ElementId; + public virtual string Label { get; set; } + public bool IsVisible = true; + public bool Selected; + public bool Remove; + + public UiElement(string elementId, string screen) + { + ElementId = elementId; + Screens = screen.ToUpper().Split(':'); + Font = Resources.EditorFont; + } + + public virtual void Update() + { + // select the element if the mouse if cursor is hovering over it + Selected = InputHandler.MouseIntersect(Rectangle); + // call the update function of the element + UpdateFunction?.Invoke(this); + } + + public virtual void Draw(SpriteBatch spriteBatch) { } + + public virtual void DrawBlur(SpriteBatch spriteBatch) { } + } +} \ No newline at end of file diff --git a/Base/UI/UiImage.cs b/Base/UI/UiImage.cs new file mode 100644 index 0000000..b36aec8 --- /dev/null +++ b/Base/UI/UiImage.cs @@ -0,0 +1,27 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace ProjectZ.Base.UI +{ + public class UiImage : UiElement + { + public Texture2D SprImage; + public Rectangle SourceRectangle; + + public UiImage(Texture2D sprImage, Rectangle drawRectangle, Rectangle sourceRectangle, string elementId, string screen, Color color, UiFunction update) + : base(elementId, screen) + { + SprImage = sprImage; + Rectangle = drawRectangle; + SourceRectangle = sourceRectangle; + BackgroundColor = color; + UpdateFunction = update; + } + + public override void Draw(SpriteBatch spriteBatch) + { + if (SprImage != null) + spriteBatch.Draw(SprImage, Rectangle, SourceRectangle, BackgroundColor); + } + } +} \ No newline at end of file diff --git a/Base/UI/UiLabel.cs b/Base/UI/UiLabel.cs new file mode 100644 index 0000000..968d73e --- /dev/null +++ b/Base/UI/UiLabel.cs @@ -0,0 +1,56 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Things; + +namespace ProjectZ.Base.UI +{ + public class UiLabel : UiElement + { + private string _label; + public sealed override string Label + { + get => _label; + set { _label = value; UpdateLabelPosition(); } + } + + private Vector2 _textPosition; + + public UiLabel(Rectangle rectangle, SpriteFont font, string text, string elementId, string screen, UiFunction update, Color backgroundColor) + : base(elementId, screen) + { + Rectangle = rectangle; + UpdateFunction = update; + + BackgroundColor = backgroundColor; + Font = font; + + Label = text; + } + + public UiLabel(Rectangle rectangle, SpriteFont font, string text, string elementId, string screen, UiFunction update) : + this(rectangle, font, text, elementId, screen, update, Color.Transparent) + { } + + public UiLabel(Rectangle rectangle, string text, string screen) : base("", screen) + { + BackgroundColor = Color.Transparent; + Rectangle = rectangle; + Label = text; + } + + public void UpdateLabelPosition() + { + _textPosition = new Vector2( + (int)(Rectangle.X + Rectangle.Width / 2 - Font.MeasureString(_label).X / 2), + (int)(Rectangle.Y + Rectangle.Height / 2 - Font.MeasureString(_label).Y / 2)); + } + + public override void Draw(SpriteBatch spriteBatch) + { + // draw the background + spriteBatch.Draw(Resources.SprWhite, Rectangle, BackgroundColor); + // draw the label + spriteBatch.DrawString(Font, _label, _textPosition, FontColor); + } + } +} \ No newline at end of file diff --git a/Base/UI/UiNumberInput.cs b/Base/UI/UiNumberInput.cs new file mode 100644 index 0000000..c0b8c6f --- /dev/null +++ b/Base/UI/UiNumberInput.cs @@ -0,0 +1,111 @@ +using System.Globalization; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using ProjectZ.InGame.Things; + +namespace ProjectZ.Base.UI +{ + public class UiNumberInput : UiElement + { + public float MinValue; + public float MaxValue; + public float Value; + public float OldValue; + + private readonly UiFunction _onNumberUpdate; + private string _strValue; + private string _strNewValue; + private readonly float _stepSize; + private int _mouseWheel; + + public UiNumberInput(Rectangle rectangle, SpriteFont font, float value, float minValue, float maxValue, + float stepSize, string elementId, string screen, UiFunction update, UiFunction onNumberUpdate) + : base(elementId, screen) + { + Rectangle = rectangle; + UpdateFunction = update; + _onNumberUpdate = onNumberUpdate; + + Value = value; + _strValue = value.ToString(CultureInfo.InvariantCulture); + + MinValue = minValue; + MaxValue = maxValue; + + _stepSize = stepSize; + + Font = font; + } + + public override void Update() + { + base.Update(); + + OldValue = Value; + _strValue = Value.ToString(CultureInfo.InvariantCulture); + + if (Selected) + { + _strNewValue = _strValue == "0" ? "" : _strValue; + + var returnNumber = InputHandler.ReturnNumber(); + if (returnNumber >= 0) + _strNewValue += returnNumber.ToString(); + + // delete last position + if (InputHandler.KeyPressed(Keys.Back) || InputHandler.MouseRightPressed(Rectangle)) + _strNewValue = _strValue.Substring(0, _strValue.Length - 1); + + // if everything was delete + if (_strNewValue == "") + _strNewValue = "0"; + + // add . + if (_stepSize % 1 > 0 && (InputHandler.KeyPressed(Keys.OemPeriod) || InputHandler.KeyPressed(Keys.OemComma)) && !_strValue.Contains(".")) + _strNewValue += "."; + + // change value when scrolling + if (InputHandler.MouseState.ScrollWheelValue > _mouseWheel && float.Parse(_strNewValue, CultureInfo.InvariantCulture) + _stepSize <= MaxValue) + _strNewValue = (float.Parse(_strNewValue, CultureInfo.InvariantCulture) + _stepSize).ToString(CultureInfo.InvariantCulture); + if (InputHandler.MouseState.ScrollWheelValue < _mouseWheel && float.Parse(_strNewValue, CultureInfo.InvariantCulture) - _stepSize >= MinValue) + _strNewValue = (float.Parse(_strNewValue, CultureInfo.InvariantCulture) - _stepSize).ToString(CultureInfo.InvariantCulture); + + InputHandler.ResetInputState(); + + float.TryParse(_strNewValue, NumberStyles.Float, CultureInfo.InvariantCulture, out var newValue); + if (newValue <= MaxValue && + (!_strNewValue.Contains(".") || _strNewValue.Split('.')[1].Length <= (_stepSize % 1).ToString(CultureInfo.InvariantCulture).Length - 2)) + _strValue = _strNewValue; + + float.TryParse(_strValue, NumberStyles.Float, CultureInfo.InvariantCulture, out Value); + + if (OldValue != Value && Value >= MinValue) + _onNumberUpdate?.Invoke(this); + } + else + { + if (Value != (int)(Value / _stepSize) * _stepSize) + { + Value = (int)(Value / _stepSize) * _stepSize; + _strValue = Value.ToString(CultureInfo.InvariantCulture); + _onNumberUpdate(this); + } + } + + _mouseWheel = InputHandler.MouseState.ScrollWheelValue; + } + + public override void Draw(SpriteBatch spriteBatch) + { + // draw the background + spriteBatch.Draw(Resources.SprWhite, Rectangle, BackgroundColor); + + Label = _strValue + (Selected ? "|" : ""); + + // draw the value + var textPosition = new Vector2(Rectangle.X + 5, (int)(Rectangle.Y + Rectangle.Height / 2 - Font.MeasureString(Label).Y / 2)); + spriteBatch.DrawString(Font, Label, textPosition, FontColor); + } + } +} \ No newline at end of file diff --git a/Base/UI/UiRectangle.cs b/Base/UI/UiRectangle.cs new file mode 100644 index 0000000..0d99e2d --- /dev/null +++ b/Base/UI/UiRectangle.cs @@ -0,0 +1,33 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Things; + +namespace ProjectZ.Base.UI +{ + public class UiRectangle : UiElement + { + public Color BlurColor; + public float Radius = 0; + + public UiRectangle(Rectangle rectangle, string elementId, string screen, Color color, Color blurColor, UiFunction update) + : base(elementId, screen) + { + Rectangle = rectangle; + BackgroundColor = color; + BlurColor = blurColor; + UpdateFunction = update; + } + + public override void DrawBlur(SpriteBatch spriteBatch) + { + Resources.RoundedCornerBlurEffect.Parameters["scale"].SetValue(Game1.UiScale); + Resources.RoundedCornerBlurEffect.Parameters["blurColor"].SetValue(BlurColor.ToVector4()); + Resources.RoundedCornerBlurEffect.Parameters["radius"].SetValue(Radius); + Resources.RoundedCornerBlurEffect.Parameters["width"].SetValue(Rectangle.Width / Game1.UiScale); + Resources.RoundedCornerBlurEffect.Parameters["height"].SetValue(Rectangle.Height / Game1.UiScale); + + // draw the blur texture + spriteBatch.Draw(Resources.SprWhite, Rectangle, BackgroundColor); + } + } +} \ No newline at end of file diff --git a/Base/UI/UiScrollableList.cs b/Base/UI/UiScrollableList.cs new file mode 100644 index 0000000..a0fe9d9 --- /dev/null +++ b/Base/UI/UiScrollableList.cs @@ -0,0 +1,91 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Things; + +namespace ProjectZ.Base.UI +{ + public class UiScrollableList : UiElement + { + public string[] ItemList = new string[0]; + public int SelectionListItemHeight = 20; + public int? Selection; + public int? MouseOverSelection; + + public int MaxLength; + public int ListLength; + public int ListPositionY; + + public int SelectionListState + { + get => MathHelper.Clamp(_selectionListState, 0, ItemList.Length - (Rectangle.Height) / SelectionListItemHeight); + set => _selectionListState = value; + } + + private int _selectionListState; + + public UiScrollableList(Rectangle rectangle, string elementId, string screen, UiFunction update) + : base(elementId, screen) + { + Rectangle = rectangle; + UpdateFunction = update; + } + + public override void Update() + { + base.Update(); + + Selection = null; + MouseOverSelection = null; + + var scrollDirection = MathHelper.Clamp(InputHandler.LastMousState.ScrollWheelValue - InputHandler.MouseState.ScrollWheelValue, -1, 1); + if (InputHandler.MouseIntersect(Rectangle)) + SelectionListState += scrollDirection; + + MaxLength = Rectangle.Height / SelectionListItemHeight; + ListLength = MathHelper.Min(ItemList.Length, MaxLength); + ListPositionY = Rectangle.Height / 2 - (MaxLength * SelectionListItemHeight) / 2; + + if (InputHandler.MouseIntersect(new Rectangle(Rectangle.X, Rectangle.Y + ListPositionY, Rectangle.Width, ListLength * SelectionListItemHeight))) + { + var selection = (InputHandler.MousePosition().Y - Rectangle.Y - ListPositionY) / SelectionListItemHeight; + + if (!(selection == 0 && selection + SelectionListState > 0) && !(selection == ListLength - 1 && selection + SelectionListState != ItemList.Length - 1)) + MouseOverSelection = selection + SelectionListState; + if (InputHandler.MouseLeftPressed()) + { + MouseOverSelection = null; + + if (selection == 0 && selection + SelectionListState > 0) + SelectionListState = 0; + else if (selection == ListLength - 1 && selection + SelectionListState != ItemList.Length - 1) + SelectionListState = ItemList.Length - Rectangle.Height / SelectionListItemHeight; + else + Selection = selection + SelectionListState; + } + } + } + + public override void Draw(SpriteBatch spriteBatch) + { + for (var i = 0; i < ListLength; i++) + { + string strText; + if (i == 0 && i + SelectionListState > 0) + strText = "▲"; + else if (i == ListLength - 1 && i + SelectionListState != ItemList.Length - 1) + strText = "▼"; + else + strText = ItemList[i + SelectionListState]; + + var drawRectangle = new Rectangle(Rectangle.X, Rectangle.Y + + i * SelectionListItemHeight + ListPositionY, Rectangle.Width, SelectionListItemHeight); + //mark if the mouse is over + if (InputHandler.MouseIntersect(drawRectangle)) + spriteBatch.Draw(Resources.SprWhite, drawRectangle, Color.Black * 0.25f); + + Basics.DrawStringCenter(Font, strText, + new Rectangle(Rectangle.X, Rectangle.Y + i * SelectionListItemHeight + ListPositionY, Rectangle.Width, SelectionListItemHeight), Color.White); + } + } + } +} \ No newline at end of file diff --git a/Base/UI/UiTextInput.cs b/Base/UI/UiTextInput.cs new file mode 100644 index 0000000..644f260 --- /dev/null +++ b/Base/UI/UiTextInput.cs @@ -0,0 +1,402 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using ProjectZ.InGame.Things; + +namespace ProjectZ.Base.UI +{ + public class UiTextInput : UiElement + { + public Type InputType; + public float MaxLength; + + public string StrValue + { + get => _strValue; + set + { + _strValue = value; + _cursorIndex = StrValue.Length; + _selectionStart = -1; + } + } + + private readonly UiFunction _onTextUpdate; + private string _strValue = ""; + + private int _cursorIndex; + + private int _selectionStart = -1; + private int _selectionEnd = -1; + private bool _mouseSelecting; + + private float _buttonDownCounter; + private int _buttonResetTime = 35; + private int _buttonResetInitTime = 250; + + private int _maxCharacterCount; + private float _cursorCounter; + private Vector2 _fontSize; + + private double _lastMouseClick; + + public UiTextInput(Rectangle rectangle, SpriteFont font, float maxLength, + string elementId, string screen, UiFunction update, UiFunction onTextUpdate) : base(elementId, screen) + { + Rectangle = rectangle; + UpdateFunction = update; + _onTextUpdate = onTextUpdate; + MaxLength = maxLength; + Font = font; + + _fontSize = font.MeasureString("A"); + _maxCharacterCount = (int)((rectangle.Width - 10) / _fontSize.X); + } + + public override void Update() + { + base.Update(); + + _cursorCounter += Game1.DeltaTime; + + if (InputHandler.KeyDown(Keys.Left) || InputHandler.KeyDown(Keys.Right) || + InputHandler.KeyDown(Keys.Up) || InputHandler.KeyDown(Keys.Down) || + InputHandler.KeyDown(Keys.Back) || InputHandler.KeyDown(Keys.Delete)) + { + _buttonDownCounter -= Game1.DeltaTime; + } + else + { + _buttonDownCounter = _buttonResetInitTime; + } + + if (!Selected) return; + + var mousePosition = InputHandler.MousePosition().ToVector2(); + var newCursorIndex = SetCursor(mousePosition); + var mouseReleased = InputHandler.MouseLeftReleased(); + + if (InputHandler.MouseLeftPressed()) + { + // set the cursor to the position the user clicked on + if (_lastMouseClick < Game1.TotalGameTime - 550 || newCursorIndex != _cursorIndex) + { + _mouseSelecting = false; + _lastMouseClick = Game1.TotalGameTime; + _cursorIndex = newCursorIndex; + _selectionStart = -1; + } + // select the word the user clicked on + else + { + _selectionStart = CursorPositionSkip(-1); + _selectionEnd = CursorPositionSkip(1); + _cursorIndex = _selectionEnd; + } + } + else if (InputHandler.MouseLeftDown() && + (_mouseSelecting || (_selectionStart == -1 && newCursorIndex != _cursorIndex))) + { + _mouseSelecting = true; + _selectionStart = Math.Min(_cursorIndex, newCursorIndex); + _selectionEnd = Math.Max(_cursorIndex, newCursorIndex); + } + + if (_mouseSelecting && InputHandler.MouseLeftReleased()) + { + _mouseSelecting = false; + _cursorIndex = newCursorIndex; + } + + var inputString = InputHandler.ReturnCharacter(); + if (_strValue.Length < MaxLength && inputString != "") + { + // delete the selection first + if (_selectionStart != -1) + DeleteSelection(); + + _strValue = _strValue.Substring(0, _cursorIndex) + inputString + + _strValue.Substring(_cursorIndex, _strValue.Length - _cursorIndex); + + _cursorIndex++; + } + + //delete last position + if ((InputHandler.KeyPressed(Keys.Back) || InputHandler.KeyDown(Keys.Back) && + _buttonDownCounter <= 0) && _strValue.Length > 0 && _cursorIndex > 0) + { + // delete selection + if (_selectionStart != -1) + { + DeleteSelection(); + } + else + { + _strValue = _strValue.Remove(_cursorIndex - 1, 1); + _cursorIndex--; + } + + _buttonDownCounter += _buttonResetTime; + _cursorCounter = 0; + } + + if ((InputHandler.KeyPressed(Keys.Delete) || InputHandler.KeyDown(Keys.Delete) && + _buttonDownCounter <= 0) && _strValue.Length > 0) + { + // delete selection + if (_selectionStart != -1) + DeleteSelection(); + else if (_cursorIndex < _strValue.Length) + _strValue = _strValue.Remove(_cursorIndex, 1); + + _buttonDownCounter += _buttonResetTime; + _cursorCounter = 0; + } + + if (InputHandler.KeyPressed(Keys.Up)) + { + _cursorIndex = 0; + _cursorCounter = 0; + } + + if (InputHandler.KeyDown(Keys.Down)) + { + _cursorIndex = _strValue.Length; + _cursorCounter = 0; + } + + // move the cursor to the end of the word + if (InputHandler.KeyPressed(Keys.Left) || InputHandler.KeyDown(Keys.Left) && _buttonDownCounter <= 0) + { + if (InputHandler.KeyDown(Keys.LeftControl)) + _cursorIndex = CursorPositionSkip(-1); + else + MoveCursor(-1); + + if (!InputHandler.KeyDown(Keys.LeftShift)) + _selectionStart = -1; + + ResetCursorTimer(); + } + + if (InputHandler.KeyPressed(Keys.Right) || InputHandler.KeyDown(Keys.Right) && _buttonDownCounter <= 0) + { + if (InputHandler.KeyDown(Keys.LeftControl)) + _cursorIndex = CursorPositionSkip(1); + else + MoveCursor(1); + + if (!InputHandler.KeyDown(Keys.LeftShift)) + _selectionStart = -1; + + ResetCursorTimer(); + } + + if (InputType == typeof(int)) + { + if (InputHandler.MouseWheelDown()) + AddValue(-1); + if (InputHandler.MouseWheelUp()) + AddValue(1); + } + if (InputType == typeof(bool)) + { + if (InputHandler.MouseWheelDown() || InputHandler.MouseWheelUp()) + ToggleBool(); + } + + _cursorIndex = MathHelper.Clamp(_cursorIndex, 0, _strValue.Length); + + InputHandler.ResetInputState(); + + _onTextUpdate?.Invoke(this); + } + + private void DeleteSelection() + { + _strValue = _strValue.Remove(_selectionStart, _selectionEnd - _selectionStart); + + if (_cursorIndex > _selectionStart) + _cursorIndex -= _selectionEnd - _selectionStart; + + _selectionStart = -1; + } + + private int SetCursor(Vector2 position) + { + var textPosition = GetTextPosition(); + + // cursor will be set in front or behind the character depending on where you click + var posX = (int)((position.X - textPosition.X + _fontSize.X / 2) / _fontSize.X); + var posY = (int)(position.Y - textPosition.Y) / (int)_fontSize.Y; + + var xIndex = MathHelper.Clamp(posX, 0, _maxCharacterCount); + var yIndex = MathHelper.Clamp(posY, 0, _maxCharacterCount); + + var positionIndex = xIndex + yIndex * _maxCharacterCount; + + _cursorCounter = 0; + return MathHelper.Clamp(positionIndex, 0, _strValue.Length); + } + + private void MoveCursor(int offset) + { + _cursorIndex += offset; + } + + private void ResetCursorTimer() + { + _buttonDownCounter += _buttonResetTime; + _cursorCounter = 0; + } + + /// + /// Move the cursor in the given direction. + /// This will try to skip over words. + /// + /// + private int CursorPositionSkip(int direction) + { + if (_strValue.Length == 0) + return 0; + + var offset = direction < 0 ? -1 : 0; + var characterIndex = _cursorIndex + offset; + var lastCharacter = -1; + + while (0 <= characterIndex && characterIndex < _strValue.Length) + { + var characterType = GetCharacterType(_strValue[characterIndex]); + // we break if there is a new character type at the cursor position + if (lastCharacter != -1 && characterType != 0 && lastCharacter != characterType) + { + characterIndex -= offset; + return characterIndex; + } + lastCharacter = characterType; + + characterIndex += direction; + } + + return direction < 0 ? 0 : _strValue.Length; + } + + private int GetCharacterType(char character) + { + if (character == ' ') + return 0; + + if (('a' <= character && character <= 'z') || + ('A' <= character && character <= 'Z') || + ('0' <= character && character <= '9') || + character == '_') + { + return 1; + } + + return 2; + } + + public void AddValue(int diff) + { + var converted = ConvertToType(); + + if (converted == null) return; + + var intValue = (int)converted + diff; + _strValue = intValue.ToString(); + } + + public void ToggleBool() + { + var converted = ConvertToType(); + + if (converted == null) return; + + var boolValue = !(bool)converted; + _strValue = boolValue.ToString(); + } + + public object ConvertToType() + { + object output = null; + + if (InputType == typeof(int)) + { + int.TryParse(_strValue, out var intResult); + output = intResult; + } + else if (InputType == typeof(bool)) + { + bool.TryParse(_strValue, out var boolResult); + output = boolResult; + } + + return output; + } + + public override void Draw(SpriteBatch spriteBatch) + { + spriteBatch.Draw(Resources.SprWhite, Rectangle, BackgroundColor); + + Label = StrValue; + + // add line breaks if needed + if (_maxCharacterCount >= 1) + { + var breakCount = 1; + var length = Label.Length; + while (length > _maxCharacterCount) + { + length -= _maxCharacterCount; + Label = Label.Insert(breakCount * _maxCharacterCount + breakCount - 1, "\n"); + breakCount++; + } + } + + // draw the text + var textPosition = GetTextPosition(); + + // draw the selection + if (Selected && _selectionStart != -1) + { + var drawIndex = _selectionStart; + + // draw the selection line by line + while (drawIndex < _selectionEnd) + { + var drawIndexEnd = MathHelper.Min( + drawIndex + _maxCharacterCount - (drawIndex % _maxCharacterCount), _selectionEnd); + var drawPosition = new Vector2( + (drawIndex % _maxCharacterCount) * _fontSize.X, + (drawIndex / _maxCharacterCount) * _fontSize.Y); + spriteBatch.Draw(Resources.SprWhite, + new Rectangle( + (int)(textPosition.X + drawPosition.X), (int)(textPosition.Y + drawPosition.Y), + (drawIndexEnd - drawIndex) * (int)_fontSize.X, (int)_fontSize.Y), Color.Blue); + drawIndex = drawIndexEnd; + } + } + + spriteBatch.DrawString(Font, Label, textPosition, FontColor); + + // draw the cursor + if (Selected && _cursorCounter % 700 < 350 && _maxCharacterCount > 0) + { + var offset = _cursorIndex != 0 && _cursorIndex % _maxCharacterCount == 0 ? 1 : 0; + var cursorPosition = new Vector2( + textPosition.X + (_cursorIndex % _maxCharacterCount + offset * _maxCharacterCount) * _fontSize.X - 3, + textPosition.Y + (_cursorIndex / _maxCharacterCount - offset) * _fontSize.Y); + + spriteBatch.DrawString(Font, "|", cursorPosition, FontColor); + } + } + + private Vector2 GetTextPosition() + { + var label = Label.Length > 0 ? Label : "0"; + return new Vector2(Rectangle.X + 5, (int)(Rectangle.Y + Rectangle.Height / 2 - Font.MeasureString(label).Y / 2)); + } + } +} \ No newline at end of file diff --git a/Content/Content.mgcb b/Content/Content.mgcb new file mode 100644 index 0000000..536eabd --- /dev/null +++ b/Content/Content.mgcb @@ -0,0 +1,1366 @@ + +#----------------------------- Global Properties ----------------------------# + +/outputDir:bin/$(Platform) +/intermediateDir:obj/$(Platform) +/platform:MacOSX +/config: +/profile:Reach +/compress:False + +#-------------------------------- References --------------------------------# + + +#---------------------------------- Content ---------------------------------# + +#begin Editor/delete.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Editor/delete.png + +#begin Editor/edit.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Editor/edit.png + +#begin Editor/eye_closed.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Editor/eye_closed.png + +#begin Editor/eye_open.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Editor/eye_open.png + +#begin Editor/select.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Editor/select.png + +#begin Fonts/credits font.png +/importer:TextureImporter +/processor:FontTextureProcessor +/processorParam:FirstCharacter= +/processorParam:PremultiplyAlpha=True +/processorParam:TextureFormat=Color +/build:Fonts/credits font.png + +#begin Fonts/credits header font.png +/importer:TextureImporter +/processor:FontTextureProcessor +/processorParam:FirstCharacter= +/processorParam:PremultiplyAlpha=True +/processorParam:TextureFormat=Color +/build:Fonts/credits header font.png + +#begin Fonts/editor font.spritefont +/importer:FontDescriptionImporter +/processor:FontDescriptionProcessor +/processorParam:PremultiplyAlpha=True +/processorParam:TextureFormat=Compressed +/build:Fonts/editor font.spritefont + +#begin Fonts/editor mono font.spritefont +/importer:FontDescriptionImporter +/processor:FontDescriptionProcessor +/processorParam:PremultiplyAlpha=True +/processorParam:TextureFormat=Compressed +/build:Fonts/editor mono font.spritefont + +#begin Fonts/editor small mono font.spritefont +/importer:FontDescriptionImporter +/processor:FontDescriptionProcessor +/processorParam:PremultiplyAlpha=True +/processorParam:TextureFormat=Compressed +/build:Fonts/editor small mono font.spritefont + +#begin Fonts/headerFont.png +/importer:TextureImporter +/processor:FontTextureProcessor +/processorParam:FirstCharacter= +/processorParam:PremultiplyAlpha=True +/processorParam:TextureFormat=Color +/build:Fonts/headerFont.png + +#begin Fonts/newHeaderFont.png +/importer:TextureImporter +/processor:FontTextureProcessor +/processorParam:FirstCharacter= +/processorParam:PremultiplyAlpha=True +/processorParam:TextureFormat=Color +/build:Fonts/newHeaderFont.png + +#begin Fonts/smallFont.png +/importer:TextureImporter +/processor:FontTextureProcessor +/processorParam:FirstCharacter= +/processorParam:PremultiplyAlpha=True +/processorParam:TextureFormat=Color +/build:Fonts/smallFont.png + +#begin Light/doorLight.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Light/doorLight.png + +#begin Light/dungeon.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Light/dungeon.png + +#begin Light/light.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Light/light.png + +#begin Light/ligth room vertical.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Light/ligth room vertical.png + +#begin Light/ligth room.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Light/ligth room.png + +#begin Light/shadow.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Light/shadow.png + +#begin Menu/copyIcon.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Menu/copyIcon.png + +#begin Menu/gearIcon.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Menu/gearIcon.png + +#begin Menu/menuBackground.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Menu/menuBackground.png + +#begin Menu/trashIcon.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Menu/trashIcon.png + +#begin Objects/fog.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Objects/fog.png + +#begin Shader/BBlurH.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:Shader/BBlurH.fx + +#begin Shader/BBlurV.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:Shader/BBlurV.fx + +#begin Shader/BlurH.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:Shader/BlurH.fx + +#begin Shader/BlurV.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:Shader/BlurV.fx + +#begin Shader/CircleShader.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:Shader/CircleShader.fx + +#begin Shader/ColorCloud.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:Shader/ColorCloud.fx + +#begin Shader/ColorShader.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:Shader/ColorShader.fx + +#begin Shader/DamageShader.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:Shader/DamageShader.fx + +#begin Shader/EffectBlur.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:Shader/EffectBlur.fx + +#begin Shader/FullShadowEffect.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:Shader/FullShadowEffect.fx + +#begin Shader/LightFadeShader.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:Shader/LightFadeShader.fx + +#begin Shader/LightShader.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:Shader/LightShader.fx + +#begin Shader/RoundedCorner.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:Shader/RoundedCorner.fx + +#begin Shader/RoundedCornerEffectBlur.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:Shader/RoundedCornerEffectBlur.fx + +#begin Shader/SaturationFilter.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:Shader/SaturationFilter.fx + +#begin Shader/ShockEffect.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:Shader/ShockEffect.fx + +#begin Shader/ThanosShader.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:Shader/ThanosShader.fx + +#begin Shader/WaleShader.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:Shader/WaleShader.fx + +#begin Shader/WobbleShader.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:Shader/WobbleShader.fx + +#begin SoundEffects/D360-01-01.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-01-01.wav + +#begin SoundEffects/D360-02-02.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-02-02.wav + +#begin SoundEffects/D360-03-03.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-03-03.wav + +#begin SoundEffects/D360-04-04.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-04-04.wav + +#begin SoundEffects/D360-05-05.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-05-05.wav + +#begin SoundEffects/D360-06-06.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-06-06.wav + +#begin SoundEffects/D360-07-07.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-07-07.wav + +#begin SoundEffects/D360-08-08.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-08-08.wav + +#begin SoundEffects/D360-09-09.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-09-09.wav + +#begin SoundEffects/D360-10-0A.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-10-0A.wav + +#begin SoundEffects/D360-11-0B.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-11-0B.wav + +#begin SoundEffects/D360-12-0C.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-12-0C.wav + +#begin SoundEffects/D360-13-0D.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-13-0D.wav + +#begin SoundEffects/D360-14-0E.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-14-0E.wav + +#begin SoundEffects/D360-15-0F.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-15-0F.wav + +#begin SoundEffects/D360-16-10.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-16-10.wav + +#begin SoundEffects/D360-17-11.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-17-11.wav + +#begin SoundEffects/D360-18-12.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-18-12.wav + +#begin SoundEffects/D360-19-13.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-19-13.wav + +#begin SoundEffects/D360-20-14.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-20-14.wav + +#begin SoundEffects/D360-21-15.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-21-15.wav + +#begin SoundEffects/D360-22-16.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-22-16.wav + +#begin SoundEffects/D360-23-17.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-23-17.wav + +#begin SoundEffects/D360-24-18.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-24-18.wav + +#begin SoundEffects/D360-25-19.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-25-19.wav + +#begin SoundEffects/D360-26-1A.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-26-1A.wav + +#begin SoundEffects/D360-27-1B.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-27-1B.wav + +#begin SoundEffects/D360-28-1C.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-28-1C.wav + +#begin SoundEffects/D360-29-1D.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-29-1D.wav + +#begin SoundEffects/D360-30-1E.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-30-1E.wav + +#begin SoundEffects/D360-31-1F.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-31-1F.wav + +#begin SoundEffects/D360-32-20.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-32-20.wav + +#begin SoundEffects/D360-33-21.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-33-21.wav + +#begin SoundEffects/D360-34-22.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-34-22.wav + +#begin SoundEffects/D360-35-23.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-35-23.wav + +#begin SoundEffects/D360-36-24.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-36-24.wav + +#begin SoundEffects/D360-37-25.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-37-25.wav + +#begin SoundEffects/D360-38-26.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-38-26.wav + +#begin SoundEffects/D360-39-27.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-39-27.wav + +#begin SoundEffects/D360-40-28.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-40-28.wav + +#begin SoundEffects/D360-41-29.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-41-29.wav + +#begin SoundEffects/D360-42-2A.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-42-2A.wav + +#begin SoundEffects/D360-43-2B.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-43-2B.wav + +#begin SoundEffects/D360-44-2C.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-44-2C.wav + +#begin SoundEffects/D360-45-2D.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-45-2D.wav + +#begin SoundEffects/D360-46-2E.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-46-2E.wav + +#begin SoundEffects/D360-47-2F.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-47-2F.wav + +#begin SoundEffects/D360-48-30.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-48-30.wav + +#begin SoundEffects/D360-49-31.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-49-31.wav + +#begin SoundEffects/D360-50-32.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-50-32.wav + +#begin SoundEffects/D360-51-33.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-51-33.wav + +#begin SoundEffects/D360-52-34.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-52-34.wav + +#begin SoundEffects/D360-53-35.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-53-35.wav + +#begin SoundEffects/D360-54-36.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-54-36.wav + +#begin SoundEffects/D360-55-37.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-55-37.wav + +#begin SoundEffects/D360-56-38.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-56-38.wav + +#begin SoundEffects/D360-57-39.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-57-39.wav + +#begin SoundEffects/D360-58-3A.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-58-3A.wav + +#begin SoundEffects/D360-59-3B.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-59-3B.wav + +#begin SoundEffects/D360-60-3C.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-60-3C.wav + +#begin SoundEffects/D360-61-3D.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-61-3D.wav + +#begin SoundEffects/D360-62-3E.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-62-3E.wav + +#begin SoundEffects/D360-63-3F.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-63-3F.wav + +#begin SoundEffects/D360-64-40.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-64-40.wav + +#begin SoundEffects/D360-65-41.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D360-65-41.wav + +#begin SoundEffects/D368-16-10.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D368-16-10.wav + +#begin SoundEffects/D370-01-01.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-01-01.wav + +#begin SoundEffects/D370-02-02.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-02-02.wav + +#begin SoundEffects/D370-03-03.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-03-03.wav + +#begin SoundEffects/D370-04-04.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-04-04.wav + +#begin SoundEffects/D370-05-05.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-05-05.wav + +#begin SoundEffects/D370-06-06.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-06-06.wav + +#begin SoundEffects/D370-07-07.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-07-07.wav + +#begin SoundEffects/D370-08-08.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-08-08.wav + +#begin SoundEffects/D370-09-09.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-09-09.wav + +#begin SoundEffects/D370-10-0A.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-10-0A.wav + +#begin SoundEffects/D370-11-0B.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-11-0B.wav + +#begin SoundEffects/D370-12-0C.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-12-0C.wav + +#begin SoundEffects/D370-13-0D.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-13-0D.wav + +#begin SoundEffects/D370-14-0E.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-14-0E.wav + +#begin SoundEffects/D370-15-0F.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-15-0F.wav + +#begin SoundEffects/D370-16-10.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-16-10.wav + +#begin SoundEffects/D370-17-11.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-17-11.wav + +#begin SoundEffects/D370-18-12.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-18-12.wav + +#begin SoundEffects/D370-19-13.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-19-13.wav + +#begin SoundEffects/D370-20-14.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-20-14.wav + +#begin SoundEffects/D370-21-15.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-21-15.wav + +#begin SoundEffects/D370-22-16.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-22-16.wav + +#begin SoundEffects/D370-23-17.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-23-17.wav + +#begin SoundEffects/D370-24-18.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-24-18.wav + +#begin SoundEffects/D370-25-19.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-25-19.wav + +#begin SoundEffects/D370-26-1A.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-26-1A.wav + +#begin SoundEffects/D370-27-1B.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-27-1B.wav + +#begin SoundEffects/D370-28-1C.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-28-1C.wav + +#begin SoundEffects/D370-30-1E.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-30-1E.wav + +#begin SoundEffects/D370-31-1F.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-31-1F.wav + +#begin SoundEffects/D370-32-20.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-32-20.wav + +#begin SoundEffects/D370-33-21.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-33-21.wav + +#begin SoundEffects/D370-34-22.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-34-22.wav + +#begin SoundEffects/D370-35-23.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D370-35-23.wav + +#begin SoundEffects/D378-01-01.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-01-01.wav + +#begin SoundEffects/D378-02-02.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-02-02.wav + +#begin SoundEffects/D378-03-03.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-03-03.wav + +#begin SoundEffects/D378-04-04.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-04-04.wav + +#begin SoundEffects/D378-05-05.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-05-05.wav + +#begin SoundEffects/D378-06-06.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-06-06.wav + +#begin SoundEffects/D378-07-07.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-07-07.wav + +#begin SoundEffects/D378-08-08.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-08-08.wav + +#begin SoundEffects/D378-09-09.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-09-09.wav + +#begin SoundEffects/D378-10-0A.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-10-0A.wav + +#begin SoundEffects/D378-11-0B.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-11-0B.wav + +#begin SoundEffects/D378-12-0C.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-12-0C.wav + +#begin SoundEffects/D378-13-0D.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-13-0D.wav + +#begin SoundEffects/D378-14-0E.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-14-0E.wav + +#begin SoundEffects/D378-15-0F.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-15-0F.wav + +#begin SoundEffects/D378-16-10.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-16-10.wav + +#begin SoundEffects/D378-17-11.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-17-11.wav + +#begin SoundEffects/D378-18-12.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-18-12.wav + +#begin SoundEffects/D378-19-13.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-19-13.wav + +#begin SoundEffects/D378-20-14.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-20-14.wav + +#begin SoundEffects/D378-21-15.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-21-15.wav + +#begin SoundEffects/D378-22-16.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-22-16.wav + +#begin SoundEffects/D378-23-17.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-23-17.wav + +#begin SoundEffects/D378-24-18.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-24-18.wav + +#begin SoundEffects/D378-25-19.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-25-19.wav + +#begin SoundEffects/D378-26-1A.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-26-1A.wav + +#begin SoundEffects/D378-27-1B.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-27-1B.wav + +#begin SoundEffects/D378-28-1C.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-28-1C.wav + +#begin SoundEffects/D378-29-1D.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-29-1D.wav + +#begin SoundEffects/D378-30-1E.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-30-1E.wav + +#begin SoundEffects/D378-31-1F.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-31-1F.wav + +#begin SoundEffects/D378-32-20.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-32-20.wav + +#begin SoundEffects/D378-33-21.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-33-21.wav + +#begin SoundEffects/D378-34-22.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-34-22.wav + +#begin SoundEffects/D378-35-23.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-35-23.wav + +#begin SoundEffects/D378-36-24.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-36-24.wav + +#begin SoundEffects/D378-37-25.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-37-25.wav + +#begin SoundEffects/D378-38-26.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-38-26.wav + +#begin SoundEffects/D378-39-27.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-39-27.wav + +#begin SoundEffects/D378-40-28.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-40-28.wav + +#begin SoundEffects/D378-41-29.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-41-29.wav + +#begin SoundEffects/D378-42-2A.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-42-2A.wav + +#begin SoundEffects/D378-43-2B.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-43-2B.wav + +#begin SoundEffects/D378-44-2C.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-44-2C.wav + +#begin SoundEffects/D378-45-2D.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-45-2D.wav + +#begin SoundEffects/D378-46-2E.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-46-2E.wav + +#begin SoundEffects/D378-47-2F.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-47-2F.wav + +#begin SoundEffects/D378-48-30.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-48-30.wav + +#begin SoundEffects/D378-49-31.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-49-31.wav + +#begin SoundEffects/D378-50-32.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-50-32.wav + +#begin SoundEffects/D378-51-33.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-51-33.wav + +#begin SoundEffects/D378-52-34.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-52-34.wav + +#begin SoundEffects/D378-53-35.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-53-35.wav + +#begin SoundEffects/D378-54-36.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-54-36.wav + +#begin SoundEffects/D378-55-37.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-55-37.wav + +#begin SoundEffects/D378-56-38.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-56-38.wav + +#begin SoundEffects/D378-57-39.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-57-39.wav + +#begin SoundEffects/D378-58-3A.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-58-3A.wav + +#begin SoundEffects/D378-59-3B.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-59-3B.wav + +#begin SoundEffects/D378-60-3D.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-60-3D.wav + +#begin SoundEffects/D378-61-3E.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-61-3E.wav + +#begin SoundEffects/D378-62-3F.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-62-3F.wav + +#begin SoundEffects/D378-63-40.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-63-40.wav + +#begin SoundEffects/D378-64-41.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:SoundEffects/D378-64-41.wav + diff --git a/Content/Editor/delete.png b/Content/Editor/delete.png new file mode 100644 index 0000000..02d6b74 Binary files /dev/null and b/Content/Editor/delete.png differ diff --git a/Content/Editor/edit.png b/Content/Editor/edit.png new file mode 100644 index 0000000..6d45b5f Binary files /dev/null and b/Content/Editor/edit.png differ diff --git a/Content/Editor/eye_closed.png b/Content/Editor/eye_closed.png new file mode 100644 index 0000000..f1808ac Binary files /dev/null and b/Content/Editor/eye_closed.png differ diff --git a/Content/Editor/eye_open.png b/Content/Editor/eye_open.png new file mode 100644 index 0000000..ee93336 Binary files /dev/null and b/Content/Editor/eye_open.png differ diff --git a/Content/Editor/select.png b/Content/Editor/select.png new file mode 100644 index 0000000..b67abbd Binary files /dev/null and b/Content/Editor/select.png differ diff --git a/Content/Fonts/credits font.png b/Content/Fonts/credits font.png new file mode 100644 index 0000000..eb6098b Binary files /dev/null and b/Content/Fonts/credits font.png differ diff --git a/Content/Fonts/credits header font.png b/Content/Fonts/credits header font.png new file mode 100644 index 0000000..7f12da3 Binary files /dev/null and b/Content/Fonts/credits header font.png differ diff --git a/Content/Fonts/editor font.spritefont b/Content/Fonts/editor font.spritefont new file mode 100644 index 0000000..45dd13f --- /dev/null +++ b/Content/Fonts/editor font.spritefont @@ -0,0 +1,60 @@ + + + + + + + Segoe UI + + + 12 + + + 0 + + + true + + + + + + + + + + + + ~ + + + + diff --git a/Content/Fonts/editor mono font.spritefont b/Content/Fonts/editor mono font.spritefont new file mode 100644 index 0000000..0b7a4af --- /dev/null +++ b/Content/Fonts/editor mono font.spritefont @@ -0,0 +1,60 @@ + + + + + + + Courier New + + + 11 + + + 0 + + + true + + + + + + + + + + + + ~ + + + + diff --git a/Content/Fonts/editor small mono font.spritefont b/Content/Fonts/editor small mono font.spritefont new file mode 100644 index 0000000..76be52a --- /dev/null +++ b/Content/Fonts/editor small mono font.spritefont @@ -0,0 +1,60 @@ + + + + + + + Courier New + + + 8 + + + 0 + + + true + + + + + + + + + + + + ~ + + + + diff --git a/Content/Fonts/headerFont.png b/Content/Fonts/headerFont.png new file mode 100644 index 0000000..c96220f Binary files /dev/null and b/Content/Fonts/headerFont.png differ diff --git a/Content/Fonts/newHeaderFont.png b/Content/Fonts/newHeaderFont.png new file mode 100644 index 0000000..c064ce8 Binary files /dev/null and b/Content/Fonts/newHeaderFont.png differ diff --git a/Content/Fonts/smallFont.png b/Content/Fonts/smallFont.png new file mode 100644 index 0000000..72f3b30 Binary files /dev/null and b/Content/Fonts/smallFont.png differ diff --git a/Content/Fonts/smallFontOld.png b/Content/Fonts/smallFontOld.png new file mode 100644 index 0000000..be15da8 Binary files /dev/null and b/Content/Fonts/smallFontOld.png differ diff --git a/Content/Light/doorLight.atlas b/Content/Light/doorLight.atlas new file mode 100644 index 0000000..a0644f1 --- /dev/null +++ b/Content/Light/doorLight.atlas @@ -0,0 +1,3 @@ +1 +2 +doorLight:0,0,48,48,24,24 diff --git a/Content/Light/doorLight.png b/Content/Light/doorLight.png new file mode 100644 index 0000000..8955ca7 Binary files /dev/null and b/Content/Light/doorLight.png differ diff --git a/Content/Light/dungeon.png b/Content/Light/dungeon.png new file mode 100644 index 0000000..c25fddf Binary files /dev/null and b/Content/Light/dungeon.png differ diff --git a/Content/Light/light.png b/Content/Light/light.png new file mode 100644 index 0000000..ba738a3 Binary files /dev/null and b/Content/Light/light.png differ diff --git a/Content/Light/ligth room vertical.png b/Content/Light/ligth room vertical.png new file mode 100644 index 0000000..1292a98 Binary files /dev/null and b/Content/Light/ligth room vertical.png differ diff --git a/Content/Light/ligth room.png b/Content/Light/ligth room.png new file mode 100644 index 0000000..03e2596 Binary files /dev/null and b/Content/Light/ligth room.png differ diff --git a/Content/Light/readme.txt b/Content/Light/readme.txt new file mode 100644 index 0000000..21541a6 --- /dev/null +++ b/Content/Light/readme.txt @@ -0,0 +1,2 @@ +the light sprites will get preprocessed to contain preprocessed alphase (?) +so they can not just get loaded like the other sprites that do not have transparency values other than 0 or 1 \ No newline at end of file diff --git a/Content/Light/shadow.png b/Content/Light/shadow.png new file mode 100644 index 0000000..7dac5ed Binary files /dev/null and b/Content/Light/shadow.png differ diff --git a/Content/Menu/copyIcon.png b/Content/Menu/copyIcon.png new file mode 100644 index 0000000..ae32299 Binary files /dev/null and b/Content/Menu/copyIcon.png differ diff --git a/Content/Menu/gearIcon.png b/Content/Menu/gearIcon.png new file mode 100644 index 0000000..c971fbf Binary files /dev/null and b/Content/Menu/gearIcon.png differ diff --git a/Content/Menu/menuBackground.png b/Content/Menu/menuBackground.png new file mode 100644 index 0000000..3852e63 Binary files /dev/null and b/Content/Menu/menuBackground.png differ diff --git a/Content/Menu/trashIcon.png b/Content/Menu/trashIcon.png new file mode 100644 index 0000000..265665d Binary files /dev/null and b/Content/Menu/trashIcon.png differ diff --git a/Content/Objects/fog.png b/Content/Objects/fog.png new file mode 100644 index 0000000..979dfff Binary files /dev/null and b/Content/Objects/fog.png differ diff --git a/Content/Shader/BBlurH.fx b/Content/Shader/BBlurH.fx new file mode 100644 index 0000000..c8a777c --- /dev/null +++ b/Content/Shader/BBlurH.fx @@ -0,0 +1,61 @@ +#if OPENGL + #define SV_POSITION POSITION + #define VS_SHADERMODEL vs_3_0 + #define PS_SHADERMODEL ps_3_0 +#else + #define VS_SHADERMODEL vs_4_0_level_9_1 + #define PS_SHADERMODEL ps_4_1 +#endif + +sampler s0; + +float pixelX; +float mult0 = 0.25; +float mult1 = 0.125; +float mult2 = 0.075; + +float4 PixelShaderFunction(float4 pos : SV_Position, float4 color1 : COLOR0, float2 coords : TEXCOORD0) : COLOR0 +{ + float val0 = tex2D(s0, float2(coords.x, coords.y)).a; + + if (val0 == 1) + return float4(0, 0, 0, val0); + + float val1 = tex2D(s0, float2(coords.x - pixelX * 1, coords.y)).a; + float val2 = tex2D(s0, float2(coords.x - pixelX * 2, coords.y)).a; + float val3 = tex2D(s0, float2(coords.x - pixelX * 3, coords.y)).a; + + float val4 = tex2D(s0, float2(coords.x + pixelX * 1, coords.y)).a; + float val5 = tex2D(s0, float2(coords.x + pixelX * 2, coords.y)).a; + float val6 = tex2D(s0, float2(coords.x + pixelX * 3, coords.y)).a; + + float valOut = val0; + + if (val1 == 1 || val4 == 1) + valOut = max(max(val1 * mult0, val4 * mult0), valOut); + else if (val2 == 1 || val5 == 1) + valOut = max(max(val2 * mult1, val5 * mult1), valOut); + else if (val3 == 1 || val6 == 1) + valOut = max(max(val3 * mult2, val6 * mult2), valOut); + else + { + float mult = 1.95f; + valOut = max(val1 * mult0 * mult, valOut); + valOut = max(val2 * mult1 * mult, valOut); + valOut = max(val3 * mult2 * mult, valOut); + + valOut = max(val4 * mult0 * mult, valOut); + valOut = max(val5 * mult1 * mult, valOut); + valOut = max(val6 * mult2 * mult, valOut); + } + + return float4(0, 0, 0, valOut); +} + +technique Technique1 +{ + pass Pass1 + { + PixelShader = compile PS_SHADERMODEL PixelShaderFunction(); + } +} diff --git a/Content/Shader/BBlurV.fx b/Content/Shader/BBlurV.fx new file mode 100644 index 0000000..eaaa529 --- /dev/null +++ b/Content/Shader/BBlurV.fx @@ -0,0 +1,42 @@ +#if OPENGL + #define SV_POSITION POSITION + #define VS_SHADERMODEL vs_3_0 + #define PS_SHADERMODEL ps_3_0 +#else + #define VS_SHADERMODEL vs_4_0_level_9_1 + #define PS_SHADERMODEL ps_4_0_level_9_1 +#endif + +sampler s0; + +float pixelY; +float mult0 = 0.25; +float mult1 = 0.125; +float mult2 = 0.075; + +// float mult0 = 0.45; +// float mult1 = 0.25; +// float mult2 = 0.075; + +float4 PixelShaderFunction(float4 pos : SV_Position, float4 color1 : COLOR0, float2 coords : TEXCOORD0) : COLOR0 +{ + float valMax = tex2D(s0, float2(coords.x, coords.y)).a; + + valMax = max(tex2D(s0, float2(coords.x, coords.y - pixelY * 1)).a * mult0, valMax); + valMax = max(tex2D(s0, float2(coords.x, coords.y - pixelY * 2)).a * mult1, valMax); + valMax = max(tex2D(s0, float2(coords.x, coords.y - pixelY * 3)).a * mult2, valMax); + + valMax = max(tex2D(s0, float2(coords.x, coords.y + pixelY * 1)).a * mult0, valMax); + valMax = max(tex2D(s0, float2(coords.x, coords.y + pixelY * 2)).a * mult1, valMax); + valMax = max(tex2D(s0, float2(coords.x, coords.y + pixelY * 3)).a * mult2, valMax); + + return float4(0, 0, 0, valMax); +} + +technique Technique1 +{ + pass Pass1 + { + PixelShader = compile PS_SHADERMODEL PixelShaderFunction(); + } +} diff --git a/Content/Shader/BlurH.fx b/Content/Shader/BlurH.fx new file mode 100644 index 0000000..4b6b583 --- /dev/null +++ b/Content/Shader/BlurH.fx @@ -0,0 +1,33 @@ +#if OPENGL + #define SV_POSITION POSITION + #define VS_SHADERMODEL vs_3_0 + #define PS_SHADERMODEL ps_3_0 +#else + #define VS_SHADERMODEL vs_4_0_level_9_1 + #define PS_SHADERMODEL ps_4_0_level_9_1 +#endif + +sampler s0; + +float pixelX; +float mult0; +float mult1; + +float4 PixelShaderFunction(float4 pos : SV_Position, float4 color1 : COLOR0, float2 coords : TEXCOORD0) : COLOR0 +{ + float4 sideColors + = tex2D(s0, float2(coords.x - pixelX * 0.5, coords.y)) * mult0; + sideColors += tex2D(s0, float2(coords.x + pixelX * 0.5, coords.y)) * mult0; + sideColors += tex2D(s0, float2(coords.x - pixelX * 2.5, coords.y)) * mult1; + sideColors += tex2D(s0, float2(coords.x + pixelX * 2.5, coords.y)) * mult1; + + return sideColors; +} + +technique Technique1 +{ + pass Pass1 + { + PixelShader = compile PS_SHADERMODEL PixelShaderFunction(); + } +} diff --git a/Content/Shader/BlurV.fx b/Content/Shader/BlurV.fx new file mode 100644 index 0000000..f478fda --- /dev/null +++ b/Content/Shader/BlurV.fx @@ -0,0 +1,33 @@ +#if OPENGL + #define SV_POSITION POSITION + #define VS_SHADERMODEL vs_3_0 + #define PS_SHADERMODEL ps_3_0 +#else + #define VS_SHADERMODEL vs_4_0_level_9_1 + #define PS_SHADERMODEL ps_4_0_level_9_1 +#endif + +sampler s0; + +float pixelY; +float mult0; +float mult1; + +float4 PixelShaderFunction(float4 pos : SV_Position, float4 color1 : COLOR0, float2 coords : TEXCOORD0) : COLOR0 +{ + float4 sideColors + = tex2D(s0, float2(coords.x, coords.y - pixelY * 0.5)) * mult0; + sideColors += tex2D(s0, float2(coords.x, coords.y + pixelY * 0.5)) * mult0; + sideColors += tex2D(s0, float2(coords.x, coords.y - pixelY * 2.5)) * mult1; + sideColors += tex2D(s0, float2(coords.x, coords.y + pixelY * 2.5)) * mult1; + + return sideColors; +} + +technique Technique1 +{ + pass Pass1 + { + PixelShader = compile PS_SHADERMODEL PixelShaderFunction(); + } +} diff --git a/Content/Shader/CircleShader.fx b/Content/Shader/CircleShader.fx new file mode 100644 index 0000000..bf0458b --- /dev/null +++ b/Content/Shader/CircleShader.fx @@ -0,0 +1,48 @@ +#if OPENGL + #define SV_POSITION POSITION + #define VS_SHADERMODEL vs_3_0 + #define PS_SHADERMODEL ps_3_0 +#else + #define VS_SHADERMODEL vs_4_0_level_9_1 + #define PS_SHADERMODEL ps_4_0 +#endif + +Texture2D SpriteTexture; + +float softRad = 30; +float size; +float centerX, centerY; + +int width; +int height; + +sampler2D SpriteTextureSampler = sampler_state +{ + Texture = ; +}; + +struct VertexShaderOutput +{ + float4 Position : SV_POSITION; + float4 Color : COLOR0; + float2 TexCoord : TEXCOORD0; +}; + +float4 MainPS(VertexShaderOutput input) : COLOR +{ + float2 pos = float2(input.TexCoord.x * width - centerX, input.TexCoord.y * height - centerY); + float white = length(pos); + + white = clamp((size - white) / softRad, 0, 1); + float black = 1 - white; + + return (input.Color * float4(1, 1, 1, 1)) * (black * black * black); +} + +technique SpriteDrawing +{ + pass P0 + { + PixelShader = compile PS_SHADERMODEL MainPS(); + } +}; \ No newline at end of file diff --git a/Content/Shader/ColorCloud.fx b/Content/Shader/ColorCloud.fx new file mode 100644 index 0000000..b541f99 --- /dev/null +++ b/Content/Shader/ColorCloud.fx @@ -0,0 +1,43 @@ +#if OPENGL + #define SV_POSITION POSITION + #define VS_SHADERMODEL vs_3_0 + #define PS_SHADERMODEL ps_3_0 +#else + #define VS_SHADERMODEL vs_4_0_level_9_1 + #define PS_SHADERMODEL ps_4_1 +#endif + +float4x4 World; +float4x4 View; +float4x4 Projection; + +sampler sampler0 : register(s0) { }; + +float scale; +float scaleX; +float scaleY; + +float4 color0 = float4(1, 0, 0, 1); +float4 color1 = float4(1, 1, 1, 1); + +float2 offset; + +float4 PixelShaderFunction(float4 pos : SV_Position, float4 color : COLOR0, float2 coords : TEXCOORD0) : COLOR0 +{ + float4 texColor = tex2D(sampler0, coords); + + float4 insideColor = color0; + if (((int)(((pos.x / scaleX + offset.x / scale)) / 4) + + (int)(((pos.y / scaleY + offset.y / scale)) / 4)) % 2 == 0) + insideColor = color1; + + return insideColor * texColor; +} + +technique Technique1 +{ + pass Pass1 + { + PixelShader = compile PS_SHADERMODEL PixelShaderFunction(); + } +} \ No newline at end of file diff --git a/Content/Shader/ColorShader.fx b/Content/Shader/ColorShader.fx new file mode 100644 index 0000000..b459a10 --- /dev/null +++ b/Content/Shader/ColorShader.fx @@ -0,0 +1,39 @@ +#if OPENGL + #define SV_POSITION POSITION + #define VS_SHADERMODEL vs_3_0 + #define PS_SHADERMODEL ps_3_0 +#else + #define VS_SHADERMODEL vs_4_0_level_9_1 + #define PS_SHADERMODEL ps_4_0_level_9_1 +#endif + +Texture2D SpriteTexture; + +sampler2D SpriteTextureSampler = sampler_state +{ + Texture = ; +}; + +struct VertexShaderOutput +{ + float4 Position : SV_POSITION; + float4 Color : COLOR0; + float2 TextureCoordinates : TEXCOORD0; +}; + +float4 MainPS(VertexShaderOutput input) : COLOR +{ + float4 color = tex2D(SpriteTextureSampler,input.TextureCoordinates); + // replace pink with the color + if (color.r == 1 && color.g == 0 && color.b) + return input.Color; + return color; +} + +technique SpriteDrawing +{ + pass P0 + { + PixelShader = compile PS_SHADERMODEL MainPS(); + } +}; \ No newline at end of file diff --git a/Content/Shader/DamageShader.fx b/Content/Shader/DamageShader.fx new file mode 100644 index 0000000..3e5ec77 --- /dev/null +++ b/Content/Shader/DamageShader.fx @@ -0,0 +1,38 @@ +#if OPENGL + #define SV_POSITION POSITION + #define VS_SHADERMODEL vs_3_0 + #define PS_SHADERMODEL ps_3_0 +#else + #define VS_SHADERMODEL vs_4_0_level_9_1 + #define PS_SHADERMODEL ps_4_0_level_9_1 +#endif + +float mark0 = 0.0; +float mark1 = 0.0; + +#define c0 float4(1.000, 0.710, 0.192, 1.000) +#define c1 float4(0.871, 0.000, 0.000, 1.000) +#define c2 float4(0.000, 0.000, 0.000, 1.000) + +sampler s0; + +float4 PixelShaderFunction(float4 pos : SV_Position, float4 color1 : COLOR0, float2 coords : TEXCOORD0) : COLOR0 +{ + float4 color = tex2D(s0, coords) * color1; + float sum = 0.333f * color.r + 0.333f * color.g + 0.333f * color.b; + + if(sum < mark0) + return c0 * color.a * color1.a; + if(sum < mark1) + return c1 * color.a * color1.a; + + return c2 * color.a * color1.a; +} + +technique Technique1 +{ + pass Pass1 + { + PixelShader = compile PS_SHADERMODEL PixelShaderFunction(); + } +} \ No newline at end of file diff --git a/Content/Shader/EffectBlur.fx b/Content/Shader/EffectBlur.fx new file mode 100644 index 0000000..9d906b5 --- /dev/null +++ b/Content/Shader/EffectBlur.fx @@ -0,0 +1,38 @@ +#if OPENGL + #define SV_POSITION POSITION + #define VS_SHADERMODEL vs_3_0 + #define PS_SHADERMODEL ps_3_0 +#else + #define VS_SHADERMODEL vs_4_0_level_9_1 + #define PS_SHADERMODEL ps_4_1 +#endif + +Texture2D sprBlur; + +sampler sampler0 : register(s0) { + Filter = POINT; +}; +sampler sampler1 : register(s1) { + Texture = (sprBlur); +}; + +int width, height; + +float4 PixelShaderFunction(float4 pos : SV_Position, float4 color1 : COLOR0, float2 coords : TEXCOORD0) : COLOR0 +{ + #if OPENGL + pos.y = height - pos.y; + #endif + + float4 textureSample = tex2D(sampler0, float2(coords.x, coords.y)); + + return tex2D(sampler1, float2(pos.x / width, pos.y / height)) * color1 * textureSample.r + textureSample * (1 - textureSample.r) * color1; +} + +technique Technique1 +{ + pass Pass1 + { + PixelShader = compile PS_SHADERMODEL PixelShaderFunction(); + } +} diff --git a/Content/Shader/FullShadowEffect.fx b/Content/Shader/FullShadowEffect.fx new file mode 100644 index 0000000..ba99bc1 --- /dev/null +++ b/Content/Shader/FullShadowEffect.fx @@ -0,0 +1,78 @@ +#if OPENGL + #define SV_POSITION POSITION + #define VS_SHADERMODEL vs_3_0 + #define PS_SHADERMODEL ps_3_0 +#else + #define VS_SHADERMODEL vs_4_0_level_9_1 + #define PS_SHADERMODEL ps_4_0_level_9_1 +#endif + +float4x4 xViewProjection; + +Texture2D SpriteTexture; + +sampler2D SpriteTextureSampler = sampler_state +{ + Texture = ; +}; + +sampler s0; + +float pixelWidth; + +float rotation = 1.5; + +float offsetX; +float height; + +struct VertexShaderOutput +{ + float4 Pos : SV_Position; + float2 TextureCoordinates : TEXCOORD0; + float2 DrawPosition : TEXCOORD1; + float2 SourceSize : TEXCOORD2; + float4 Color: COLOR0; +}; + +struct PixelShaderInput +{ + float4 Pos : SV_Position; + float2 TextureCoordinates : TEXCOORD0; + float2 DrawPosition : TEXCOORD1; + float2 SourceSize : TEXCOORD2; + float2 RealCoord : TEXCOORD3; + float4 Color: COLOR0; +}; + +PixelShaderInput SpriteVertexShader(VertexShaderOutput input) +{ + PixelShaderInput Output = (PixelShaderInput)0; + + input.Pos.x += ((input.SourceSize.y - input.Pos.y + input.DrawPosition.y) * offsetX); + input.Pos.y -= ((-(input.DrawPosition.y + input.SourceSize.y) + input.Pos.y) * (1 - height)); + + Output.RealCoord = float2( + (input.Pos.x - input.DrawPosition.x) / input.SourceSize.x, + (input.Pos.y - input.DrawPosition.y - (input.SourceSize.y * (1 - height))) / (input.SourceSize.y * height)); + + Output.Pos = mul(input.Pos, xViewProjection); + Output.TextureCoordinates = input.TextureCoordinates; + Output.Color = input.Color; + + return Output; +} + +float4 MainPS(PixelShaderInput input) : COLOR +{ + float4 texColor = tex2D(s0, float2(input.TextureCoordinates.x, input.TextureCoordinates.y)); + return texColor.a * input.Color; +} + +technique SpriteDrawing +{ + pass P0 + { + VertexShader = compile VS_SHADERMODEL SpriteVertexShader(); + PixelShader = compile PS_SHADERMODEL MainPS(); + } +}; \ No newline at end of file diff --git a/Content/Shader/LightFadeShader.fx b/Content/Shader/LightFadeShader.fx new file mode 100644 index 0000000..bcc0609 --- /dev/null +++ b/Content/Shader/LightFadeShader.fx @@ -0,0 +1,29 @@ +#if OPENGL + #define SV_POSITION POSITION + #define VS_SHADERMODEL vs_3_0 + #define PS_SHADERMODEL ps_3_0 +#else + #define VS_SHADERMODEL vs_4_0_level_9_1 + #define PS_SHADERMODEL ps_4_1 +#endif + +float4x4 World; +float4x4 View; +float4x4 Projection; + +sampler s0; + +float4 PixelShaderFunction(float4 pos : SV_Position, float4 color : COLOR0, float2 coords : TEXCOORD0) : COLOR0 +{ + float4 texColor = tex2D(s0, coords); + float dist = 1.0 - clamp(((0.05 + texColor.a * 0.95) - color.a) / 0.05, 0, 1); + return float4(0, 0, 0, dist); +} + +technique Technique1 +{ + pass Pass1 + { + PixelShader = compile PS_SHADERMODEL PixelShaderFunction(); + } +} \ No newline at end of file diff --git a/Content/Shader/LightShader.fx b/Content/Shader/LightShader.fx new file mode 100644 index 0000000..b588d81 --- /dev/null +++ b/Content/Shader/LightShader.fx @@ -0,0 +1,47 @@ +#if OPENGL + #define SV_POSITION POSITION + #define VS_SHADERMODEL vs_3_0 + #define PS_SHADERMODEL ps_3_0 +#else + #define VS_SHADERMODEL vs_4_0_level_9_1 + #define PS_SHADERMODEL ps_4_1 +#endif + +float4x4 World; +float4x4 View; +float4x4 Projection; + +Texture2D sprLight; + +sampler sampler0 : register(s0) { }; +sampler sampler1 : register(s1) +{ + Texture = (sprLight); +}; + +float lightState = 0; +int mode = 0; +int width, height; + +float4 PixelShaderFunction(float4 pos : SV_Position, float4 color1 : COLOR0, float2 coords : TEXCOORD0) : COLOR0 +{ + float4 texColor = tex2D(sampler0, coords); + float4 lightColor = tex2D(sampler1, float2(pos.x / width, pos.y / height));// * float4(1.963, 1.0, 5.149, 1); + + lightColor.r = clamp(lightColor.r, 0, 1); + lightColor.b = clamp(lightColor.b, 0, 1); + + float3 lerpTarget = float3(1, 1, 1); + if (mode == 1) + lerpTarget = texColor.rgb; + + return float4(lerp(texColor.rgb * lightColor.rgb, lerpTarget, lightState), texColor.a) * color1; +} + +technique Technique1 +{ + pass Pass1 + { + PixelShader = compile PS_SHADERMODEL PixelShaderFunction(); + } +} \ No newline at end of file diff --git a/Content/Shader/RoundedCorner.fx b/Content/Shader/RoundedCorner.fx new file mode 100644 index 0000000..da164f7 --- /dev/null +++ b/Content/Shader/RoundedCorner.fx @@ -0,0 +1,61 @@ +#if OPENGL + #define SV_POSITION POSITION + #define VS_SHADERMODEL vs_3_0 + #define PS_SHADERMODEL ps_3_0 +#else + #define VS_SHADERMODEL vs_4_0_level_9_1 + #define PS_SHADERMODEL ps_4_0 +#endif + +const float PI = 3.14159265f; + +float radius = 2.5f; +float scale = 1; +float centerX, centerY; + +int width, height; + +sampler sampler0 : register(s0) { }; + +struct VertexShaderOutput +{ + float4 Position : SV_POSITION; + float4 Color : COLOR0; + float2 TexCoord : TEXCOORD0; +}; + +float4 MainPS(VertexShaderOutput input) : COLOR +{ + float4 texColor = tex2D(sampler0, input.TexCoord); + + float posX = input.TexCoord.x * width; + float posY = input.TexCoord.y * height; + + float distX = min(posX, abs(posX - width)); + float distY = min(posY, abs(posY - height)); + + float circle = 1; + + if (distX < radius && distY < radius) + { + float a = radius - distX; + float b = radius - distY; + float dist = clamp((radius - sqrt(a * a + b * b)) * scale, 0, 1); + circle = dist; + } + else + { + float distEdge = clamp(min(distX, distY) * scale, 0, 1); + circle = distEdge; + } + + return texColor * input.Color * circle; +} + +technique SpriteDrawing +{ + pass P0 + { + PixelShader = compile PS_SHADERMODEL MainPS(); + } +}; \ No newline at end of file diff --git a/Content/Shader/RoundedCornerEffectBlur.fx b/Content/Shader/RoundedCornerEffectBlur.fx new file mode 100644 index 0000000..aebef90 --- /dev/null +++ b/Content/Shader/RoundedCornerEffectBlur.fx @@ -0,0 +1,69 @@ +#if OPENGL + #define SV_POSITION POSITION + #define VS_SHADERMODEL vs_3_0 + #define PS_SHADERMODEL ps_3_0 +#else + #define VS_SHADERMODEL vs_4_0_level_9_1 + #define PS_SHADERMODEL ps_4_1 +#endif + +Texture2D sprBlur; + +sampler sampler0 : register(s0) { + Filter = POINT; +}; +sampler sampler1 : register(s1) { + Texture = (sprBlur); +}; + +float4 blurColor; + +float radius = 2.5f; +float scale = 1; + +int width, height; +int textureWidth, textureHeight; + +float4 PixelShaderFunction(float4 pos : SV_Position, float4 color1 : COLOR0, float2 coords : TEXCOORD0) : COLOR0 +{ + #if OPENGL + pos.y = height - pos.y; + #endif + + float posX = coords.x * width; + float posY = coords.y * height; + + float distX = min(posX, abs(posX - width)); + float distY = min(posY, abs(posY - height)); + + float circle = 1; + + if (distX < radius && distY < radius) + { + float a = radius - distX; + float b = radius - distY; + float dist = clamp((radius - sqrt(a * a + b * b)) * scale, 0, 1); + circle = dist; + } + else + { + float distEdge = clamp(min(distX, distY) * scale, 0, 1); + circle = distEdge; + } + + if (radius == 0) + circle = 1; + + float4 textureSample = tex2D(sampler0, float2(coords.x, coords.y)); + float4 blurSample = tex2D(sampler1, float2(pos.x / textureWidth, pos.y / textureHeight)); + + return ((blurSample * blurColor * (1 - color1.a) + color1) * textureSample.r + textureSample * (1 - textureSample.r) * blurColor) * circle; +} + +technique Technique1 +{ + pass Pass1 + { + PixelShader = compile PS_SHADERMODEL PixelShaderFunction(); + } +} diff --git a/Content/Shader/SaturationFilter.fx b/Content/Shader/SaturationFilter.fx new file mode 100644 index 0000000..5dc79b1 --- /dev/null +++ b/Content/Shader/SaturationFilter.fx @@ -0,0 +1,33 @@ +#if OPENGL + #define SV_POSITION POSITION + #define VS_SHADERMODEL vs_3_0 + #define PS_SHADERMODEL ps_3_0 +#else + #define VS_SHADERMODEL vs_4_0_level_9_1 + #define PS_SHADERMODEL ps_4_0_level_9_1 +#endif + +float4x4 World; +float4x4 View; +float4x4 Projection; + +sampler s0; + +float3 W = float3(0.3, 0.59, 0.11); +float percentage; + +float4 PixelShaderFunction(float4 pos : SV_Position, float4 color0 : COLOR0, float2 coords : TEXCOORD0) : COLOR0 +{ + float4 color = tex2D(s0, float2(coords.x, coords.y)); + float intensity = dot(color.rgb, W); + float4 grayscale = float4(intensity, intensity, intensity, color.a); + return lerp(color, grayscale, percentage) * color0; +} + +technique Technique1 +{ + pass Pass1 + { + PixelShader = compile PS_SHADERMODEL PixelShaderFunction(); + } +} diff --git a/Content/Shader/ShockEffect.fx b/Content/Shader/ShockEffect.fx new file mode 100644 index 0000000..ecb41a3 --- /dev/null +++ b/Content/Shader/ShockEffect.fx @@ -0,0 +1,41 @@ +#if OPENGL + #define SV_POSITION POSITION + #define VS_SHADERMODEL vs_3_0 + #define PS_SHADERMODEL ps_3_0 +#else + #define VS_SHADERMODEL vs_4_0_level_9_1 + #define PS_SHADERMODEL ps_4_0_level_9_1 +#endif + +float mark0 = 0.0; +float mark1 = 0.0; +float mark2 = 0.0; + +#define c0 float4(1.000, 1.000, 0.482, 1.000) +#define c1 float4(0.063, 0.129, 0.192, 1.000) +#define c2 float4(1.000, 1.000, 1.000, 1.000) + +sampler s0; + +float4 MainPS(float4 pos : SV_Position, float4 color1 : COLOR0, float2 coords : TEXCOORD0) : COLOR0 +{ + float4 color = tex2D(s0, coords) * color1; + float sum = 0.4f * color.r + 0.2f * color.g + 0.4f * color.b; + + if(sum <= mark0) + return color; + if(sum <= mark1) + return c0 * color.a * color1.a; + if(sum <= mark2) + return c1 * color.a * color1.a; + + return c2 * color.a * color1.a; +} + +technique BasicColorDrawing +{ + pass P0 + { + PixelShader = compile PS_SHADERMODEL MainPS(); + } +}; \ No newline at end of file diff --git a/Content/Shader/ThanosShader.fx b/Content/Shader/ThanosShader.fx new file mode 100644 index 0000000..8c4644e --- /dev/null +++ b/Content/Shader/ThanosShader.fx @@ -0,0 +1,44 @@ +#if OPENGL + #define SV_POSITION POSITION + #define VS_SHADERMODEL vs_3_0 + #define PS_SHADERMODEL ps_3_0 +#else + #define VS_SHADERMODEL vs_4_0_level_9_1 + #define PS_SHADERMODEL ps_4_1 +#endif + +float4x4 World; +float4x4 View; +float4x4 Projection; + +Texture2D SpriteTexture; +sampler2D sampler0 : register(s0) +{ +}; + +Texture2D NoiceTexture; +sampler sampler1 : register(s1) +{ + Texture = (NoiceTexture); + Filter = POINT; +}; + +float Percentage; +float2 Scale; + +float4 PixelShaderFunction(float4 pos : SV_Position, float4 color1 : COLOR0, float2 coords : TEXCOORD0) : COLOR0 +{ + float4 texColor = tex2D(sampler0, coords); + if ((Percentage > 0 && Percentage >= tex2D(sampler1, coords * Scale).r) || Percentage == 1) + return float4(0, 0, 0, 0); + else + return texColor * color1; +} + +technique Technique1 +{ + pass Pass1 + { + PixelShader = compile PS_SHADERMODEL PixelShaderFunction(); + } +} \ No newline at end of file diff --git a/Content/Shader/WaleShader.fx b/Content/Shader/WaleShader.fx new file mode 100644 index 0000000..462c604 --- /dev/null +++ b/Content/Shader/WaleShader.fx @@ -0,0 +1,29 @@ +#if OPENGL + #define SV_POSITION POSITION + #define VS_SHADERMODEL vs_3_0 + #define PS_SHADERMODEL ps_3_0 +#else + #define VS_SHADERMODEL vs_4_0_level_9_1 + #define PS_SHADERMODEL ps_4_0_level_9_1 +#endif + +sampler s0; + +float Offset; +float Period; +float Time; + +float4 MainPS(float4 pos : SV_Position, float4 color0 : COLOR0, float2 coords : TEXCOORD0) : COLOR0 +{ + coords.x += sin(coords.y * Period + Time) * Offset; + float4 color = tex2D(s0, coords); + return color * color0; +} + +technique BasicColorDrawing +{ + pass P0 + { + PixelShader = compile PS_SHADERMODEL MainPS(); + } +}; \ No newline at end of file diff --git a/Content/Shader/WobbleShader.fx b/Content/Shader/WobbleShader.fx new file mode 100644 index 0000000..adf6f3f --- /dev/null +++ b/Content/Shader/WobbleShader.fx @@ -0,0 +1,36 @@ +#if OPENGL + #define SV_POSITION POSITION + #define VS_SHADERMODEL vs_3_0 + #define PS_SHADERMODEL ps_3_0 +#else + #define VS_SHADERMODEL vs_4_0_level_9_1 + #define PS_SHADERMODEL ps_4_0_level_9_1 +#endif + +#define PI 3.1415926538 + +sampler s0; + +int width; +int height; +float scale; +float brightness; +float offset; + +float offsetWidth; +float offsetHeight; + +float4 PixelShaderFunction(float4 pos : SV_Position, float4 color0 : COLOR0, float2 coords : TEXCOORD0) : COLOR0 +{ + // offset + float offsetX = sin(offset + coords.y * (height / scale) / offsetHeight * PI + PI / 2) * (offsetWidth / (width / scale)); + return tex2D(s0, float2(coords.x + offsetX, coords.y)) * (1 - brightness) + float4(1, 1, 1, 1) * brightness; +} + +technique Technique1 +{ + pass Pass1 + { + PixelShader = compile PS_SHADERMODEL PixelShaderFunction(); + } +} diff --git a/Content/SoundEffects/D360-01-01.wav b/Content/SoundEffects/D360-01-01.wav new file mode 100644 index 0000000..ebfa143 Binary files /dev/null and b/Content/SoundEffects/D360-01-01.wav differ diff --git a/Content/SoundEffects/D360-02-02.wav b/Content/SoundEffects/D360-02-02.wav new file mode 100644 index 0000000..e247dd0 Binary files /dev/null and b/Content/SoundEffects/D360-02-02.wav differ diff --git a/Content/SoundEffects/D360-03-03.wav b/Content/SoundEffects/D360-03-03.wav new file mode 100644 index 0000000..d960453 Binary files /dev/null and b/Content/SoundEffects/D360-03-03.wav differ diff --git a/Content/SoundEffects/D360-04-04.wav b/Content/SoundEffects/D360-04-04.wav new file mode 100644 index 0000000..521e24a Binary files /dev/null and b/Content/SoundEffects/D360-04-04.wav differ diff --git a/Content/SoundEffects/D360-05-05.wav b/Content/SoundEffects/D360-05-05.wav new file mode 100644 index 0000000..757e559 Binary files /dev/null and b/Content/SoundEffects/D360-05-05.wav differ diff --git a/Content/SoundEffects/D360-06-06.wav b/Content/SoundEffects/D360-06-06.wav new file mode 100644 index 0000000..aa31950 Binary files /dev/null and b/Content/SoundEffects/D360-06-06.wav differ diff --git a/Content/SoundEffects/D360-07-07.wav b/Content/SoundEffects/D360-07-07.wav new file mode 100644 index 0000000..375fe75 Binary files /dev/null and b/Content/SoundEffects/D360-07-07.wav differ diff --git a/Content/SoundEffects/D360-08-08.wav b/Content/SoundEffects/D360-08-08.wav new file mode 100644 index 0000000..01fcc9e Binary files /dev/null and b/Content/SoundEffects/D360-08-08.wav differ diff --git a/Content/SoundEffects/D360-09-09.wav b/Content/SoundEffects/D360-09-09.wav new file mode 100644 index 0000000..5872c1f Binary files /dev/null and b/Content/SoundEffects/D360-09-09.wav differ diff --git a/Content/SoundEffects/D360-10-0A.wav b/Content/SoundEffects/D360-10-0A.wav new file mode 100644 index 0000000..6c32010 Binary files /dev/null and b/Content/SoundEffects/D360-10-0A.wav differ diff --git a/Content/SoundEffects/D360-11-0B.wav b/Content/SoundEffects/D360-11-0B.wav new file mode 100644 index 0000000..e240512 Binary files /dev/null and b/Content/SoundEffects/D360-11-0B.wav differ diff --git a/Content/SoundEffects/D360-12-0C.wav b/Content/SoundEffects/D360-12-0C.wav new file mode 100644 index 0000000..dd79d03 Binary files /dev/null and b/Content/SoundEffects/D360-12-0C.wav differ diff --git a/Content/SoundEffects/D360-13-0D.wav b/Content/SoundEffects/D360-13-0D.wav new file mode 100644 index 0000000..350d83e Binary files /dev/null and b/Content/SoundEffects/D360-13-0D.wav differ diff --git a/Content/SoundEffects/D360-14-0E.wav b/Content/SoundEffects/D360-14-0E.wav new file mode 100644 index 0000000..4cf2644 Binary files /dev/null and b/Content/SoundEffects/D360-14-0E.wav differ diff --git a/Content/SoundEffects/D360-15-0F.wav b/Content/SoundEffects/D360-15-0F.wav new file mode 100644 index 0000000..d8f760c Binary files /dev/null and b/Content/SoundEffects/D360-15-0F.wav differ diff --git a/Content/SoundEffects/D360-16-10.wav b/Content/SoundEffects/D360-16-10.wav new file mode 100644 index 0000000..ccd9568 Binary files /dev/null and b/Content/SoundEffects/D360-16-10.wav differ diff --git a/Content/SoundEffects/D360-17-11.wav b/Content/SoundEffects/D360-17-11.wav new file mode 100644 index 0000000..2149735 Binary files /dev/null and b/Content/SoundEffects/D360-17-11.wav differ diff --git a/Content/SoundEffects/D360-18-12.wav b/Content/SoundEffects/D360-18-12.wav new file mode 100644 index 0000000..3ec7d74 Binary files /dev/null and b/Content/SoundEffects/D360-18-12.wav differ diff --git a/Content/SoundEffects/D360-19-13.wav b/Content/SoundEffects/D360-19-13.wav new file mode 100644 index 0000000..0191c1a Binary files /dev/null and b/Content/SoundEffects/D360-19-13.wav differ diff --git a/Content/SoundEffects/D360-20-14.wav b/Content/SoundEffects/D360-20-14.wav new file mode 100644 index 0000000..85128e5 Binary files /dev/null and b/Content/SoundEffects/D360-20-14.wav differ diff --git a/Content/SoundEffects/D360-21-15.wav b/Content/SoundEffects/D360-21-15.wav new file mode 100644 index 0000000..4738d37 Binary files /dev/null and b/Content/SoundEffects/D360-21-15.wav differ diff --git a/Content/SoundEffects/D360-22-16.wav b/Content/SoundEffects/D360-22-16.wav new file mode 100644 index 0000000..937ac14 Binary files /dev/null and b/Content/SoundEffects/D360-22-16.wav differ diff --git a/Content/SoundEffects/D360-23-17.wav b/Content/SoundEffects/D360-23-17.wav new file mode 100644 index 0000000..b8ab81d Binary files /dev/null and b/Content/SoundEffects/D360-23-17.wav differ diff --git a/Content/SoundEffects/D360-24-18.wav b/Content/SoundEffects/D360-24-18.wav new file mode 100644 index 0000000..af545dc Binary files /dev/null and b/Content/SoundEffects/D360-24-18.wav differ diff --git a/Content/SoundEffects/D360-25-19.wav b/Content/SoundEffects/D360-25-19.wav new file mode 100644 index 0000000..febf9dc Binary files /dev/null and b/Content/SoundEffects/D360-25-19.wav differ diff --git a/Content/SoundEffects/D360-26-1A.wav b/Content/SoundEffects/D360-26-1A.wav new file mode 100644 index 0000000..9e2472c Binary files /dev/null and b/Content/SoundEffects/D360-26-1A.wav differ diff --git a/Content/SoundEffects/D360-27-1B.wav b/Content/SoundEffects/D360-27-1B.wav new file mode 100644 index 0000000..a79d9f8 Binary files /dev/null and b/Content/SoundEffects/D360-27-1B.wav differ diff --git a/Content/SoundEffects/D360-28-1C.wav b/Content/SoundEffects/D360-28-1C.wav new file mode 100644 index 0000000..fa5c960 Binary files /dev/null and b/Content/SoundEffects/D360-28-1C.wav differ diff --git a/Content/SoundEffects/D360-29-1D.wav b/Content/SoundEffects/D360-29-1D.wav new file mode 100644 index 0000000..2492a28 Binary files /dev/null and b/Content/SoundEffects/D360-29-1D.wav differ diff --git a/Content/SoundEffects/D360-30-1E.wav b/Content/SoundEffects/D360-30-1E.wav new file mode 100644 index 0000000..c9eb050 Binary files /dev/null and b/Content/SoundEffects/D360-30-1E.wav differ diff --git a/Content/SoundEffects/D360-31-1F.wav b/Content/SoundEffects/D360-31-1F.wav new file mode 100644 index 0000000..cdbd449 Binary files /dev/null and b/Content/SoundEffects/D360-31-1F.wav differ diff --git a/Content/SoundEffects/D360-32-20.wav b/Content/SoundEffects/D360-32-20.wav new file mode 100644 index 0000000..e4f7794 Binary files /dev/null and b/Content/SoundEffects/D360-32-20.wav differ diff --git a/Content/SoundEffects/D360-33-21.wav b/Content/SoundEffects/D360-33-21.wav new file mode 100644 index 0000000..7d826f1 Binary files /dev/null and b/Content/SoundEffects/D360-33-21.wav differ diff --git a/Content/SoundEffects/D360-34-22.wav b/Content/SoundEffects/D360-34-22.wav new file mode 100644 index 0000000..dd702ec Binary files /dev/null and b/Content/SoundEffects/D360-34-22.wav differ diff --git a/Content/SoundEffects/D360-35-23.wav b/Content/SoundEffects/D360-35-23.wav new file mode 100644 index 0000000..c0d8a3f Binary files /dev/null and b/Content/SoundEffects/D360-35-23.wav differ diff --git a/Content/SoundEffects/D360-36-24.wav b/Content/SoundEffects/D360-36-24.wav new file mode 100644 index 0000000..436c107 Binary files /dev/null and b/Content/SoundEffects/D360-36-24.wav differ diff --git a/Content/SoundEffects/D360-37-25.wav b/Content/SoundEffects/D360-37-25.wav new file mode 100644 index 0000000..300b560 Binary files /dev/null and b/Content/SoundEffects/D360-37-25.wav differ diff --git a/Content/SoundEffects/D360-38-26.wav b/Content/SoundEffects/D360-38-26.wav new file mode 100644 index 0000000..3431b50 Binary files /dev/null and b/Content/SoundEffects/D360-38-26.wav differ diff --git a/Content/SoundEffects/D360-39-27.wav b/Content/SoundEffects/D360-39-27.wav new file mode 100644 index 0000000..ee53471 Binary files /dev/null and b/Content/SoundEffects/D360-39-27.wav differ diff --git a/Content/SoundEffects/D360-40-28.wav b/Content/SoundEffects/D360-40-28.wav new file mode 100644 index 0000000..3722fb3 Binary files /dev/null and b/Content/SoundEffects/D360-40-28.wav differ diff --git a/Content/SoundEffects/D360-41-29.wav b/Content/SoundEffects/D360-41-29.wav new file mode 100644 index 0000000..e4c2fc5 Binary files /dev/null and b/Content/SoundEffects/D360-41-29.wav differ diff --git a/Content/SoundEffects/D360-42-2A.wav b/Content/SoundEffects/D360-42-2A.wav new file mode 100644 index 0000000..ee6aba1 Binary files /dev/null and b/Content/SoundEffects/D360-42-2A.wav differ diff --git a/Content/SoundEffects/D360-43-2B.wav b/Content/SoundEffects/D360-43-2B.wav new file mode 100644 index 0000000..4310871 Binary files /dev/null and b/Content/SoundEffects/D360-43-2B.wav differ diff --git a/Content/SoundEffects/D360-44-2C.wav b/Content/SoundEffects/D360-44-2C.wav new file mode 100644 index 0000000..2914e2b Binary files /dev/null and b/Content/SoundEffects/D360-44-2C.wav differ diff --git a/Content/SoundEffects/D360-45-2D.wav b/Content/SoundEffects/D360-45-2D.wav new file mode 100644 index 0000000..9ecb4da Binary files /dev/null and b/Content/SoundEffects/D360-45-2D.wav differ diff --git a/Content/SoundEffects/D360-46-2E.wav b/Content/SoundEffects/D360-46-2E.wav new file mode 100644 index 0000000..92b905e Binary files /dev/null and b/Content/SoundEffects/D360-46-2E.wav differ diff --git a/Content/SoundEffects/D360-47-2F.wav b/Content/SoundEffects/D360-47-2F.wav new file mode 100644 index 0000000..11a15a3 Binary files /dev/null and b/Content/SoundEffects/D360-47-2F.wav differ diff --git a/Content/SoundEffects/D360-48-30.wav b/Content/SoundEffects/D360-48-30.wav new file mode 100644 index 0000000..6826785 Binary files /dev/null and b/Content/SoundEffects/D360-48-30.wav differ diff --git a/Content/SoundEffects/D360-49-31.wav b/Content/SoundEffects/D360-49-31.wav new file mode 100644 index 0000000..e486223 Binary files /dev/null and b/Content/SoundEffects/D360-49-31.wav differ diff --git a/Content/SoundEffects/D360-50-32.wav b/Content/SoundEffects/D360-50-32.wav new file mode 100644 index 0000000..782cda6 Binary files /dev/null and b/Content/SoundEffects/D360-50-32.wav differ diff --git a/Content/SoundEffects/D360-51-33.wav b/Content/SoundEffects/D360-51-33.wav new file mode 100644 index 0000000..7dc5ca3 Binary files /dev/null and b/Content/SoundEffects/D360-51-33.wav differ diff --git a/Content/SoundEffects/D360-52-34.wav b/Content/SoundEffects/D360-52-34.wav new file mode 100644 index 0000000..3c5ac28 Binary files /dev/null and b/Content/SoundEffects/D360-52-34.wav differ diff --git a/Content/SoundEffects/D360-53-35.wav b/Content/SoundEffects/D360-53-35.wav new file mode 100644 index 0000000..918ea7f Binary files /dev/null and b/Content/SoundEffects/D360-53-35.wav differ diff --git a/Content/SoundEffects/D360-54-36.wav b/Content/SoundEffects/D360-54-36.wav new file mode 100644 index 0000000..f0aa0c9 Binary files /dev/null and b/Content/SoundEffects/D360-54-36.wav differ diff --git a/Content/SoundEffects/D360-55-37.wav b/Content/SoundEffects/D360-55-37.wav new file mode 100644 index 0000000..9bff095 Binary files /dev/null and b/Content/SoundEffects/D360-55-37.wav differ diff --git a/Content/SoundEffects/D360-56-38.wav b/Content/SoundEffects/D360-56-38.wav new file mode 100644 index 0000000..74c4327 Binary files /dev/null and b/Content/SoundEffects/D360-56-38.wav differ diff --git a/Content/SoundEffects/D360-57-39.wav b/Content/SoundEffects/D360-57-39.wav new file mode 100644 index 0000000..03acc37 Binary files /dev/null and b/Content/SoundEffects/D360-57-39.wav differ diff --git a/Content/SoundEffects/D360-58-3A.wav b/Content/SoundEffects/D360-58-3A.wav new file mode 100644 index 0000000..8c1c7c6 Binary files /dev/null and b/Content/SoundEffects/D360-58-3A.wav differ diff --git a/Content/SoundEffects/D360-59-3B.wav b/Content/SoundEffects/D360-59-3B.wav new file mode 100644 index 0000000..7ceee7f Binary files /dev/null and b/Content/SoundEffects/D360-59-3B.wav differ diff --git a/Content/SoundEffects/D360-60-3C.wav b/Content/SoundEffects/D360-60-3C.wav new file mode 100644 index 0000000..9ee8923 Binary files /dev/null and b/Content/SoundEffects/D360-60-3C.wav differ diff --git a/Content/SoundEffects/D360-61-3D.wav b/Content/SoundEffects/D360-61-3D.wav new file mode 100644 index 0000000..c7171c2 Binary files /dev/null and b/Content/SoundEffects/D360-61-3D.wav differ diff --git a/Content/SoundEffects/D360-62-3E.wav b/Content/SoundEffects/D360-62-3E.wav new file mode 100644 index 0000000..5a5a9c8 Binary files /dev/null and b/Content/SoundEffects/D360-62-3E.wav differ diff --git a/Content/SoundEffects/D360-63-3F.wav b/Content/SoundEffects/D360-63-3F.wav new file mode 100644 index 0000000..82e7115 Binary files /dev/null and b/Content/SoundEffects/D360-63-3F.wav differ diff --git a/Content/SoundEffects/D360-64-40.wav b/Content/SoundEffects/D360-64-40.wav new file mode 100644 index 0000000..e7ed492 Binary files /dev/null and b/Content/SoundEffects/D360-64-40.wav differ diff --git a/Content/SoundEffects/D360-65-41.wav b/Content/SoundEffects/D360-65-41.wav new file mode 100644 index 0000000..2df3abc Binary files /dev/null and b/Content/SoundEffects/D360-65-41.wav differ diff --git a/Content/SoundEffects/D368-16-10.wav b/Content/SoundEffects/D368-16-10.wav new file mode 100644 index 0000000..5c74380 Binary files /dev/null and b/Content/SoundEffects/D368-16-10.wav differ diff --git a/Content/SoundEffects/D370-01-01.wav b/Content/SoundEffects/D370-01-01.wav new file mode 100644 index 0000000..5180b52 Binary files /dev/null and b/Content/SoundEffects/D370-01-01.wav differ diff --git a/Content/SoundEffects/D370-02-02.wav b/Content/SoundEffects/D370-02-02.wav new file mode 100644 index 0000000..4cf0271 Binary files /dev/null and b/Content/SoundEffects/D370-02-02.wav differ diff --git a/Content/SoundEffects/D370-03-03.wav b/Content/SoundEffects/D370-03-03.wav new file mode 100644 index 0000000..3a19d21 Binary files /dev/null and b/Content/SoundEffects/D370-03-03.wav differ diff --git a/Content/SoundEffects/D370-04-04.wav b/Content/SoundEffects/D370-04-04.wav new file mode 100644 index 0000000..066e531 Binary files /dev/null and b/Content/SoundEffects/D370-04-04.wav differ diff --git a/Content/SoundEffects/D370-05-05.wav b/Content/SoundEffects/D370-05-05.wav new file mode 100644 index 0000000..a981c4a Binary files /dev/null and b/Content/SoundEffects/D370-05-05.wav differ diff --git a/Content/SoundEffects/D370-06-06.wav b/Content/SoundEffects/D370-06-06.wav new file mode 100644 index 0000000..14ef34c Binary files /dev/null and b/Content/SoundEffects/D370-06-06.wav differ diff --git a/Content/SoundEffects/D370-07-07.wav b/Content/SoundEffects/D370-07-07.wav new file mode 100644 index 0000000..1b2b754 Binary files /dev/null and b/Content/SoundEffects/D370-07-07.wav differ diff --git a/Content/SoundEffects/D370-08-08.wav b/Content/SoundEffects/D370-08-08.wav new file mode 100644 index 0000000..2d5d02b Binary files /dev/null and b/Content/SoundEffects/D370-08-08.wav differ diff --git a/Content/SoundEffects/D370-09-09.wav b/Content/SoundEffects/D370-09-09.wav new file mode 100644 index 0000000..e4fe61d Binary files /dev/null and b/Content/SoundEffects/D370-09-09.wav differ diff --git a/Content/SoundEffects/D370-10-0A.wav b/Content/SoundEffects/D370-10-0A.wav new file mode 100644 index 0000000..75bdaf3 Binary files /dev/null and b/Content/SoundEffects/D370-10-0A.wav differ diff --git a/Content/SoundEffects/D370-11-0B.wav b/Content/SoundEffects/D370-11-0B.wav new file mode 100644 index 0000000..745f053 Binary files /dev/null and b/Content/SoundEffects/D370-11-0B.wav differ diff --git a/Content/SoundEffects/D370-12-0C.wav b/Content/SoundEffects/D370-12-0C.wav new file mode 100644 index 0000000..777b288 Binary files /dev/null and b/Content/SoundEffects/D370-12-0C.wav differ diff --git a/Content/SoundEffects/D370-13-0D.wav b/Content/SoundEffects/D370-13-0D.wav new file mode 100644 index 0000000..029f5c4 Binary files /dev/null and b/Content/SoundEffects/D370-13-0D.wav differ diff --git a/Content/SoundEffects/D370-14-0E.wav b/Content/SoundEffects/D370-14-0E.wav new file mode 100644 index 0000000..2576781 Binary files /dev/null and b/Content/SoundEffects/D370-14-0E.wav differ diff --git a/Content/SoundEffects/D370-15-0F.wav b/Content/SoundEffects/D370-15-0F.wav new file mode 100644 index 0000000..5fe99ba Binary files /dev/null and b/Content/SoundEffects/D370-15-0F.wav differ diff --git a/Content/SoundEffects/D370-16-10.wav b/Content/SoundEffects/D370-16-10.wav new file mode 100644 index 0000000..0e12e5d Binary files /dev/null and b/Content/SoundEffects/D370-16-10.wav differ diff --git a/Content/SoundEffects/D370-17-11.wav b/Content/SoundEffects/D370-17-11.wav new file mode 100644 index 0000000..1c112b0 Binary files /dev/null and b/Content/SoundEffects/D370-17-11.wav differ diff --git a/Content/SoundEffects/D370-18-12.wav b/Content/SoundEffects/D370-18-12.wav new file mode 100644 index 0000000..5c8fee2 Binary files /dev/null and b/Content/SoundEffects/D370-18-12.wav differ diff --git a/Content/SoundEffects/D370-19-13.wav b/Content/SoundEffects/D370-19-13.wav new file mode 100644 index 0000000..9a05551 Binary files /dev/null and b/Content/SoundEffects/D370-19-13.wav differ diff --git a/Content/SoundEffects/D370-20-14.wav b/Content/SoundEffects/D370-20-14.wav new file mode 100644 index 0000000..0f1eeaf Binary files /dev/null and b/Content/SoundEffects/D370-20-14.wav differ diff --git a/Content/SoundEffects/D370-21-15.wav b/Content/SoundEffects/D370-21-15.wav new file mode 100644 index 0000000..5569d47 Binary files /dev/null and b/Content/SoundEffects/D370-21-15.wav differ diff --git a/Content/SoundEffects/D370-22-16.wav b/Content/SoundEffects/D370-22-16.wav new file mode 100644 index 0000000..8923cbe Binary files /dev/null and b/Content/SoundEffects/D370-22-16.wav differ diff --git a/Content/SoundEffects/D370-23-17.wav b/Content/SoundEffects/D370-23-17.wav new file mode 100644 index 0000000..74dc1df Binary files /dev/null and b/Content/SoundEffects/D370-23-17.wav differ diff --git a/Content/SoundEffects/D370-24-18.wav b/Content/SoundEffects/D370-24-18.wav new file mode 100644 index 0000000..03a7ec0 Binary files /dev/null and b/Content/SoundEffects/D370-24-18.wav differ diff --git a/Content/SoundEffects/D370-25-19.wav b/Content/SoundEffects/D370-25-19.wav new file mode 100644 index 0000000..27c065c Binary files /dev/null and b/Content/SoundEffects/D370-25-19.wav differ diff --git a/Content/SoundEffects/D370-26-1A.wav b/Content/SoundEffects/D370-26-1A.wav new file mode 100644 index 0000000..6579ddc Binary files /dev/null and b/Content/SoundEffects/D370-26-1A.wav differ diff --git a/Content/SoundEffects/D370-27-1B.wav b/Content/SoundEffects/D370-27-1B.wav new file mode 100644 index 0000000..ba805a7 Binary files /dev/null and b/Content/SoundEffects/D370-27-1B.wav differ diff --git a/Content/SoundEffects/D370-28-1C.wav b/Content/SoundEffects/D370-28-1C.wav new file mode 100644 index 0000000..e788f7a Binary files /dev/null and b/Content/SoundEffects/D370-28-1C.wav differ diff --git a/Content/SoundEffects/D370-30-1E.wav b/Content/SoundEffects/D370-30-1E.wav new file mode 100644 index 0000000..951e1c3 Binary files /dev/null and b/Content/SoundEffects/D370-30-1E.wav differ diff --git a/Content/SoundEffects/D370-31-1F.wav b/Content/SoundEffects/D370-31-1F.wav new file mode 100644 index 0000000..aff43f0 Binary files /dev/null and b/Content/SoundEffects/D370-31-1F.wav differ diff --git a/Content/SoundEffects/D370-32-20.wav b/Content/SoundEffects/D370-32-20.wav new file mode 100644 index 0000000..2b1e2a8 Binary files /dev/null and b/Content/SoundEffects/D370-32-20.wav differ diff --git a/Content/SoundEffects/D370-33-21.wav b/Content/SoundEffects/D370-33-21.wav new file mode 100644 index 0000000..2d9a079 Binary files /dev/null and b/Content/SoundEffects/D370-33-21.wav differ diff --git a/Content/SoundEffects/D370-34-22.wav b/Content/SoundEffects/D370-34-22.wav new file mode 100644 index 0000000..2b1e2a8 Binary files /dev/null and b/Content/SoundEffects/D370-34-22.wav differ diff --git a/Content/SoundEffects/D370-35-23.wav b/Content/SoundEffects/D370-35-23.wav new file mode 100644 index 0000000..bdab6f2 Binary files /dev/null and b/Content/SoundEffects/D370-35-23.wav differ diff --git a/Content/SoundEffects/D378-01-01.wav b/Content/SoundEffects/D378-01-01.wav new file mode 100644 index 0000000..6336d9c Binary files /dev/null and b/Content/SoundEffects/D378-01-01.wav differ diff --git a/Content/SoundEffects/D378-02-02.wav b/Content/SoundEffects/D378-02-02.wav new file mode 100644 index 0000000..90c125e Binary files /dev/null and b/Content/SoundEffects/D378-02-02.wav differ diff --git a/Content/SoundEffects/D378-03-03.wav b/Content/SoundEffects/D378-03-03.wav new file mode 100644 index 0000000..5b53b7b Binary files /dev/null and b/Content/SoundEffects/D378-03-03.wav differ diff --git a/Content/SoundEffects/D378-04-04.wav b/Content/SoundEffects/D378-04-04.wav new file mode 100644 index 0000000..aa8f866 Binary files /dev/null and b/Content/SoundEffects/D378-04-04.wav differ diff --git a/Content/SoundEffects/D378-05-05.wav b/Content/SoundEffects/D378-05-05.wav new file mode 100644 index 0000000..3610353 Binary files /dev/null and b/Content/SoundEffects/D378-05-05.wav differ diff --git a/Content/SoundEffects/D378-06-06.wav b/Content/SoundEffects/D378-06-06.wav new file mode 100644 index 0000000..6b1f4fa Binary files /dev/null and b/Content/SoundEffects/D378-06-06.wav differ diff --git a/Content/SoundEffects/D378-07-07.wav b/Content/SoundEffects/D378-07-07.wav new file mode 100644 index 0000000..c5a8f3c Binary files /dev/null and b/Content/SoundEffects/D378-07-07.wav differ diff --git a/Content/SoundEffects/D378-08-08.wav b/Content/SoundEffects/D378-08-08.wav new file mode 100644 index 0000000..47e0e31 Binary files /dev/null and b/Content/SoundEffects/D378-08-08.wav differ diff --git a/Content/SoundEffects/D378-09-09.wav b/Content/SoundEffects/D378-09-09.wav new file mode 100644 index 0000000..e40edfd Binary files /dev/null and b/Content/SoundEffects/D378-09-09.wav differ diff --git a/Content/SoundEffects/D378-10-0A.wav b/Content/SoundEffects/D378-10-0A.wav new file mode 100644 index 0000000..a334c95 Binary files /dev/null and b/Content/SoundEffects/D378-10-0A.wav differ diff --git a/Content/SoundEffects/D378-11-0B.wav b/Content/SoundEffects/D378-11-0B.wav new file mode 100644 index 0000000..f86be20 Binary files /dev/null and b/Content/SoundEffects/D378-11-0B.wav differ diff --git a/Content/SoundEffects/D378-12-0C.wav b/Content/SoundEffects/D378-12-0C.wav new file mode 100644 index 0000000..c0daf84 Binary files /dev/null and b/Content/SoundEffects/D378-12-0C.wav differ diff --git a/Content/SoundEffects/D378-13-0D.wav b/Content/SoundEffects/D378-13-0D.wav new file mode 100644 index 0000000..6fb7f89 Binary files /dev/null and b/Content/SoundEffects/D378-13-0D.wav differ diff --git a/Content/SoundEffects/D378-14-0E.wav b/Content/SoundEffects/D378-14-0E.wav new file mode 100644 index 0000000..eede8e7 Binary files /dev/null and b/Content/SoundEffects/D378-14-0E.wav differ diff --git a/Content/SoundEffects/D378-15-0F.wav b/Content/SoundEffects/D378-15-0F.wav new file mode 100644 index 0000000..a757087 Binary files /dev/null and b/Content/SoundEffects/D378-15-0F.wav differ diff --git a/Content/SoundEffects/D378-16-10.wav b/Content/SoundEffects/D378-16-10.wav new file mode 100644 index 0000000..bd2879f Binary files /dev/null and b/Content/SoundEffects/D378-16-10.wav differ diff --git a/Content/SoundEffects/D378-17-11.wav b/Content/SoundEffects/D378-17-11.wav new file mode 100644 index 0000000..1c1cc84 Binary files /dev/null and b/Content/SoundEffects/D378-17-11.wav differ diff --git a/Content/SoundEffects/D378-18-12.wav b/Content/SoundEffects/D378-18-12.wav new file mode 100644 index 0000000..cbef658 Binary files /dev/null and b/Content/SoundEffects/D378-18-12.wav differ diff --git a/Content/SoundEffects/D378-19-13.wav b/Content/SoundEffects/D378-19-13.wav new file mode 100644 index 0000000..7b51406 Binary files /dev/null and b/Content/SoundEffects/D378-19-13.wav differ diff --git a/Content/SoundEffects/D378-20-14.wav b/Content/SoundEffects/D378-20-14.wav new file mode 100644 index 0000000..f35ef0e Binary files /dev/null and b/Content/SoundEffects/D378-20-14.wav differ diff --git a/Content/SoundEffects/D378-21-15.wav b/Content/SoundEffects/D378-21-15.wav new file mode 100644 index 0000000..bac1d44 Binary files /dev/null and b/Content/SoundEffects/D378-21-15.wav differ diff --git a/Content/SoundEffects/D378-22-16.wav b/Content/SoundEffects/D378-22-16.wav new file mode 100644 index 0000000..4a8e2bc Binary files /dev/null and b/Content/SoundEffects/D378-22-16.wav differ diff --git a/Content/SoundEffects/D378-23-17.wav b/Content/SoundEffects/D378-23-17.wav new file mode 100644 index 0000000..59bb11a Binary files /dev/null and b/Content/SoundEffects/D378-23-17.wav differ diff --git a/Content/SoundEffects/D378-24-18.wav b/Content/SoundEffects/D378-24-18.wav new file mode 100644 index 0000000..3e27dea Binary files /dev/null and b/Content/SoundEffects/D378-24-18.wav differ diff --git a/Content/SoundEffects/D378-25-19.wav b/Content/SoundEffects/D378-25-19.wav new file mode 100644 index 0000000..ca7892b Binary files /dev/null and b/Content/SoundEffects/D378-25-19.wav differ diff --git a/Content/SoundEffects/D378-26-1A.wav b/Content/SoundEffects/D378-26-1A.wav new file mode 100644 index 0000000..ebe05c9 Binary files /dev/null and b/Content/SoundEffects/D378-26-1A.wav differ diff --git a/Content/SoundEffects/D378-27-1B.wav b/Content/SoundEffects/D378-27-1B.wav new file mode 100644 index 0000000..9120bbf Binary files /dev/null and b/Content/SoundEffects/D378-27-1B.wav differ diff --git a/Content/SoundEffects/D378-28-1C.wav b/Content/SoundEffects/D378-28-1C.wav new file mode 100644 index 0000000..1486c1c Binary files /dev/null and b/Content/SoundEffects/D378-28-1C.wav differ diff --git a/Content/SoundEffects/D378-29-1D.wav b/Content/SoundEffects/D378-29-1D.wav new file mode 100644 index 0000000..687c59b Binary files /dev/null and b/Content/SoundEffects/D378-29-1D.wav differ diff --git a/Content/SoundEffects/D378-30-1E.wav b/Content/SoundEffects/D378-30-1E.wav new file mode 100644 index 0000000..789d359 Binary files /dev/null and b/Content/SoundEffects/D378-30-1E.wav differ diff --git a/Content/SoundEffects/D378-31-1F.wav b/Content/SoundEffects/D378-31-1F.wav new file mode 100644 index 0000000..154fd74 Binary files /dev/null and b/Content/SoundEffects/D378-31-1F.wav differ diff --git a/Content/SoundEffects/D378-32-20.wav b/Content/SoundEffects/D378-32-20.wav new file mode 100644 index 0000000..1ccbfc0 Binary files /dev/null and b/Content/SoundEffects/D378-32-20.wav differ diff --git a/Content/SoundEffects/D378-33-21.wav b/Content/SoundEffects/D378-33-21.wav new file mode 100644 index 0000000..2ae6b01 Binary files /dev/null and b/Content/SoundEffects/D378-33-21.wav differ diff --git a/Content/SoundEffects/D378-34-22.wav b/Content/SoundEffects/D378-34-22.wav new file mode 100644 index 0000000..556b197 Binary files /dev/null and b/Content/SoundEffects/D378-34-22.wav differ diff --git a/Content/SoundEffects/D378-35-23.wav b/Content/SoundEffects/D378-35-23.wav new file mode 100644 index 0000000..7076726 Binary files /dev/null and b/Content/SoundEffects/D378-35-23.wav differ diff --git a/Content/SoundEffects/D378-36-24.wav b/Content/SoundEffects/D378-36-24.wav new file mode 100644 index 0000000..f90ebbd Binary files /dev/null and b/Content/SoundEffects/D378-36-24.wav differ diff --git a/Content/SoundEffects/D378-37-25.wav b/Content/SoundEffects/D378-37-25.wav new file mode 100644 index 0000000..72d63db Binary files /dev/null and b/Content/SoundEffects/D378-37-25.wav differ diff --git a/Content/SoundEffects/D378-38-26.wav b/Content/SoundEffects/D378-38-26.wav new file mode 100644 index 0000000..9458963 Binary files /dev/null and b/Content/SoundEffects/D378-38-26.wav differ diff --git a/Content/SoundEffects/D378-39-27.wav b/Content/SoundEffects/D378-39-27.wav new file mode 100644 index 0000000..d9d44b2 Binary files /dev/null and b/Content/SoundEffects/D378-39-27.wav differ diff --git a/Content/SoundEffects/D378-40-28.wav b/Content/SoundEffects/D378-40-28.wav new file mode 100644 index 0000000..031c25b Binary files /dev/null and b/Content/SoundEffects/D378-40-28.wav differ diff --git a/Content/SoundEffects/D378-41-29.wav b/Content/SoundEffects/D378-41-29.wav new file mode 100644 index 0000000..f67ca93 Binary files /dev/null and b/Content/SoundEffects/D378-41-29.wav differ diff --git a/Content/SoundEffects/D378-42-2A.wav b/Content/SoundEffects/D378-42-2A.wav new file mode 100644 index 0000000..de2a8d3 Binary files /dev/null and b/Content/SoundEffects/D378-42-2A.wav differ diff --git a/Content/SoundEffects/D378-43-2B.wav b/Content/SoundEffects/D378-43-2B.wav new file mode 100644 index 0000000..7b2fe89 Binary files /dev/null and b/Content/SoundEffects/D378-43-2B.wav differ diff --git a/Content/SoundEffects/D378-44-2C.wav b/Content/SoundEffects/D378-44-2C.wav new file mode 100644 index 0000000..59393bc Binary files /dev/null and b/Content/SoundEffects/D378-44-2C.wav differ diff --git a/Content/SoundEffects/D378-45-2D.wav b/Content/SoundEffects/D378-45-2D.wav new file mode 100644 index 0000000..6901e90 Binary files /dev/null and b/Content/SoundEffects/D378-45-2D.wav differ diff --git a/Content/SoundEffects/D378-46-2E.wav b/Content/SoundEffects/D378-46-2E.wav new file mode 100644 index 0000000..d9e40db Binary files /dev/null and b/Content/SoundEffects/D378-46-2E.wav differ diff --git a/Content/SoundEffects/D378-47-2F.wav b/Content/SoundEffects/D378-47-2F.wav new file mode 100644 index 0000000..cfe20dc Binary files /dev/null and b/Content/SoundEffects/D378-47-2F.wav differ diff --git a/Content/SoundEffects/D378-48-30.wav b/Content/SoundEffects/D378-48-30.wav new file mode 100644 index 0000000..12432c2 Binary files /dev/null and b/Content/SoundEffects/D378-48-30.wav differ diff --git a/Content/SoundEffects/D378-49-31.wav b/Content/SoundEffects/D378-49-31.wav new file mode 100644 index 0000000..d0efbdb Binary files /dev/null and b/Content/SoundEffects/D378-49-31.wav differ diff --git a/Content/SoundEffects/D378-50-32.wav b/Content/SoundEffects/D378-50-32.wav new file mode 100644 index 0000000..aa1b99d Binary files /dev/null and b/Content/SoundEffects/D378-50-32.wav differ diff --git a/Content/SoundEffects/D378-51-33.wav b/Content/SoundEffects/D378-51-33.wav new file mode 100644 index 0000000..085ed31 Binary files /dev/null and b/Content/SoundEffects/D378-51-33.wav differ diff --git a/Content/SoundEffects/D378-52-34.wav b/Content/SoundEffects/D378-52-34.wav new file mode 100644 index 0000000..308b00b Binary files /dev/null and b/Content/SoundEffects/D378-52-34.wav differ diff --git a/Content/SoundEffects/D378-53-35.wav b/Content/SoundEffects/D378-53-35.wav new file mode 100644 index 0000000..504cd26 Binary files /dev/null and b/Content/SoundEffects/D378-53-35.wav differ diff --git a/Content/SoundEffects/D378-54-36.wav b/Content/SoundEffects/D378-54-36.wav new file mode 100644 index 0000000..aef9662 Binary files /dev/null and b/Content/SoundEffects/D378-54-36.wav differ diff --git a/Content/SoundEffects/D378-55-37.wav b/Content/SoundEffects/D378-55-37.wav new file mode 100644 index 0000000..04c90c2 Binary files /dev/null and b/Content/SoundEffects/D378-55-37.wav differ diff --git a/Content/SoundEffects/D378-56-38.wav b/Content/SoundEffects/D378-56-38.wav new file mode 100644 index 0000000..38b2354 Binary files /dev/null and b/Content/SoundEffects/D378-56-38.wav differ diff --git a/Content/SoundEffects/D378-57-39.wav b/Content/SoundEffects/D378-57-39.wav new file mode 100644 index 0000000..026ec83 Binary files /dev/null and b/Content/SoundEffects/D378-57-39.wav differ diff --git a/Content/SoundEffects/D378-58-3A.wav b/Content/SoundEffects/D378-58-3A.wav new file mode 100644 index 0000000..ddecb92 Binary files /dev/null and b/Content/SoundEffects/D378-58-3A.wav differ diff --git a/Content/SoundEffects/D378-59-3B.wav b/Content/SoundEffects/D378-59-3B.wav new file mode 100644 index 0000000..f5789a2 Binary files /dev/null and b/Content/SoundEffects/D378-59-3B.wav differ diff --git a/Content/SoundEffects/D378-60-3D.wav b/Content/SoundEffects/D378-60-3D.wav new file mode 100644 index 0000000..645b415 Binary files /dev/null and b/Content/SoundEffects/D378-60-3D.wav differ diff --git a/Content/SoundEffects/D378-61-3E.wav b/Content/SoundEffects/D378-61-3E.wav new file mode 100644 index 0000000..5940756 Binary files /dev/null and b/Content/SoundEffects/D378-61-3E.wav differ diff --git a/Content/SoundEffects/D378-62-3F.wav b/Content/SoundEffects/D378-62-3F.wav new file mode 100644 index 0000000..22fad19 Binary files /dev/null and b/Content/SoundEffects/D378-62-3F.wav differ diff --git a/Content/SoundEffects/D378-63-40.wav b/Content/SoundEffects/D378-63-40.wav new file mode 100644 index 0000000..22909b2 Binary files /dev/null and b/Content/SoundEffects/D378-63-40.wav differ diff --git a/Content/SoundEffects/D378-64-41.wav b/Content/SoundEffects/D378-64-41.wav new file mode 100644 index 0000000..e0d31de Binary files /dev/null and b/Content/SoundEffects/D378-64-41.wav differ diff --git a/Editor/AnimationScreen.cs b/Editor/AnimationScreen.cs new file mode 100644 index 0000000..b08aba7 --- /dev/null +++ b/Editor/AnimationScreen.cs @@ -0,0 +1,734 @@ +using System; +using System.IO; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.Base.UI; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +#if WINDOWS +using System.Windows.Forms; +#endif + +namespace ProjectZ.Editor +{ + internal class AnimationScreen : InGame.Screens.Screen + { + private readonly EditorCamera _camera = new EditorCamera(); + + private Animator _animator = new Animator(); + private Animator _overlayAnimator; + private Texture2D _sprAnimator; + + private Point _currentPosition, _selectionStart, _selectionEnd; + private UiNumberInput _animationInput, _frameInput, _numberInputX, _numberInputY, _numberInputWidth, _numberInputHeight; + private UiNumberInput _niOffsetX, _niOffsetY, _niAnOffsetX, _niAnOffsetY, _fpsInput, _loopCountInput; + private UiTextInput _animationName, _nextAnimationName; + private UiLabel _animationUiLabel, _frameUiLabel; + private UiCheckBox _checkBoxLoop, _cbFrameMirroredV, _cbFrameMirroredH; + + private string _sprPath; + private string _lastFileName; + private const float MinScale = 1; + private const float MaxScale = 10; + private const int LeftBarWidth = 200; + private const int RightBarWidth = 300; + private const int TileSize = 2; + private int _selectedAnimation, _selectedFrame; + private bool _selecting; + private bool _collisionRectangleMode; + private bool _isPlaying; + private bool _showAllSelections; + + public AnimationScreen(string screenId) : base(screenId) { } + + public override void Load(ContentManager content) + { + var buttonDist = 5; + var buttonWidth = LeftBarWidth - buttonDist * 2; + var buttonWidthHalf = (LeftBarWidth - buttonDist * 3) / 2; + var buttonHeight = 30; + var labelHeight = Resources.EditorFontHeight; + var buttonQWidth = LeftBarWidth - 15 - buttonHeight; + var posY = Values.ToolBarHeight + buttonDist; + + var screenId = Values.EditorUiAnimation; + + Game1.EditorUi.AddElement(new UiRectangle(new Rectangle(0, 0, 0, 0), "leftBackground", screenId, Values.ColorBackgroundLight, Color.White, + ui => { ui.Rectangle = new Rectangle(0, Values.ToolBarHeight, LeftBarWidth, Game1.WindowHeight - Values.ToolBarHeight); })); + + Game1.EditorUi.AddElement(new UiRectangle(new Rectangle(0, 0, 0, 0), "rightBackground", screenId, Values.ColorBackgroundLight, Color.White, + ui => { ui.Rectangle = new Rectangle(Game1.WindowWidth - RightBarWidth, Values.ToolBarHeight, RightBarWidth, Game1.WindowHeight - Values.ToolBarHeight - RightBarWidth); })); + // animation background + Game1.EditorUi.AddElement(new UiRectangle(new Rectangle(0, 0, 0, 0), "rightAnimationBackground", screenId, Color.White * 0.5f, Color.White, + ui => { ui.Rectangle = new Rectangle(Game1.WindowWidth - RightBarWidth, Game1.WindowHeight - RightBarWidth, RightBarWidth, RightBarWidth); })); + + // right toolbar + Game1.EditorUi.AddElement(new UiButton(Rectangle.Empty, Resources.EditorFont, "load overlay", "bt1", screenId, + ui => { ui.Rectangle = new Rectangle(Game1.WindowWidth - RightBarWidth + 5, Values.ToolBarHeight + buttonDist, buttonWidth, buttonHeight); }, + ui => { LoadOverlayAnimation(); })); + + Game1.EditorUi.AddElement(new UiButton(Rectangle.Empty, Resources.EditorFont, "play/pause", "bt1", screenId, + ui => { ui.Rectangle = new Rectangle(Game1.WindowWidth - RightBarWidth + 5, Values.ToolBarHeight + buttonDist * 2 + buttonHeight, buttonWidth, buttonHeight); }, + ui => { _isPlaying = !_isPlaying; })); + + posY = Values.ToolBarHeight + buttonDist; + + // load button + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY, buttonWidth, buttonHeight), Resources.EditorFont, + "load", "bt1", screenId, null, ui => { LoadAnimation(); })); + + // save button + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight), Resources.EditorFont, + "save as...", "bt1", screenId, null, ui => { SaveAnimationDialog(); })); + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight), Resources.EditorFont, + "save...", "bt1", screenId, null, ui => { SaveAnimation(); })); + + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight), Resources.EditorFont, + "updated animations", "bt1", screenId, null, ui => { UpdateAnimations(); })); + + // load image + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight), Resources.EditorFont, + "load image", "bt1", screenId, null, ui => { LoadImage(); })); + // clear animation + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight), Resources.EditorFont, + "clear animator", "bt1", screenId, null, ui => { CreateAnimator(); })); + + Game1.EditorUi.AddElement(new UiCheckBox(new Rectangle(5, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight), + Resources.EditorFont, "show all selections", "showAllSelections", screenId, false, null, + ui => { _showAllSelections = ((UiCheckBox)ui).CurrentState; })); + + Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist, posY += buttonHeight + buttonDist * 3, buttonWidth, labelHeight), + Resources.EditorFont, "Animation", "frameHeader", screenId, null)); + + _animationUiLabel = new UiLabel(new Rectangle(buttonDist, posY += labelHeight + buttonDist, buttonWidthHalf, buttonHeight), + Resources.EditorFont, "animation", "flable", screenId, ui => { ui.Label = "[" + (_selectedAnimation + 1) + "/" + _animator.Animations.Count + "]"; }); + Game1.EditorUi.AddElement(_animationUiLabel); + _animationInput = new UiNumberInput(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, buttonWidthHalf, buttonHeight), + Resources.EditorFont, 1, 1, 1, 1, "numberX", screenId, + ui => { ((UiNumberInput)ui).MaxValue = _animator.Animations.Count; }, + ui => { ChangeAnimation((int)((UiNumberInput)ui).Value - 1); }); + Game1.EditorUi.AddElement(_animationInput); + + // add animation + Game1.EditorUi.AddElement(new UiButton(new Rectangle(buttonDist, posY += buttonHeight + buttonDist, buttonWidthHalf, buttonHeight), + Resources.EditorFont, "add", "bt1", screenId, null, ui => { AddAnimation(); })); + Game1.EditorUi.AddElement(new UiButton(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, buttonWidthHalf, buttonHeight), + Resources.EditorFont, "remove", "bt1", screenId, null, ui => { RemoveAnimation(); })); + + // animation name + var animationNameLabel = new UiLabel(new Rectangle(buttonDist, posY += buttonHeight + buttonDist, buttonWidth, labelHeight), + Resources.EditorFont, "name", "lableX", screenId, null); + Game1.EditorUi.AddElement(animationNameLabel); + _animationName = new UiTextInput(new Rectangle(buttonDist, posY += labelHeight, buttonWidth, buttonHeight), + Resources.EditorFontMonoSpace, 20, "animationName", screenId, null, ui => { _animator.Animations[_selectedAnimation].Id = ((UiTextInput)ui).StrValue; }); + Game1.EditorUi.AddElement(_animationName); + + // next animation + var nextAnimationLabel = new UiLabel(new Rectangle(buttonDist, posY += buttonHeight + buttonDist, buttonWidth, labelHeight), + Resources.EditorFont, "next animation", "lableX", screenId, null); + Game1.EditorUi.AddElement(nextAnimationLabel); + _nextAnimationName = new UiTextInput(new Rectangle(buttonDist, posY += labelHeight, buttonWidth, buttonHeight), + Resources.EditorFontMonoSpace, 20, "nextAnimationName", screenId, null, + ui => { _animator.Animations[_selectedAnimation].NextAnimation = ((UiTextInput)ui).StrValue; }); + Game1.EditorUi.AddElement(_nextAnimationName); + + // collision + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight), Resources.EditorFont, + "collision mode", "bt1", screenId, ui => { ((UiButton)ui).Marked = _collisionRectangleMode; }, + ui => { _collisionRectangleMode = !_collisionRectangleMode; })); + + //// loop checkbox + //_checkBoxLoop = new CheckBox(new Rectangle(5, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight), Resources.EditorFont, + // "loop", "cbloop", screenId, false, ui => { ((CheckBox)ui).CurrentState = _animator.CurrentAnimation.Looping; }, + // ui => { _animator.CurrentAnimation.Looping = ((CheckBox)ui).CurrentState; }); + //Game1.EditorUi.AddElement(_checkBoxLoop); + + Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist, posY += buttonHeight + buttonDist, buttonWidthHalf, buttonHeight), + Resources.EditorFont, "Loops", "flable", screenId, null)); + _loopCountInput = new UiNumberInput(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, buttonWidthHalf, buttonHeight), + Resources.EditorFont, 1, -1, 999, 1, "loopCount", screenId, null, + ui => _animator.Animations[_selectedAnimation].LoopCount = (int)((UiNumberInput)ui).Value); + Game1.EditorUi.AddElement(_loopCountInput); + + + Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist, posY += buttonHeight + buttonDist * 3, buttonWidth, labelHeight), + Resources.EditorFont, "Frame", "frameHeader", screenId, null)); + + // frame information + Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist, posY += labelHeight + buttonDist, buttonWidthHalf, buttonHeight), + Resources.EditorFont, "frame", "flable", screenId, + ui => { ui.Label = "frame [" + (_selectedFrame + 1) + "/" + _animator.Animations[_selectedAnimation].Frames.Length + "]"; })); + _frameInput = new UiNumberInput(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, buttonWidthHalf, buttonHeight), + Resources.EditorFont, 1, 1, 1, 1, "numberX", screenId, + ui => { ((UiNumberInput)ui).MaxValue = _animator.Animations[_selectedAnimation].Frames.Length; }, + ui => { ChangeFrame((int)((UiNumberInput)ui).Value - 1); }); + Game1.EditorUi.AddElement(_frameInput); + + // add remove frame + Game1.EditorUi.AddElement(new UiButton(new Rectangle(buttonDist, posY += buttonHeight + buttonDist, buttonWidthHalf, buttonHeight), Resources.EditorFont, + "add", "addFrame", screenId, null, ui => { AddFrame(); })); + Game1.EditorUi.AddElement(new UiButton(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, buttonWidthHalf, buttonHeight), Resources.EditorFont, + "delete", "deleteFrame", screenId, null, ui => { DeleteFrame(); })); + + _cbFrameMirroredV = (UiCheckBox)Game1.EditorUi.AddElement(new UiCheckBox(new Rectangle(5, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight), + Resources.EditorFont, "mirrored V", "cbmirrored", screenId, false, null, + ui => { _animator.Animations[_selectedAnimation].Frames[_selectedFrame].MirroredV = ((UiCheckBox)ui).CurrentState; })); + _cbFrameMirroredH = (UiCheckBox)Game1.EditorUi.AddElement(new UiCheckBox(new Rectangle(5, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight), + Resources.EditorFont, "mirrored H", "cbmirrored", screenId, false, null, + ui => { _animator.Animations[_selectedAnimation].Frames[_selectedFrame].MirroredH = ((UiCheckBox)ui).CurrentState; })); + + Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist, posY += buttonHeight + buttonDist * 2, buttonWidth, labelHeight), + Resources.EditorFont, "fps", "flable", screenId, null)); + _fpsInput = new UiNumberInput(new Rectangle(buttonDist, posY += labelHeight + buttonDist, buttonWidthHalf, buttonHeight), + Resources.EditorFont, 1, 1, 1000, 1, "numberX", screenId, null, + ui => { _animator.SetFrameFps(_selectedAnimation, _selectedFrame, (int)((UiNumberInput)ui).Value); }); + Game1.EditorUi.AddElement(_fpsInput); + Game1.EditorUi.AddElement(new UiButton(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, buttonWidthHalf, buttonHeight), + Resources.EditorFont, "to all", "toall", screenId, null, + ui => { _animator.SetAnimationFps(_selectedAnimation, (int)_fpsInput.Value); })); + + // animation offset + Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist, posY += buttonHeight + buttonDist, + buttonWidth, labelHeight), Resources.EditorFont, "animation offset", "lableX", screenId, null)); + //Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist, posY += Resources.EditorFontHeight + buttonDist, + // buttonWidthHalf, labelHeight), Resources.EditorFont, "x", "lableX", screenId, null)); + //Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, + // buttonWidthHalf, labelHeight), Resources.EditorFont, "y", "lableX", screenId, null)); + _niAnOffsetX = new UiNumberInput(new Rectangle(buttonDist, posY += labelHeight + buttonDist, buttonWidthHalf, buttonHeight), + Resources.EditorFont, 0, -100, 100, 1, "animationWidth", screenId, null, + ui => { _animator.Animations[_selectedAnimation].Offset.X = (int)((UiNumberInput)ui).Value; }); + _niAnOffsetY = new UiNumberInput(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, buttonWidthHalf, buttonHeight), + Resources.EditorFont, 0, -100, 100, 1, "animationWidth", screenId, null, + ui => { _animator.Animations[_selectedAnimation].Offset.Y = (int)((UiNumberInput)ui).Value; }); + Game1.EditorUi.AddElement(_niAnOffsetX); + Game1.EditorUi.AddElement(_niAnOffsetY); + + // rectangle + // labels + Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist, posY += buttonHeight + buttonDist, + buttonWidth, labelHeight), Resources.EditorFont, "rectangle", "rectangle", screenId, null)); + //Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, + // buttonWidthHalf, labelHeight), Resources.EditorFont, "y", "lableX", screenId, null)); + // number picker + _numberInputX = new UiNumberInput(new Rectangle(buttonDist, posY += labelHeight + buttonDist, buttonWidthHalf, buttonHeight), + Resources.EditorFont, 0, 0, 1000, 1, "numberX", screenId, null, + ui => + { + _animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle.X = (int)((UiNumberInput)ui).Value; + UpdateCurrentFrame(); + }); + _numberInputY = new UiNumberInput(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, buttonWidthHalf, buttonHeight), + Resources.EditorFont, 0, 0, 1000, 1, "numberY", screenId, null, + ui => + { + _animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle.Y = (int)((UiNumberInput)ui).Value; + UpdateCurrentFrame(); + }); + Game1.EditorUi.AddElement(_numberInputX); + Game1.EditorUi.AddElement(_numberInputY); + //// labels + //Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist, posY += buttonHeight + buttonDist, + // buttonWidthHalf, labelHeight), Resources.EditorFont, "width", "lableX", screenId, null)); + //Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, + // buttonWidthHalf, labelHeight), Resources.EditorFont, "height", "lableX", screenId, null)); + // number picker + _numberInputWidth = new UiNumberInput(new Rectangle(buttonDist, posY += buttonHeight + buttonDist, buttonWidthHalf, buttonHeight), + Resources.EditorFont, 0, 0, 1000, 1, "numberWidth", screenId, null, ui => + { + _animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle.Width = (int)((UiNumberInput)ui).Value; + UpdateCurrentFrame(); + }); + _numberInputHeight = new UiNumberInput(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, buttonWidthHalf, buttonHeight), + Resources.EditorFont, 0, 0, 1000, 1, "numberHeight", screenId, null, ui => + { + _animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle.Height = (int)((UiNumberInput)ui).Value; + UpdateCurrentFrame(); + }); + Game1.EditorUi.AddElement(_numberInputWidth); + Game1.EditorUi.AddElement(_numberInputHeight); + + // offset + // labels + Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist, posY += buttonHeight + buttonDist, + buttonWidth, labelHeight), Resources.EditorFont, "frame offset", "lableX", screenId, null)); + //Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist, posY += buttonHeight / 2, + // buttonWidthHalf, labelHeight), Resources.EditorFont, "x", "lableX", screenId, null)); + //Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, + // buttonWidthHalf, labelHeight), Resources.EditorFont, "y", "lableX", screenId, null)); + // number picker + _niOffsetX = new UiNumberInput(new Rectangle(buttonDist, posY += labelHeight + buttonDist, buttonWidthHalf, buttonHeight), + Resources.EditorFont, 0, -100, 100, 1, "numberX", screenId, null, ui => + { + _animator.Animations[_selectedAnimation].Frames[_selectedFrame].Offset.X = (int)((UiNumberInput)ui).Value; + UpdateCurrentFrame(); + }); + _niOffsetY = new UiNumberInput(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, buttonWidthHalf, buttonHeight), + Resources.EditorFont, 0, -100, 100, 1, "numberY", screenId, null, ui => + { + _animator.Animations[_selectedAnimation].Frames[_selectedFrame].Offset.Y = (int)((UiNumberInput)ui).Value; + UpdateCurrentFrame(); + }); + Game1.EditorUi.AddElement(_niOffsetX); + Game1.EditorUi.AddElement(_niOffsetY); + + // create empty animation + CreateAnimator(); + } + + public override void Update(GameTime gameTime) + { + Game1.EditorUi.CurrentScreen = Values.EditorUiAnimation; + + if (_sprAnimator == null) + return; + + var mousePosition = InputHandler.MousePosition(); + + if (_isPlaying && !_animator.IsPlaying) + { + _animator.Play(_selectedAnimation); + } + + if (_isPlaying) + _animator.Update(); + else + { + _animator.SetFrame(_selectedFrame); + } + + // update tileset scale + if (InputHandler.MouseIntersect(new Rectangle(LeftBarWidth, Values.ToolBarHeight, + Game1.WindowWidth - LeftBarWidth - RightBarWidth, Game1.WindowHeight - Values.ToolBarHeight))) + { + _currentPosition = new Point( + (int)((InputHandler.MousePosition().X - _camera.Location.X) / _camera.Scale), + (int)((InputHandler.MousePosition().Y - _camera.Location.Y) / _camera.Scale)); + + if (InputHandler.MouseLeftStart()) + { + _selecting = true; + _selectionStart = _currentPosition; + } + if (InputHandler.MouseLeftDown() && _selecting) + { + _selectionEnd = _currentPosition; + + var selectionStart1 = new Point(Math.Min(_selectionStart.X, _selectionEnd.X), Math.Min(_selectionStart.Y, _selectionEnd.Y)); + var selectionEnd1 = new Point(Math.Max(_selectionStart.X, _selectionEnd.X) + 1, Math.Max(_selectionStart.Y, _selectionEnd.Y) + 1); + + if (_collisionRectangleMode) + _animator.Animations[_selectedAnimation].Frames[_selectedFrame].CollisionRectangle = + new Rectangle( + selectionStart1.X - _animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle.X, + selectionStart1.Y - _animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle.Y, + selectionEnd1.X - selectionStart1.X, selectionEnd1.Y - selectionStart1.Y); + else + { + _animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle = + new Rectangle(selectionStart1.X, selectionStart1.Y, selectionEnd1.X - selectionStart1.X, + selectionEnd1.Y - selectionStart1.Y); + UpdateCurrentFrame(); + } + + UpdateInputUi(); + } + if (InputHandler.MouseLeftReleased()) + { + _selecting = false; + } + + if (InputHandler.MouseRightPressed()) + { + if (_collisionRectangleMode) + _animator.Animations[_selectedAnimation].Frames[_selectedFrame].CollisionRectangle = Rectangle.Empty; + } + + if (InputHandler.MouseWheelUp()) + _camera.Zoom(1, mousePosition); + if (InputHandler.MouseWheelDown()) + _camera.Zoom(-1, mousePosition); + } + + if (!InputHandler.MouseMiddleStart() && InputHandler.MouseMiddleDown()) + _camera.Location += mousePosition - InputHandler.LastMousePosition(); + } + + public override void Draw(SpriteBatch spriteBatch) + { + if (_sprAnimator == null) + return; + + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, _camera.TransformMatrix); + + // draw the tiled background + spriteBatch.Draw(Resources.SprTiledBlock, new Rectangle(0, 0, _sprAnimator.Width, _sprAnimator.Height), + new Rectangle(0, 0, + (int)(_sprAnimator.Width / (float)TileSize * 2), + (int)(_sprAnimator.Height / (float)TileSize * 2)), Color.White); + + // draw the sprite + spriteBatch.Draw(_sprAnimator, new Rectangle(0, 0, _sprAnimator.Width, _sprAnimator.Height), Color.White); + + // draw current position of the mouse + spriteBatch.Draw(Resources.SprWhite, new Rectangle(_currentPosition.X, _currentPosition.Y, 1, 1), Color.Red * 0.5f); + + // show all source rectangles of all animations + if (_showAllSelections) + { + foreach (var animation in _animator.Animations) + for (var i = 0; i < animation.Frames.Length; i++) + spriteBatch.Draw(Resources.SprWhite, animation.Frames[i].SourceRectangle, Color.HotPink * 0.25f); + } + + // draw the selection + for (var i = 0; i < _animator.Animations[_selectedAnimation].Frames.Length; i++) + { + spriteBatch.Draw(Resources.SprWhite, _animator.Animations[_selectedAnimation].Frames[i].SourceRectangle, _selectedFrame == i ? Color.Red * 0.5f : Color.Red * 0.25f); + } + + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + _animator.Animations[_selectedAnimation].Frames[_selectedFrame].CollisionRectangle.X + + _animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle.X, + _animator.Animations[_selectedAnimation].Frames[_selectedFrame].CollisionRectangle.Y + + _animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle.Y, + _animator.Animations[_selectedAnimation].Frames[_selectedFrame].CollisionRectangle.Width, + _animator.Animations[_selectedAnimation].Frames[_selectedFrame].CollisionRectangle.Height), Color.Green * 0.5f); + + spriteBatch.End(); + } + + public override void DrawTop(SpriteBatch spriteBatch) + { + if (_sprAnimator == null) + return; + + float drawScale = 2; + + if (_animator.CurrentAnimation.AnimationWidth > 0 && _animator.CurrentAnimation.AnimationHeight > 0) + { + if (_animator.CurrentAnimation.AnimationWidth > _animator.CurrentAnimation.AnimationHeight) + drawScale = (int)(RightBarWidth / (float)(_animator.CurrentAnimation.AnimationWidth + 2)); + else + drawScale = (int)(RightBarWidth / (float)(_animator.CurrentAnimation.AnimationHeight + 2)); + } + + var drawOffsetX = Game1.WindowWidth - RightBarWidth / 2 - + (int)((_animator.CurrentAnimation.AnimationWidth + 2) * drawScale) / 2; + var drawOffsetY = Game1.WindowHeight - RightBarWidth / 2 - + (int)((_animator.CurrentAnimation.AnimationHeight + 2) * drawScale) / 2; + + var drawPositionX = drawOffsetX + (int)drawScale + + (int)((_animator.CurrentFrame.Offset.X - _animator.CurrentAnimation.AnimationLeft) * drawScale); + var drawPositionY = drawOffsetY + (int)drawScale + + (int)((_animator.CurrentFrame.Offset.Y - _animator.CurrentAnimation.AnimationTop) * drawScale); + + // draw the tiled background + spriteBatch.Draw(Resources.SprTiledBlock, new Rectangle( + drawOffsetX, drawOffsetY, + (int)((_animator.CurrentAnimation.AnimationWidth + 2) * drawScale), + (int)((_animator.CurrentAnimation.AnimationHeight + 2) * drawScale)), + new Rectangle(0, 0, + (int)((_animator.CurrentAnimation.AnimationWidth + 2) / (float)TileSize * 2), + (int)((_animator.CurrentAnimation.AnimationHeight + 2) / (float)TileSize * 2)), Color.White * 0.5f); + + DrawOverlayAnimation(spriteBatch, drawOffsetX, drawOffsetY, drawScale); + + // draw the current animation sprite + spriteBatch.Draw(_sprAnimator, new Rectangle( + drawPositionX, drawPositionY, (int)(drawScale * _animator.FrameWidth), (int)(drawScale * _animator.FrameHeight)), + _animator.CurrentFrame.SourceRectangle, Color.White, 0, Vector2.Zero, + (_animator.CurrentFrame.MirroredV ? SpriteEffects.FlipVertically : SpriteEffects.None) | + (_animator.CurrentFrame.MirroredH ? SpriteEffects.FlipHorizontally : SpriteEffects.None), 0); + + // draw the origin xy axis + var originPosition = new Vector2( + drawPositionX + (-_animator.CurrentAnimation.Offset.X - _animator.CurrentFrame.Offset.X) * drawScale, + drawPositionY + (-_animator.CurrentAnimation.Offset.Y - _animator.CurrentFrame.Offset.Y) * drawScale); + spriteBatch.Draw(Resources.SprWhite, new Vector2(originPosition.X - 1, originPosition.Y - 10), new Rectangle(0, 0, 2, 20), Color.Green); + spriteBatch.Draw(Resources.SprWhite, new Vector2(originPosition.X - 10, originPosition.Y - 1), new Rectangle(0, 0, 20, 2), Color.Red); + } + + private void DrawOverlayAnimation(SpriteBatch spriteBatch, int drawOffsetX, int drawOffsetY, float drawScale) + { + if (_overlayAnimator != null && _overlayAnimator.GetAnimationIndex(_animator.CurrentAnimation.Id) >= 0) + { + _overlayAnimator.Play(_animator.CurrentAnimation.Id); + // find the matching frame + var frameIndex = GetOverlayFrame(); + + _overlayAnimator.SetFrame(frameIndex); + + var drawPositionX = drawOffsetX + (int)drawScale + + (int)((_overlayAnimator.CurrentFrame.Offset.X - + _animator.CurrentAnimation.AnimationLeft + + _overlayAnimator.CurrentAnimation.Offset.X - + _animator.CurrentAnimation.Offset.X) * drawScale); + var drawPositionY = drawOffsetY + (int)drawScale + + (int)((_overlayAnimator.CurrentFrame.Offset.Y - + _animator.CurrentAnimation.AnimationTop + + _overlayAnimator.CurrentAnimation.Offset.Y - + _animator.CurrentAnimation.Offset.Y) * drawScale); + + spriteBatch.Draw(_overlayAnimator.SprTexture, new Rectangle( + drawPositionX, drawPositionY, (int)(drawScale * _overlayAnimator.FrameWidth), + (int)(drawScale * _overlayAnimator.FrameHeight)), + _overlayAnimator.CurrentFrame.SourceRectangle, Color.White, 0, Vector2.Zero, + (_overlayAnimator.CurrentFrame.MirroredV ? SpriteEffects.FlipVertically : SpriteEffects.None) | + (_overlayAnimator.CurrentFrame.MirroredH ? SpriteEffects.FlipHorizontally : SpriteEffects.None), 0); + } + } + + private int GetOverlayFrame() + { + if (_overlayAnimator.CurrentAnimation.Frames.Length <= 0) + return 0; + + // time to reach the selected frame + var frameTime = 0; + for (var i = 0; i < _animator.CurrentFrameIndex; i++) + frameTime += _animator.CurrentAnimation.Frames[i].FrameTime; + + var index = 0; + while (frameTime >= 0) + { + frameTime -= _overlayAnimator.CurrentAnimation.Frames[index].FrameTime; + if (frameTime < 0) + return index; + + if (_overlayAnimator.CurrentAnimation.Frames.Length > index + 1) + index++; + // loop animation + else + index = 0; + } + + return 0; + } + + private void UpdateCurrentFrame() + { + // update the size of the animation + _animator.RecalculateAnimationSize(_selectedAnimation); + } + + public void CreateAnimator() + { + // create empty animator with one animation and frame + _animator = new Animator(); + AddAnimation(); + + _animator.SpritePath = _sprPath; + } + + public void AddAnimation() + { + var newAnimation = new Animation("a" + _animator.Animations.Count) { NextAnimation = "" }; + + _animator.AddAnimation(newAnimation); + _animator.AddFrame(_animator.Animations.Count - 1, 0, new Frame() { FrameTimeFps = 5 }); + + ChangeAnimation(_animator.Animations.Count - 1); + } + + private void RemoveAnimation() + { + if (_animator.Animations.Count <= 1) + return; + + _animator.Animations.Remove(_animator.Animations[_selectedAnimation]); + ChangeAnimation(_selectedAnimation % _animator.Animations.Count); + } + + public void AddFrame() + { + var newFrame = new Frame() + { + SourceRectangle = _animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle, + Offset = _animator.Animations[_selectedAnimation].Frames[_selectedFrame].Offset, + FrameTimeFps = 5 + }; + + _animator.AddFrame(_selectedAnimation, _selectedFrame + 1, newFrame); + + _selectedFrame++; + UpdateInputUi(); + } + + public void DeleteFrame() + { + // cant delete the last frame + if (_animator.Animations[_selectedAnimation].Frames.Length <= 1) + return; + + _animator.Stop(); + + // create new frame array without the selected frame + var newFrames = new Frame[_animator.Animations[_selectedAnimation].Frames.Length - 1]; + var newIndex = 0; + for (var i = 0; i < _animator.Animations[_selectedAnimation].Frames.Length; i++) + if (i != _selectedFrame) + { + newFrames[newIndex] = _animator.Animations[_selectedAnimation].Frames[i]; + newIndex++; + } + _animator.Animations[_selectedAnimation].Frames = newFrames; + + if (_selectedFrame > 0) + _selectedFrame--; + + UpdateInputUi(); + } + + public void ChangeAnimation(int nextAnimation) + { + _selectedAnimation = nextAnimation; + _selectedFrame = 0; + _animator.Play(_selectedAnimation); + + UpdateInputUi(); + } + + public void ChangeFrame(int nextFrame) + { + _selectedFrame = nextFrame; + UpdateInputUi(); + } + + public void UpdateInputUi() + { + _animationInput.Value = _selectedAnimation + 1; + _frameInput.Value = _selectedFrame + 1; + + _loopCountInput.Value = _animator.Animations[_selectedAnimation].LoopCount; + _fpsInput.Value = _animator.Animations[_selectedAnimation].Frames[_selectedFrame].FrameTimeFps; + + _animationName.StrValue = _animator.Animations[_selectedAnimation].Id; + _nextAnimationName.StrValue = _animator.Animations[_selectedAnimation].NextAnimation; + + _niAnOffsetX.Value = _animator.CurrentAnimation.Offset.X; + _niAnOffsetY.Value = _animator.CurrentAnimation.Offset.Y; + + _numberInputX.Value = _animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle.X; + _numberInputY.Value = _animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle.Y; + _numberInputWidth.Value = _animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle.Width; + _numberInputHeight.Value = _animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle.Height; + + _niOffsetX.Value = _animator.Animations[_selectedAnimation].Frames[_selectedFrame].Offset.X; + _niOffsetY.Value = _animator.Animations[_selectedAnimation].Frames[_selectedFrame].Offset.Y; + + _cbFrameMirroredV.CurrentState = _animator.Animations[_selectedAnimation].Frames[_selectedFrame].MirroredV; + _cbFrameMirroredH.CurrentState = _animator.Animations[_selectedAnimation].Frames[_selectedFrame].MirroredH; + } + + public void SaveAnimationDialog() + { +#if WINDOWS + var saveFileDialog = new SaveFileDialog() + { + RestoreDirectory = true, + Filter = "animator files (*.ani)|*.ani", + }; + + if (_lastFileName != null) + { + saveFileDialog.FileName = Path.GetFileName(_lastFileName); + saveFileDialog.InitialDirectory = Path.GetFullPath(Path.GetDirectoryName(_lastFileName)); + } + + if (saveFileDialog.ShowDialog() == DialogResult.OK) + AnimatorSaveLoad.SaveAnimator(saveFileDialog.FileName, _animator); +#endif + } + + public void SaveAnimation() + { + AnimatorSaveLoad.SaveAnimator(_lastFileName, _animator); + } + + public void LoadAnimation() + { +#if WINDOWS + var openFileDialog = new OpenFileDialog() + { + Filter = "animator files (*.ani)|*.ani" + }; + + if (openFileDialog.ShowDialog() != DialogResult.OK) + return; + + EditorLoadAnimation(openFileDialog.FileName); +#endif + } + + public void EditorLoadAnimation(string filePath) + { + _selectedAnimation = 0; + _selectedFrame = 0; + _lastFileName = filePath; + _animator = AnimatorSaveLoad.LoadAnimatorFile(filePath); + _sprAnimator = _animator.SprTexture; + + UpdateInputUi(); + } + + private void LoadOverlayAnimation() + { +#if WINDOWS + var openFileDialog = new OpenFileDialog() + { + Filter = "animator files (*.ani)|*.ani" + }; + + if (openFileDialog.ShowDialog() != DialogResult.OK) return; + + _overlayAnimator = AnimatorSaveLoad.LoadAnimatorFile(openFileDialog.FileName); +#endif + } + + public void UpdateAnimations() + { +#if WINDOWS + var openFileDialog = new OpenFileDialog() + { + Filter = "animator files (*.ani)|*.ani", + Multiselect = true + }; + + if (openFileDialog.ShowDialog() != DialogResult.OK) return; + + foreach (var fileName in openFileDialog.FileNames) + { + _animator = AnimatorSaveLoad.LoadAnimatorFile(fileName); + AnimatorSaveLoad.SaveAnimator(fileName, _animator); + } +#endif + } + + public void LoadImage() + { +#if WINDOWS + var openFileDialog = new OpenFileDialog() + { + Filter = "png files (*.png)|*.png" + }; + + if (openFileDialog.ShowDialog() != DialogResult.OK) return; + + try + { + using (var stream = File.OpenRead(openFileDialog.FileName)) + { + _sprAnimator = Texture2D.FromStream(Game1.Graphics.GraphicsDevice, stream); + _sprPath = Path.GetFileName(openFileDialog.FileName); + _animator.SpritePath = _sprPath; + } + } + catch { } +#endif + } + + } +} diff --git a/Editor/DigMapEditor.cs b/Editor/DigMapEditor.cs new file mode 100644 index 0000000..8a16752 --- /dev/null +++ b/Editor/DigMapEditor.cs @@ -0,0 +1,181 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using ProjectZ.Base; +using ProjectZ.Base.UI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; +using System.Collections.Generic; + +namespace ProjectZ.Editor +{ + class DigMapEditor + { + private readonly EditorCamera _camera; + + private Dictionary _colorMap = new Dictionary(); + private Color[,] _colorData; + private Stack _colorStack = new Stack(); + + private Map CurrentMap => Game1.GameManager.MapManager.CurrentMap; + private string LastMap; + + private string _selection = ""; + + private int _tileWidth = 16; + private int _tileHeight = 16; + + private int _leftToolbarWidth = 200; + + public DigMapEditor(EditorCamera camera) + { + _camera = camera; + + _colorStack.Clear(); + _colorStack.Push(Color.Black); + _colorStack.Push(Color.Purple); + _colorStack.Push(Color.Orange); + _colorStack.Push(Color.Red); + //_colorStack.Push(Color.Blue); + //_colorStack.Push(Color.Green); + + _colorMap.Add("", Color.White * 0.5f); + _colorMap.Add("1", Color.Green); + _colorMap.Add("2", Color.Blue); + } + + public void SetUpUi(int posY) + { + var buttonWidth = 190; + var buttonHeight = 35; + var distanceY = buttonHeight + 5; + + Game1.EditorUi.AddElement(new UiTextInput(new Rectangle(5, posY, buttonWidth, 50), + Resources.EditorFontMonoSpace, 50, "Mode", Values.EditorUiDigTileEditor, + uiElement => ((UiTextInput)uiElement).StrValue = _selection ?? "", + uiElement => _selection = ((UiTextInput)uiElement).StrValue)); + + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += 55, buttonWidth, buttonHeight), + Resources.EditorFont, "Fill Map", "button", Values.EditorUiDigTileEditor, null, FillMap)); + } + + public void Update(GameTime gameTime) + { + Game1.EditorUi.CurrentScreen = Values.EditorUiDigTileEditor; + + if (LastMap != CurrentMap.MapFileName) + { + LastMap = CurrentMap.MapFileName; + UpdateColor(); + } + + var cursorPosition = GetTiledCursor(); + if (cursorPosition.X >= 0) + { + if (InputHandler.MouseRightDown() || InputHandler.KeyPressed(Keys.Space)) + _selection = CurrentMap.DigMap[cursorPosition.X, cursorPosition.Y]; + if (InputHandler.MouseLeftDown()) + { + CurrentMap.DigMap[cursorPosition.X, cursorPosition.Y] = _selection; + UpdateColor(cursorPosition.X, cursorPosition.Y); + } + } + } + + public void Draw(SpriteBatch spriteBatch) + { + for (var y = 0; y < CurrentMap.DigMap.GetLength(1); y++) + { + for (var x = 0; x < CurrentMap.DigMap.GetLength(0); x++) + { + var posX = _tileWidth * x; + var posY = _tileHeight * y; + var width = _tileWidth; + var height = _tileHeight; + + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + posX + (_tileWidth - width) / 2, + posY + (_tileHeight - height) / 2, width, height), _colorData[x, y] * 0.75f); + } + } + + var cursorPosition = GetTiledCursor(); + if (cursorPosition.X >= 0 && !string.IsNullOrEmpty(CurrentMap.DigMap[cursorPosition.X, cursorPosition.Y])) + { + var spriteSize = Resources.EditorFont.MeasureString(CurrentMap.DigMap[cursorPosition.X, cursorPosition.Y]); + var scale = spriteSize.X > spriteSize.Y ? (_tileWidth - 2) / spriteSize.X : 1; + + spriteBatch.DrawString(Resources.EditorFont, CurrentMap.DigMap[cursorPosition.X, cursorPosition.Y], + new Vector2( + _tileWidth * cursorPosition.X + _tileWidth / 2 - (spriteSize.X / 2 * scale), + _tileHeight * cursorPosition.Y + _tileHeight / 2 - (spriteSize.Y / 2 * scale)), + Color.White, 0, Vector2.One, new Vector2(scale), SpriteEffects.None, 0); + } + } + + private void UpdateColor() + { + _colorData = new Color[CurrentMap.DigMap.GetLength(0), CurrentMap.DigMap.GetLength(1)]; + + for (var y = 0; y < CurrentMap.DigMap.GetLength(1); y++) + for (var x = 0; x < CurrentMap.DigMap.GetLength(0); x++) + UpdateColor(x, y); + } + + private void UpdateColor(int x, int y) + { + if (_colorMap.TryGetValue(CurrentMap.DigMap[x, y], out var color)) + _colorData[x, y] = color; + else + { + Color newColor; + + if (_colorStack.Count > 0) + { + newColor = _colorStack.Pop(); + } + else + { + newColor = new Color( + Game1.RandomNumber.Next(0, 256), + Game1.RandomNumber.Next(0, 256), + Game1.RandomNumber.Next(0, 256)); + } + + _colorData[x, y] = newColor; + _colorMap.Add(CurrentMap.DigMap[x, y], newColor); + } + } + + private void FillMap(UiElement uiElement) + { + for (var y = 0; y < CurrentMap.DigMap.GetLength(1); y++) + for (var x = 0; x < CurrentMap.DigMap.GetLength(0); x++) + CurrentMap.DigMap[x, y] = _selection; + } + + public Point GetTiledCursor() + { + var _mousePosition = InputHandler.MousePosition(); + + var position = new Point( + (int)((_mousePosition.X - _camera.Location.X) / (_tileWidth * _camera.Scale)), + (int)((_mousePosition.Y - _camera.Location.Y) / (_tileHeight * _camera.Scale))); + + // fix + if (_mousePosition.X - _camera.Location.X < 0) + position.X--; + if (_mousePosition.Y - _camera.Location.Y < 0) + position.Y--; + + if (_mousePosition.X > _leftToolbarWidth && + 0 <= position.X && position.X < CurrentMap.DigMap.GetLength(0) && + 0 <= position.Y && position.Y < CurrentMap.DigMap.GetLength(1)) + { + return position; + } + + return new Point(-1, -1); + } + } +} diff --git a/Editor/EditorCamera.cs b/Editor/EditorCamera.cs new file mode 100644 index 0000000..0cf3703 --- /dev/null +++ b/Editor/EditorCamera.cs @@ -0,0 +1,34 @@ +using System; +using Microsoft.Xna.Framework; + +namespace ProjectZ.Editor +{ + public class EditorCamera + { + public Matrix TransformMatrix => Matrix.CreateScale(Scale) * + Matrix.CreateTranslation(new Vector3(Location.X, Location.Y, 0)); + public Point Location = new Point(0, 0); + public float Scale = 1; + + public float MinScale = 0.25f; + public float MaxScale = 15.0f; + + public void Zoom(float dir, Point mousePosition) + { + var stepSize = Scale / 4 * dir; + + var preScale = Scale; + + if (Scale + stepSize < MinScale || MaxScale < Scale + stepSize) + Scale = stepSize < 0 ? MinScale : MaxScale; + else + Scale += stepSize; + + Scale = (int)Math.Round(Scale * 100) / 100f; + + var scale = Scale / preScale; + Location.X = mousePosition.X - (int)((mousePosition.X - Location.X) * scale); + Location.Y = mousePosition.Y - (int)((mousePosition.Y - Location.Y) * scale); + } + } +} diff --git a/Editor/MapEditorScreen.cs b/Editor/MapEditorScreen.cs new file mode 100644 index 0000000..0f4b0d1 --- /dev/null +++ b/Editor/MapEditorScreen.cs @@ -0,0 +1,368 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using ProjectZ.Base; +using ProjectZ.Base.UI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Screens; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.Editor +{ + internal class MapEditorScreen : Screen + { + public enum EditorModes + { + TileMode, + ObjectMode, + DigMode, + MusicMode + } + + public Vector2 MousePixelPosition => new Vector2( + (InputHandler.MousePosition().X - _camera.Location.X) / _camera.Scale, + (InputHandler.MousePosition().Y - _camera.Location.Y) / _camera.Scale); + + public Point MouseMapPosition => new Point( + (InputHandler.MousePosition().X - _camera.Location.X) / (int)(Values.TileSize * _camera.Scale), + (InputHandler.MousePosition().Y - _camera.Location.Y) / (int)(Values.TileSize * _camera.Scale)); + + public bool ShowGrid; + + private EditorModes _currentMode = EditorModes.ObjectMode; + + private readonly EditorCamera _camera = new EditorCamera(); + + private readonly TileEditorScreen _tileEditorScreen; + private readonly ObjectEditorScreen _objectEditorScreen; + private readonly DigMapEditor _digMapEditor; + private readonly MusicTileEditor _musicTileEditor; + + private UiNumberInput _niOffsetX; + private UiNumberInput _niOffsetY; + + private Point _mousePosition; + + private int _mapOffsetX = 0; + private int _mapOffsetY = 0; + + private string _currentMapName; + private int _toolBarWidth = 200; + private bool _showTiles = true; + private bool _showObjects = true; + private bool _shiftDown; + + public MapEditorScreen(string screenId) : base(screenId) + { + _tileEditorScreen = new TileEditorScreen(_camera); + _objectEditorScreen = new ObjectEditorScreen(_camera); + _digMapEditor = new DigMapEditor(_camera); + _musicTileEditor = new MusicTileEditor(_camera); + } + + public override void Load(ContentManager content) + { + _tileEditorScreen.Load(content); + _objectEditorScreen.Load(); + + SetupUi(); + } + + public void SetupUi() + { + var buttonWidth = _toolBarWidth - 10; + var buttonWidthHalf = (buttonWidth - 4) / 2; + var buttonHeight = 30; + var lableHeight = 20; + var buttonQWidth = _toolBarWidth - 15 - buttonHeight; + var posY = Values.ToolBarHeight + 5; + var dist = 4; + var bigDist = 16; + + var strScreenName = $"{Values.EditorUiTileEditor}:{Values.EditorUiObjectEditor}:{Values.EditorUiDigTileEditor}:{Values.EditorUiMusicTileEditor}"; + + // left background + Game1.EditorUi.AddElement(new UiRectangle(Rectangle.Empty, "left", strScreenName, + Values.ColorBackgroundLight, Color.White, + ui => + { + ui.Rectangle = new Rectangle(0, Values.ToolBarHeight, _toolBarWidth, + Game1.WindowHeight - Values.ToolBarHeight); + })); + + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY, buttonWidth, buttonHeight), + Resources.EditorFont, + "Load", "", strScreenName, null, ui => SaveLoadMap.LoadMap(Game1.GameManager.MapManager.CurrentMap))); + + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + dist, buttonWidth, buttonHeight), + Resources.EditorFont, + "Save as...", "", strScreenName, null, ui => SaveLoadMap.SaveMapDialog(Game1.GameManager.MapManager.CurrentMap))); + + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + dist, buttonWidth, buttonHeight), + Resources.EditorFont, + "Save...", "", strScreenName, null, ui => SaveLoadMap.SaveMap(Game1.GameManager.MapManager.CurrentMap))); + + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + dist, buttonWidth, buttonHeight), + Resources.EditorFont, + "Update Maps", "", strScreenName, null, ui => SaveLoadMap.UpdateMaps())); + + // map offset + Game1.EditorUi.AddElement(_niOffsetX = new UiNumberInput( + new Rectangle(5, posY += buttonHeight + dist, buttonWidthHalf, buttonHeight), + Resources.EditorFont, _mapOffsetX, -16, 16, 1, "", strScreenName, null, NumberInputChangeMapOffsetX)); + Game1.EditorUi.AddElement(_niOffsetY = new UiNumberInput( + new Rectangle(5 + buttonWidthHalf + dist, posY, buttonWidthHalf, buttonHeight), + Resources.EditorFont, _mapOffsetX, -16, 16, 1, "", strScreenName, null, NumberInputChangeMapOffsetY)); + + Game1.EditorUi.AddElement(new UiNumberInput( + new Rectangle(5, posY += buttonHeight + dist, buttonWidthHalf, buttonHeight), + Resources.EditorFont, _mapOffsetX, -16, 16, 1, "", strScreenName, null, NumberInputChangeOffsetX)); + Game1.EditorUi.AddElement(new UiNumberInput( + new Rectangle(5 + buttonWidthHalf + dist, posY, buttonWidthHalf, buttonHeight), + Resources.EditorFont, _mapOffsetX, -16, 16, 1, "", strScreenName, null, NumberInputChangeOffsetY)); + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + dist, buttonWidth, buttonHeight), + Resources.EditorFont, "Offset Map", "", strScreenName, null, ButtonPressedOffsetMap)); + + // show grid button + Game1.EditorUi.AddElement(new UiCheckBox( + new Rectangle(5, posY += buttonHeight + bigDist, buttonWidth, buttonHeight), Resources.EditorFont, + "show grid", "cb", strScreenName, false, null, + ui => { ShowGrid = ((UiCheckBox)ui).CurrentState; })); + + // tile/object mode switch + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + bigDist, buttonQWidth, buttonHeight), + Resources.EditorFont, "Tiles", "", strScreenName, + element => ((UiButton)element).Marked = _currentMode == EditorModes.TileMode, + element => _currentMode = EditorModes.TileMode)); + + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5 + buttonQWidth + dist, posY, buttonHeight, buttonHeight), + Resources.EditorFont, "", "bt1", strScreenName, null, ButtonUpdateTilesVisibility) + { ButtonIcon = Resources.EditorEyeOpen }); + + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + dist, buttonQWidth, buttonHeight), + Resources.EditorFont, "Objects", "", strScreenName, + element => ((UiButton)element).Marked = _currentMode == EditorModes.ObjectMode, + element => _currentMode = EditorModes.ObjectMode)); + + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5 + buttonQWidth + dist, posY, buttonHeight, buttonHeight), + Resources.EditorFont, "", "bt1", strScreenName, null, ButtonUpdateObjectsVisibility) + { ButtonIcon = Resources.EditorEyeOpen }); + + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + dist, buttonWidth, buttonHeight), + Resources.EditorFont, "Dig Map", "", strScreenName, + element => ((UiButton)element).Marked = _currentMode == EditorModes.DigMode, + element => _currentMode = EditorModes.DigMode)); + + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + dist, buttonWidth, buttonHeight), + Resources.EditorFont, "Music", "", strScreenName, + element => ((UiButton)element).Marked = _currentMode == EditorModes.MusicMode, + element => _currentMode = EditorModes.MusicMode)); + + posY += buttonHeight + bigDist; + + // load the ui of the tile editor + _tileEditorScreen.SetupUi(posY); + + // load the ui of the object editor + _objectEditorScreen.SetupUi(posY); + + _digMapEditor.SetUpUi(posY); + + // set up music ui + _musicTileEditor.SetUpUi(posY); + } + + public override void Update(GameTime gameTime) + { + _shiftDown = InputHandler.KeyDown(Keys.LeftControl) & InputHandler.MousePosition().X < Game1.WindowWidth - _toolBarWidth; + + // update the selection screen or the editor screen + if (_shiftDown) + UpdateSelectionScreen(gameTime); + else + UpdateEditorScreen(gameTime); + } + + public void UpdateSelectionScreen(GameTime gameTime) + { + if (_currentMode == EditorModes.TileMode) + _tileEditorScreen.UpdateTileSelection(gameTime); + else if (_currentMode == EditorModes.ObjectMode) + _objectEditorScreen.UpdateObjectSelection(gameTime); + } + + public void UpdateEditorScreen(GameTime gameTime) + { + _mousePosition = InputHandler.MousePosition(); + + // move the tileset + if (!InputHandler.MouseMiddleStart() && InputHandler.MouseMiddleDown()) + _camera.Location += _mousePosition - InputHandler.LastMousePosition(); + + // center camera after map change + if (Game1.GameManager.MapManager.CurrentMap.MapName != _currentMapName) + { + _currentMapName = Game1.GameManager.MapManager.CurrentMap.MapName; + CenterCamera(); + } + + _musicTileEditor.Map = Game1.GameManager.MapManager.CurrentMap; + _tileEditorScreen.Map = Game1.GameManager.MapManager.CurrentMap; + + _niOffsetX.Value = Game1.GameManager.MapManager.CurrentMap.MapOffsetX; + _niOffsetY.Value = Game1.GameManager.MapManager.CurrentMap.MapOffsetY; + + // update the tile or the object editor screen + if (_currentMode == EditorModes.TileMode) + _tileEditorScreen.Update(gameTime); + else if (_currentMode == EditorModes.ObjectMode) + _objectEditorScreen.Update(gameTime); + else if (_currentMode == EditorModes.DigMode) + _digMapEditor.Update(gameTime); + else if (_currentMode == EditorModes.MusicMode) + _musicTileEditor.Update(gameTime); + + // update tileset scale + if (InputHandler.MouseWheelUp()) + _camera.Zoom(1, _mousePosition); + if (InputHandler.MouseWheelDown()) + _camera.Zoom(-1, _mousePosition); + } + + public override void Draw(SpriteBatch spriteBatch) + { + // show the tile or the object selection screen + if (_shiftDown) + DrawSelectionScreen(spriteBatch); + else + // draw the editor screen + DrawEditorScreen(spriteBatch); + } + + private void DrawSelectionScreen(SpriteBatch spriteBatch) + { + if (_currentMode == EditorModes.TileMode) + _tileEditorScreen.DrawTileSelection(spriteBatch); + else if (_currentMode == EditorModes.ObjectMode) + _objectEditorScreen.DrawObjectSelection(spriteBatch); + } + + private void DrawEditorScreen(SpriteBatch spriteBatch) + { + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, _camera.TransformMatrix); + + // draw the background + spriteBatch.Draw(Resources.SprTiledBlock, new Rectangle(0, 0, + Game1.GameManager.MapManager.CurrentMap.MapWidth * Values.TileSize, + Game1.GameManager.MapManager.CurrentMap.MapHeight * Values.TileSize), + new Rectangle(0, 0, + Game1.GameManager.MapManager.CurrentMap.MapWidth * 2, + Game1.GameManager.MapManager.CurrentMap.MapHeight * 2), + Color.White); + + // draw the tile layers + if (_showTiles) + _tileEditorScreen.Draw(spriteBatch, _currentMode == EditorModes.TileMode); + + // draw the object layer + if (_showObjects) + _objectEditorScreen.Draw(spriteBatch); + + if (_currentMode == EditorModes.DigMode) + _digMapEditor.Draw(spriteBatch); + else if (_currentMode == EditorModes.MusicMode) + _musicTileEditor.Draw(spriteBatch); + + // draw the grid + var currentMap = Game1.GameManager.MapManager.CurrentMap; + if (ShowGrid) + { + var countX = MathF.Ceiling(currentMap.TileMap.ArrayTileMap.GetLength(0) / 10.0f); + var countY = MathF.Ceiling(currentMap.TileMap.ArrayTileMap.GetLength(1) / 8.0f); + + for (var y = 0; y < countY; y++) + for (var x = 0; x < countX; x++) + if ((y + x) % 2 == 0) + { + var sizeX = Math.Min(10, currentMap.TileMap.ArrayTileMap.GetLength(0) - x * 10); + var sizeY = Math.Min(8, currentMap.TileMap.ArrayTileMap.GetLength(1) - y * 8); + + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + (x * 10 + currentMap.MapOffsetX) * Values.TileSize, + (y * 8 + currentMap.MapOffsetY) * Values.TileSize, + Values.TileSize * sizeX, Values.TileSize * sizeY), Color.White * 0.5f); + } + } + + spriteBatch.End(); + } + + public override void DrawTop(SpriteBatch spriteBatch) + { + if (_shiftDown) + return; + + if (_currentMode == EditorModes.TileMode) + _tileEditorScreen.DrawTop(spriteBatch); + else if (_currentMode == EditorModes.ObjectMode) + _objectEditorScreen.DrawTop(spriteBatch); + } + + public void CenterCamera() + { + _camera.Location.X = (int)(Game1.WindowWidth - Values.TileSize * Game1.GameManager.MapManager.CurrentMap.MapWidth * _camera.Scale) / 2; + _camera.Location.Y = (int)(Game1.WindowHeight - Values.TileSize * Game1.GameManager.MapManager.CurrentMap.MapHeight * _camera.Scale) / 2; + } + + public bool InsideField() + { + return InputHandler.MouseIntersect(new Rectangle( + _toolBarWidth, Values.ToolBarHeight, + Game1.WindowWidth - _toolBarWidth * 2, + Game1.WindowHeight - Values.ToolBarHeight)); + } + + private void ButtonUpdateTilesVisibility(UiElement ui) + { + _showTiles = !_showTiles; + ((UiButton)ui).ButtonIcon = _showTiles ? Resources.EditorEyeOpen : Resources.EditorEyeClosed; + } + + private void ButtonUpdateObjectsVisibility(UiElement ui) + { + _showObjects = !_showObjects; + ((UiButton)ui).ButtonIcon = _showObjects ? Resources.EditorEyeOpen : Resources.EditorEyeClosed; + } + + private void NumberInputChangeMapOffsetX(UiElement uiElement) + { + Game1.GameManager.MapManager.CurrentMap.MapOffsetX = (int)((UiNumberInput)uiElement).Value; + } + + private void NumberInputChangeMapOffsetY(UiElement uiElement) + { + Game1.GameManager.MapManager.CurrentMap.MapOffsetY = (int)((UiNumberInput)uiElement).Value; + } + + private void NumberInputChangeOffsetX(UiElement uiElement) + { + _mapOffsetX = (int)((UiNumberInput)uiElement).Value; + } + + private void NumberInputChangeOffsetY(UiElement uiElement) + { + _mapOffsetY = (int)((UiNumberInput)uiElement).Value; + } + + private void ButtonPressedOffsetMap(UiElement uiElement) + { + // offset the tilemap + _tileEditorScreen.OffsetTileMap(_mapOffsetX, _mapOffsetY); + // offset the objects + ObjectEditorScreen.OffsetObjects( + Game1.GameManager.MapManager.CurrentMap, _mapOffsetX * Values.TileSize, _mapOffsetY * Values.TileSize); + } + } +} \ No newline at end of file diff --git a/Editor/MusicTileEditor.cs b/Editor/MusicTileEditor.cs new file mode 100644 index 0000000..f1726a8 --- /dev/null +++ b/Editor/MusicTileEditor.cs @@ -0,0 +1,209 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using ProjectZ.Base; +using ProjectZ.Base.UI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using System.Collections.Generic; + +namespace ProjectZ.Editor +{ + class MusicTileEditor + { + public Map Map; + + private readonly EditorCamera _camera; + + private Dictionary _colorMap = new Dictionary(); + private Color[,] _colorData; + private Stack _colorStack = new Stack(); + + private string[,] _dataArray; + private string _selection = ""; + + private int _tileWidth = 16; + private int _tileHeight = 16; + //private int _tileWidth = 160; + //private int _tileHeight = 128; + + private bool _roomMode; + + private int _leftToolbarWidth = 200; + + public MusicTileEditor(EditorCamera camera) + { + _camera = camera; + + _dataArray = new string[16 * 10, 16 * 8]; + for (var y = 0; y < _dataArray.GetLength(1); y++) + for (var x = 0; x < _dataArray.GetLength(0); x++) + _dataArray[x, y] = ""; + + UpdateColor(); + } + + private void ResetColor() + { + _colorStack.Clear(); + _colorStack.Push(Color.Black); + _colorStack.Push(Color.Purple); + _colorStack.Push(Color.Orange); + _colorStack.Push(Color.Blue); + _colorStack.Push(Color.Green); + _colorStack.Push(Color.Red); + } + + public void SetUpUi(int posY) + { + var buttonWidth = 190; + var buttonHeight = 35; + var distanceY = buttonHeight + 5; + + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY, buttonWidth, buttonHeight), + Resources.EditorFont, "Load", "button", Values.EditorUiMusicTileEditor, null, uiElement => LoadFile())); + + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += distanceY, buttonWidth, buttonHeight), + Resources.EditorFont, "Save", "button", Values.EditorUiMusicTileEditor, null, uiElement => DataMapSerializer.SaveDialog(_dataArray))); + + Game1.EditorUi.AddElement(new UiCheckBox(new Rectangle(5, posY += distanceY, buttonWidth, buttonHeight), + Resources.EditorFont, "Room", "button", Values.EditorUiMusicTileEditor, _roomMode, null, element => _roomMode = ((UiCheckBox)element).CurrentState)); + + Game1.EditorUi.AddElement(new UiTextInput(new Rectangle(5, posY += distanceY, buttonWidth, 50), + Resources.EditorFontMonoSpace, 50, "Mode", Values.EditorUiMusicTileEditor, + uiElement => ((UiTextInput)uiElement).StrValue = _selection, + uiElement => _selection = ((UiTextInput)uiElement).StrValue)); + } + + private void LoadFile() + { + DataMapSerializer.LoadDialog(ref _dataArray); + + UpdateColor(); + + //_tileWidth = (Game1.GameManager.MapManager.CurrentMap.MapWidth * Values.TileSize) / _dataArray.GetLength(0); + //_tileHeight = (Game1.GameManager.MapManager.CurrentMap.MapHeight * Values.TileSize) / _dataArray.GetLength(1); + } + + private void UpdateColor() + { + ResetColor(); + + _colorData = new Color[_dataArray.GetLength(0), _dataArray.GetLength(1)]; + + for (var y = 0; y < _dataArray.GetLength(1); y++) + for (var x = 0; x < _dataArray.GetLength(0); x++) + UpdateColor(x, y); + } + + private void UpdateColor(int x, int y) + { + if (_colorMap.TryGetValue(_dataArray[x, y], out var color)) + _colorData[x, y] = color; + else + { + Color newColor; + + if (_colorStack.Count > 0) + { + newColor = _colorStack.Pop(); + } + else + { + newColor = new Color( + Game1.RandomNumber.Next(0, 256), + Game1.RandomNumber.Next(0, 256), + Game1.RandomNumber.Next(0, 256)); + } + + _colorData[x, y] = newColor; + _colorMap.Add(_dataArray[x, y], newColor); + } + } + + public void Update(GameTime gameTime) + { + Game1.EditorUi.CurrentScreen = Values.EditorUiMusicTileEditor; + + var cursorPosition = GetTiledCursor(); + if (cursorPosition.X >= 0) + { + if (InputHandler.MouseRightDown() || InputHandler.KeyPressed(Keys.Space)) + _selection = _dataArray[cursorPosition.X, cursorPosition.Y]; + if (InputHandler.MouseLeftDown()) + { + if (_roomMode) + { + var startX = (cursorPosition.X / 10) * 10; + var startY = (cursorPosition.Y / 8) * 8; + + for (var y = startY; y < startY + 8; y++) + if (y < _dataArray.GetLength(1)) + for (var x = startX; x < startX + 10; x++) + { + if (x < _dataArray.GetLength(0)) + { + _dataArray[x, y] = _selection; + UpdateColor(x, y); + } + } + } + else + { + _dataArray[cursorPosition.X, cursorPosition.Y] = _selection; + UpdateColor(cursorPosition.X, cursorPosition.Y); + } + } + } + } + + public void Draw(SpriteBatch spriteBatch) + { + for (var y = 0; y < _dataArray.GetLength(1); y++) + { + for (var x = 0; x < _dataArray.GetLength(0); x++) + { + var posX = _tileWidth * x + Map.MapOffsetX * Values.TileSize; + var posY = _tileHeight * y + Map.MapOffsetY * Values.TileSize; + var width = _tileWidth; + var height = _tileHeight; + + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + posX + (_tileWidth - width) / 2, + posY + (_tileHeight - height) / 2, width, height), _colorData[x, y] * 0.75f); + } + } + + var cursorPosition = GetTiledCursor(); + if (cursorPosition.X >= 0) + spriteBatch.DrawString(Resources.EditorFontSmallMonoSpace, _dataArray[cursorPosition.X, cursorPosition.Y], + new Vector2(_tileWidth * cursorPosition.X + Map.MapOffsetX * Values.TileSize + _tileWidth / 2 - 1, + _tileHeight * cursorPosition.Y + Map.MapOffsetY * Values.TileSize + _tileHeight / 2 - 6), Color.White); + } + + public Point GetTiledCursor() + { + var _mousePosition = InputHandler.MousePosition(); + + var position = new Point( + (int)((_mousePosition.X - _camera.Location.X - Map.MapOffsetX * Values.TileSize * _camera.Scale) / (_tileWidth * _camera.Scale)), + (int)((_mousePosition.Y - _camera.Location.Y - Map.MapOffsetY * Values.TileSize * _camera.Scale) / (_tileHeight * _camera.Scale))); + + // fix + if (_mousePosition.X - _camera.Location.X < 0) + position.X--; + if (_mousePosition.Y - _camera.Location.Y < 0) + position.Y--; + + if (_mousePosition.X > _leftToolbarWidth && + 0 <= position.X && position.X < _dataArray.GetLength(0) && + 0 <= position.Y && position.Y < _dataArray.GetLength(1)) + { + return position; + } + + return new Point(-1, -1); + } + } +} diff --git a/Editor/ObjectEditorScreen.cs b/Editor/ObjectEditorScreen.cs new file mode 100644 index 0000000..ab0db43 --- /dev/null +++ b/Editor/ObjectEditorScreen.cs @@ -0,0 +1,735 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.Base.UI; +using ProjectZ.InGame.GameObjects; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using Keys = Microsoft.Xna.Framework.Input.Keys; + +namespace ProjectZ.Editor +{ + class ObjectEditorScreen + { + enum Mode + { + Draw, + Edit + } + + enum EditMode + { + Idle, + Moving + } + + enum DrawMode + { + Draw, + Erase, + Nothing + } + + public static Dictionary EditorObjectTemplates = new Dictionary(); + + private Mode _currentMode = Mode.Edit; + private EditMode _currentEditMode = EditMode.Idle; + private DrawMode _currentDrawMode = DrawMode.Nothing; + + private readonly ObjectSelectionScreen _objectSelectionSelectionScreen = new ObjectSelectionScreen(); + + private const int MaxParameter = 15; + private readonly UiLabel[] _uiParameterHeader = new UiLabel[MaxParameter]; + private readonly UiTextInput[] _uiParameterTextInput = new UiTextInput[MaxParameter]; + private readonly string[] _strParameter = new string[MaxParameter]; + + private UiNumberInput _bezier0; + private UiNumberInput _bezier1; + private UiNumberInput _bezier2; + private UiNumberInput _bezier3; + private CubicBezier _cublicBezier; + + private GameObjectItem _selectedGameObjectItem; + + private EditorCamera _camera; + + public Point ObjectCursor; + public Point SelectionStart; + public Point SelectionEnd; + + private Point? LastObjectCursor; + private Point mousePosition, mouseMapPosition; + + private Point _moveOffset; + private Point _startMovePosition; + + public Point MouseMapPosition => new Point( + (InputHandler.MousePosition().X - _camera.Location.X) / (int)(Values.TileSize * _camera.Scale), + (InputHandler.MousePosition().Y - _camera.Location.Y) / (int)(Values.TileSize * _camera.Scale)); + + private string _currentMapPath; + + private int _currentLayer; + private int _replaceSelection; + + private int _leftToolbarWidth = 200; + private int _rightToolbarWidth = 250; + + private int gridSize = 1; + + public bool DrawObjectLayer = true; + public bool MultiSelect; + + public ObjectEditorScreen(EditorCamera camera) + { + _camera = camera; + } + + public void Load() + { + _objectSelectionSelectionScreen.Load(); + } + + public void SetupUi(int posY) + { + { + var buttonWidth = _leftToolbarWidth - 10; + var halfButtonWidth = buttonWidth / 2 - 2; + var buttonHeight = 30; + var lableHeight = 20; + + //Game1.EditorUi.AddElement(new UiButton( + // new Rectangle(5, posY += (int)(buttonHeight * 1.5f) + 5, buttonWidth, buttonHeight), + // Resources.EditorFont, + // "add obj at selected tile", "bt1", Values.EditorUiObjectEditor, null, ui => { AddObjectsAt(); })); + + Game1.EditorUi.AddElement(new UiLabel(new Rectangle(5, posY, buttonWidth, buttonHeight), + Resources.EditorFont, "Mode", "bt1", Values.EditorUiObjectEditor, null)); + + Game1.EditorUi.AddElement(new UiButton( + new Rectangle(5, posY += buttonHeight, halfButtonWidth, buttonHeight), Resources.EditorFont, + "Draw", "bt1", Values.EditorUiObjectEditor, + ui => { ((UiButton)ui).Marked = _currentMode == Mode.Draw; }, + ui => { _currentMode = Mode.Draw; }) + { ButtonIcon = Resources.EditorIconEdit }); + + Game1.EditorUi.AddElement(new UiButton( + new Rectangle(5 + halfButtonWidth + 4, posY, halfButtonWidth, buttonHeight), + Resources.EditorFont, + "Edit", "bt1", Values.EditorUiObjectEditor, + ui => { ((UiButton)ui).Marked = _currentMode == Mode.Edit; }, + ui => { _currentMode = Mode.Edit; }) + { ButtonIcon = Resources.EditorIconSelect }); + + Game1.EditorUi.AddElement(new UiLabel( + new Rectangle(5, posY += buttonHeight + 5, buttonWidth, buttonHeight), + Resources.EditorFont, "Grid", "bt1", Values.EditorUiObjectEditor, null)); + + // grid size + posY += buttonHeight; + var gridValue = 1; + var gridButtonWidth = (buttonWidth - 3 * 4) / 5; + for (var i = 0; i < 5; i++) + { + var gridValueLocal = gridValue; + + Game1.EditorUi.AddElement(new UiButton( + new Rectangle(5 + (gridButtonWidth + 3) * i, posY, gridButtonWidth, buttonHeight), + Resources.EditorFont, + gridValue.ToString(), "bt1", Values.EditorUiObjectEditor, + ui => { ((UiButton)ui).Marked = gridSize == gridValueLocal; }, + ui => { ChangeGridSteps(gridValueLocal); })); + + gridValue *= 2; + } + + //_cublicBezier = new CubicBezier(100, Vector2.Zero, Vector2.One); + //Game1.EditorUi.AddElement(_bezier0 = new UiNumberInput( + // new Rectangle(5, posY += buttonHeight, buttonWidth, buttonHeight), + // Resources.EditorFont, 0, 0, 100, 1, "tx", Values.EditorUiObjectEditor, null, ui => UpdateBezierCurve())); + //Game1.EditorUi.AddElement(_bezier1 = new UiNumberInput( + // new Rectangle(5, posY += buttonHeight, buttonWidth, buttonHeight), + // Resources.EditorFont, 0, 0, 100, 1, "tx", Values.EditorUiObjectEditor, null, ui => UpdateBezierCurve())); + //Game1.EditorUi.AddElement(_bezier2 = new UiNumberInput( + // new Rectangle(5, posY += buttonHeight, buttonWidth, buttonHeight), + // Resources.EditorFont, 0, 0, 100, 1, "tx", Values.EditorUiObjectEditor, null, ui => UpdateBezierCurve())); + //Game1.EditorUi.AddElement(_bezier3 = new UiNumberInput( + // new Rectangle(5, posY += buttonHeight, buttonWidth, buttonHeight), + // Resources.EditorFont, 0, 0, 100, 1, "tx", Values.EditorUiObjectEditor, null, ui => UpdateBezierCurve())); + } + + { + var buttonWidth = _rightToolbarWidth - 10; + var buttonHeight = 30; + var buttonHeightBig = 50; + var lableHeight = 20; + + // right background + Game1.EditorUi.AddElement(new UiRectangle(Rectangle.Empty, "left", Values.EditorUiObjectEditor, + Values.ColorBackgroundLight, Color.White, + ui => + { + ui.Rectangle = new Rectangle(Game1.WindowWidth - _rightToolbarWidth, Values.ToolBarHeight, + _rightToolbarWidth, + Game1.WindowHeight - Values.ToolBarHeight); + })); + + var leftPosition = Game1.WindowWidth - buttonWidth - 5; + posY = Values.ToolBarHeight + 5; + + for (var i = 0; i < MaxParameter; i++) + { + var i1 = i; + + var textInputHeight = i >= 2 ? buttonHeightBig : buttonHeight; + + _uiParameterHeader[i] = new UiLabel( + new Rectangle(leftPosition, posY += textInputHeight + 5, buttonWidth, lableHeight), "", + Values.EditorUiObjectEditor) + { + SizeUpdate = ui => + { + ui.Rectangle = new Rectangle(Game1.WindowWidth - buttonWidth - 5, ui.Rectangle.Y, + ui.Rectangle.Width, ui.Rectangle.Height); + ((UiLabel)ui).UpdateLabelPosition(); + } + }; + + _uiParameterTextInput[i] = new UiTextInput( + new Rectangle(leftPosition, posY += lableHeight, buttonWidth, textInputHeight), + Resources.EditorFontMonoSpace, + 100, "objectparameter", Values.EditorUiObjectEditor, null, ui => + { + _strParameter[i1] = ((UiTextInput)ui).StrValue; + UpdateObjectParameter(); + }) + { + SizeUpdate = ui => + { + ui.Rectangle = new Rectangle(Game1.WindowWidth - buttonWidth - 5, ui.Rectangle.Y, + ui.Rectangle.Width, ui.Rectangle.Height); + } + }; + } + + // add the text fields + foreach (var element in _uiParameterTextInput) + Game1.EditorUi.AddElement(element); + + // add the labels + foreach (var element in _uiParameterHeader) + Game1.EditorUi.AddElement(element); + } + } + + //private void UpdateBezierCurve() + //{ + // _cublicBezier.FirstPoint = new Vector2(_bezier0.Value / 100.0f, _bezier1.Value / 100.0f); + // _cublicBezier.SecondPoint = new Vector2(_bezier2.Value / 100.0f, _bezier3.Value / 100.0f); + //} + + public void UpdateObjectSelection(GameTime gameTime) + { + // update object selection + _objectSelectionSelectionScreen.Update(gameTime); + } + + public void Update(GameTime gameTime) + { + Game1.EditorUi.CurrentScreen = Values.EditorUiObjectEditor; + + mousePosition = InputHandler.MousePosition(); + + mouseMapPosition = GetMapPosition(mousePosition); + + ObjectCursor = GetGriddedPosition(mouseMapPosition); + + if (_currentMode == Mode.Edit) + UpdateEditMode(); + else + UpdateDrawMode(); + + LastObjectCursor = ObjectCursor; + } + + public void UpdateDrawMode() + { + // draw + if (!MultiSelect) + SelectionStart = ObjectCursor; + + SelectionEnd = ObjectCursor; + + // start to draw or to erase + if (InsideField() && _currentDrawMode == DrawMode.Nothing) + { + if (InputHandler.MouseLeftStart()) + _currentDrawMode = DrawMode.Draw; + else if (InputHandler.MouseRightStart()) + _currentDrawMode = DrawMode.Erase; + + LastObjectCursor = null; + } + + if (_currentDrawMode == DrawMode.Draw && (InputHandler.MouseLeftDown() || InputHandler.MouseLeftReleased()) || + _currentDrawMode == DrawMode.Erase && (InputHandler.MouseRightDown() || InputHandler.MouseRightReleased())) + { + if (InputHandler.KeyDown(Keys.LeftAlt) && + (_currentDrawMode == DrawMode.Draw && InputHandler.MouseLeftDown() || + _currentDrawMode == DrawMode.Erase && InputHandler.MouseRightDown())) + { + MultiSelect = true; + } + else + { + // no longer in multiselect + if (MultiSelect) + { + MultiSelect = false; + FillMultiSelection(); + } + else + { + // only draw when the cursor was moved or drawing was just startet + if (LastObjectCursor != ObjectCursor) + FillSelection(); + } + } + } + else + { + MultiSelect = false; + _currentDrawMode = DrawMode.Nothing; + } + } + + public void UpdateEditMode() + { + // select the current object + if (InsideField() && InputHandler.MouseLeftStart()) + { + GetSingleSelectedObject(); + + if (_selectedGameObjectItem != null) + { + var mapPosition = GetMapPosition(mousePosition); + _startMovePosition = GetGriddedPosition(mapPosition); + + // what was this for??? + _moveOffset = GetGriddedPosition(new Point( + mapPosition.X - (int)_selectedGameObjectItem.Parameter[1], + mapPosition.Y - (int)_selectedGameObjectItem.Parameter[2])); + + _moveOffset = new Point( + _moveOffset.X * (Values.TileSize / gridSize), + _moveOffset.Y * (Values.TileSize / gridSize)); + + _currentEditMode = EditMode.Moving; + } + } + + if (InputHandler.MouseLeftReleased()) + { + _currentEditMode = EditMode.Idle; + + // update parameter after the position was changed + UpdateSelectedObjectParameters(); + } + + // update the location of the object to move + if (_currentEditMode == EditMode.Moving) + { + var scaledOffset = new Point( + (int)(_moveOffset.X * _camera.Scale), + (int)(_moveOffset.Y * _camera.Scale)); + + var griddedPosition = GetGriddedPosition(GetMapPosition(mousePosition - scaledOffset)); + + if (_startMovePosition != griddedPosition) + { + _startMovePosition = griddedPosition; + _selectedGameObjectItem.Parameter[1] = griddedPosition.X * Values.TileSize / gridSize; + _selectedGameObjectItem.Parameter[2] = griddedPosition.Y * Values.TileSize / gridSize; + } + } + } + + public void DrawObjectSelection(SpriteBatch spriteBatch) + { + _objectSelectionSelectionScreen.Draw(spriteBatch); + } + + public void Draw(SpriteBatch spriteBatch) + { + // draw all the objects + if (DrawObjectLayer) + { + foreach (var gameObjItem in Game1.GameManager.MapManager.CurrentMap.Objects.ObjectList) + { + // draw the object + if (EditorObjectTemplates.ContainsKey(gameObjItem.Index)) + { + var gameObject = EditorObjectTemplates[gameObjItem.Index]; + var scaledSize = new Vector2(gameObject.EditorIconSource.Width, gameObject.EditorIconSource.Height) * gameObject.EditorIconScale; + var position = new Vector2( + (int)gameObjItem.Parameter[1] + (scaledSize.X > 16 ? 0 : 8 - scaledSize.X / 2), + (int)gameObjItem.Parameter[2] + (scaledSize.Y > 16 ? 0 : 8 - scaledSize.Y / 2)); + gameObject.DrawEditor(spriteBatch, position); + + // overlay red on the selected object + if (_selectedGameObjectItem == gameObjItem) + spriteBatch.Draw(Resources.SprWhite, + new Rectangle((int)position.X, (int)position.Y, (int)scaledSize.X, (int)scaledSize.Y), Color.Red * 0.25f); + } + } + } + + + if (_currentMode == Mode.Draw) + { + // draw the selection + if (MultiSelect) + { + var left = Math.Min(SelectionStart.X, SelectionEnd.X); + var right = Math.Max(SelectionStart.X, SelectionEnd.X); + var top = Math.Min(SelectionStart.Y, SelectionEnd.Y); + var down = Math.Max(SelectionStart.Y, SelectionEnd.Y); + + spriteBatch.Draw(Resources.SprWhite, + new Rectangle( + left * Values.TileSize / gridSize, + top * Values.TileSize / gridSize, + (right - left + 1) * Values.TileSize / gridSize, + (down - top + 1) * Values.TileSize / gridSize), Color.White * 0.5f); + } + + // draw the cursor + spriteBatch.Draw(Resources.SprWhite, + new Rectangle( + ObjectCursor.X * Values.TileSize / gridSize, + ObjectCursor.Y * Values.TileSize / gridSize, + Values.TileSize / gridSize, + Values.TileSize / gridSize), Color.Red * 0.75f); + } + } + + public void DrawTop(SpriteBatch spriteBatch) + { + // draw the selected object above the blured layer + var rectangle = new Rectangle( + 0, Game1.WindowHeight - _leftToolbarWidth, _leftToolbarWidth, _leftToolbarWidth); + + _objectSelectionSelectionScreen.DrawSelectedObject(spriteBatch, rectangle); + + //var curveSize = 200; + //var curvePosition = new Vector2(300, 300); + + //for (var i = 0; i < _cublicBezier.Data.Length; i++) + //{ + // spriteBatch.Draw(Resources.SprWhite, new Vector2( + // curvePosition.X + (i / (float)(_cublicBezier.Data.Length - 1)) * curveSize, + // curvePosition.Y - _cublicBezier.Data[i] * curveSize) - new Vector2(1, 1), + // new Rectangle(0, 0, 3, 3), Color.Green); + //} + + //var smallCurveSize = 450; + //for (var i = 0; i < smallCurveSize; i++) + //{ + // var percentage = i / (float)(smallCurveSize - 1); + // var curve = _cublicBezier.EvaluateX(percentage); + // spriteBatch.Draw(Resources.SprWhite, new Vector2(curvePosition.X + percentage * curveSize, curvePosition.Y - curve * curveSize), Color.Red); + //} + + //for (var i = 0; i < curveSize; i++) + //{ + // var percentage = i / (float)(curveSize - 1); + // var curve = _cublicBezier.EvaluatePosition(percentage); + // spriteBatch.Draw(Resources.SprWhite, new Vector2(curvePosition.X + curve.X * curveSize, curvePosition.Y - curve.Y * curveSize), Color.White); + //} + + //spriteBatch.Draw(Resources.SprWhite, curvePosition + + // new Vector2(_cublicBezier.FirstPoint.X, -_cublicBezier.FirstPoint.Y) * curveSize - new Vector2(1, 1), new Rectangle(0, 0, 3, 3), Color.Blue); + //spriteBatch.Draw(Resources.SprWhite, curvePosition + + // new Vector2(_cublicBezier.SecondPoint.X, -_cublicBezier.SecondPoint.Y) * curveSize - new Vector2(1, 1), new Rectangle(0, 0, 3, 3), Color.Red); + + } + + public bool InsideField() + { + return InputHandler.MouseIntersect(new Rectangle( + _leftToolbarWidth, Values.ToolBarHeight, + Game1.WindowWidth - _leftToolbarWidth - _rightToolbarWidth, + Game1.WindowHeight - Values.ToolBarHeight)); + } + + private void GetSingleSelectedObject() + { + _selectedGameObjectItem = GetSelectedGameObject(mouseMapPosition, _selectedGameObjectItem); + + UpdateSelectedObjectParameters(); + } + + public void RemoveObject(Rectangle deleteRectangle) + { + var currentMap = Game1.GameManager.MapManager.CurrentMap; + + // remove one object that collides with the rectangle + for (var i = 0; i < currentMap.Objects.ObjectList.Count; i++) + { + var objectPosition = GetObjectPosition(currentMap.Objects.ObjectList[i], true); + var objTemplate = EditorObjectTemplates[currentMap.Objects.ObjectList[i].Index]; + var scaledSize = new Vector2(objTemplate.EditorIconSource.Width, objTemplate.EditorIconSource.Height) * objTemplate.EditorIconScale; + + if (objectPosition.X < deleteRectangle.X + deleteRectangle.Width && + deleteRectangle.X < objectPosition.X + scaledSize.X && + objectPosition.Y < deleteRectangle.Y + deleteRectangle.Height && + deleteRectangle.Y < objectPosition.Y + scaledSize.Y) + { + currentMap.Objects.ObjectList.Remove(currentMap.Objects.ObjectList[i]); + return; + } + } + } + + public List GetGameObjectsAt(Point position, bool selectMode) + { + var objectList = new List(); + + // search for the objects at the given position and add the to the list + foreach (var gameObject in Game1.GameManager.MapManager.CurrentMap.Objects.ObjectList) + { + // @HACK + // maybe the ObjectList wasn't that good of an idea + if (ObjectContainsPosition(gameObject, position, selectMode)) + objectList.Add(gameObject); + } + + return objectList; + } + + private Vector2 GetObjectPosition(GameObjectItem gameObjectItem, bool selectMode) + { + // calculate the position of the object + if (!selectMode) + return new Vector2((int)gameObjectItem.Parameter[1], (int)gameObjectItem.Parameter[2]); + + var objTemplate = EditorObjectTemplates[gameObjectItem.Index]; + var scaledSize = new Vector2(objTemplate.EditorIconSource.Width, objTemplate.EditorIconSource.Height) * objTemplate.EditorIconScale; + + return new Vector2( + (int)gameObjectItem.Parameter[1] + (scaledSize.X > 16 ? 0 : 8 - scaledSize.X / 2), + (int)gameObjectItem.Parameter[2] + (scaledSize.Y > 16 ? 0 : 8 - scaledSize.Y / 2)); + } + + private bool ObjectContainsPosition(GameObjectItem gameObjectItem, Point position, bool selectMode) + { + var objectPosition = GetObjectPosition(gameObjectItem, selectMode); + + var objTemplate = EditorObjectTemplates[gameObjectItem.Index]; + var scaledSize = new Vector2(objTemplate.EditorIconSource.Width, objTemplate.EditorIconSource.Height) * objTemplate.EditorIconScale; + + return objectPosition.X <= position.X && position.X < objectPosition.X + scaledSize.X && + objectPosition.Y <= position.Y && position.Y < objectPosition.Y + scaledSize.Y; + } + + public string ObjectToString(object stringObject) + { + if (stringObject is Rectangle rectangle) + return rectangle.X + "." + rectangle.Y + "." + rectangle.Width + "." + rectangle.Height; + if (stringObject is float) + return ((float)stringObject).ToString(CultureInfo.InvariantCulture); + + return stringObject.ToString(); + } + + private void UpdateSelectedObjectParameters() + { + if (_selectedGameObjectItem == null) + { + for (var i = 0; i < MaxParameter; i++) + { + _uiParameterHeader[i].IsVisible = false; + _uiParameterTextInput[i].IsVisible = false; + } + + return; + } + + var objectParameter = GameObjectTemplates.GameObjectParameter[_selectedGameObjectItem.Index]; + + for (var i = 1; i <= MaxParameter; i++) + { + if (objectParameter.Length > i) + { + _uiParameterHeader[i - 1].Label = objectParameter[i].Name; + + _strParameter[i - 1] = ""; + if (_selectedGameObjectItem.Parameter[i] != null) + _strParameter[i - 1] = ObjectToString(_selectedGameObjectItem.Parameter[i]); + + _uiParameterTextInput[i - 1].StrValue = _strParameter[i - 1]; + _uiParameterTextInput[i - 1].InputType = GameObjectTemplates.GameObjectParameter[_selectedGameObjectItem.Index][i].ParameterType; + } + + // hide the empty ui elements + _uiParameterHeader[i - 1].IsVisible = objectParameter.Length > i; + _uiParameterTextInput[i - 1].IsVisible = objectParameter.Length > i; + } + + _objectSelectionSelectionScreen.SelectObject(_selectedGameObjectItem.Index); + _objectSelectionSelectionScreen.SelectedObjectParameter = _selectedGameObjectItem.Parameter; + } + + private void UpdateObjectParameter() + { + // set the parameter of the object + if (_selectedGameObjectItem == null) return; + + for (var i = 1; i < _selectedGameObjectItem.Parameter.Length; i++) + { + var parameterType = GameObjectTemplates.GameObjectParameter[_selectedGameObjectItem.Index][i].ParameterType; + var parameter = MapData.ConvertToObject(_strParameter[i - 1], parameterType); + + if (parameter != null) + _selectedGameObjectItem.Parameter[i] = parameter; + } + } + + private string GetObjectIndex() + { + return _currentDrawMode == DrawMode.Draw ? _objectSelectionSelectionScreen.SelectedObjectIndex : null; + } + + private object[] GetObjectParameter() + { + return _objectSelectionSelectionScreen.SelectedObjectParameter; + } + + private void FillMultiSelection() + { + var left = Math.Min(SelectionStart.X, SelectionEnd.X); + var right = Math.Max(SelectionStart.X, SelectionEnd.X); + var top = Math.Min(SelectionStart.Y, SelectionEnd.Y); + var down = Math.Max(SelectionStart.Y, SelectionEnd.Y); + + for (var y = top; y <= down; y++) + for (var x = left; x <= right; x++) + { + SetMapObject( + x * Values.TileSize / gridSize, + y * Values.TileSize / gridSize, _currentLayer, GetObjectIndex(), GetObjectParameter()); + } + } + + private void FillSelection() + { + // draw or delete + SetMapObject( + ObjectCursor.X * Values.TileSize / gridSize, + ObjectCursor.Y * Values.TileSize / gridSize, _currentLayer, GetObjectIndex(), GetObjectParameter()); + } + + private void SetMapObject(int x, int y, int z, string index, object[] parameter) + { + // remove the object + if (index == null) + { + RemoveObject(new Rectangle(x, y, Values.TileSize / gridSize, Values.TileSize / gridSize)); + return; + } + + // create a clone of the parameter + var objParameter = MapData.GetParameterArray(index); + + objParameter[1] = x; + objParameter[2] = y; + + // this does only make a shallow copy, but the editor does not even support the editing of arrays in the parameters + // so this should be okay as long the editor does not allow this + for (var i = 3; i < parameter?.Length; i++) + objParameter[i] = parameter[i]; + + AddObjectToMap(index, objParameter); + } + + public Point GetMapPosition(Point inputPosition) + { + return new Point( + (int)((inputPosition.X - _camera.Location.X) / _camera.Scale), + (int)((inputPosition.Y - _camera.Location.Y) / _camera.Scale)); + } + + public Point GetGriddedPosition(Point inputPosition) + { + var position = new Point( + inputPosition.X / (Values.TileSize / gridSize), + inputPosition.Y / (Values.TileSize / gridSize)); + + // fix + if (inputPosition.X < 0) + position.X--; + if (inputPosition.Y < 0) + position.Y--; + + return position; + } + + private void ChangeGridSteps(int scale) + { + gridSize = scale; + } + + public void AddObjectToMap(string index, object[] parameter) + { + if (index == null) return; + + // only add the object if there is currently not the same object on the position + var goAtPosition = GetGameObjectsAt(new Point((int)parameter[1], (int)parameter[2]), false); + foreach (var gameObjects in goAtPosition) + if (gameObjects.Index == index && + (int)gameObjects.Parameter[1] == (int)parameter[1] && + (int)gameObjects.Parameter[2] == (int)parameter[2]) + return; + + // add the object + Game1.GameManager.MapManager.CurrentMap.Objects.ObjectList.Add(new GameObjectItem(index, parameter)); + } + + public GameObjectItem GetSelectedGameObject(Point position, GameObjectItem startSelection) + { + var objectsAtPosition = GetGameObjectsAt(position, true); + + if (objectsAtPosition.Count <= 0) + return null; + + // @Hack + // finds the start position of the "startSelection"-GameObjectItem + // so it is possible to switch between objects at the same position + var startPosition = 0; + if (startSelection != null) + for (var i = 0; i < objectsAtPosition.Count; i++) + if (objectsAtPosition[i] == startSelection) + { + startPosition = i + 1; + break; + } + + var index = startPosition % objectsAtPosition.Count; + return objectsAtPosition[index]; + } + + public static void OffsetObjects(Map map, int offsetX, int offsetY) + { + foreach (var gameObject in map.Objects.ObjectList) + { + gameObject.Parameter[1] = (int)gameObject.Parameter[1] + offsetX; + gameObject.Parameter[2] = (int)gameObject.Parameter[2] + offsetY; + } + } + } +} diff --git a/Editor/ObjectSelectionScreen.cs b/Editor/ObjectSelectionScreen.cs new file mode 100644 index 0000000..b7a44a9 --- /dev/null +++ b/Editor/ObjectSelectionScreen.cs @@ -0,0 +1,184 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.Editor +{ + internal class ObjectSelectionScreen + { + private readonly EditorCamera _camera = new EditorCamera(); + private readonly EditorCamera _singleObjectCamera = new EditorCamera(); + private Point _drawSize; + + public object[] SelectedObjectParameter; + public string SelectedObjectIndex; + + private GameObject _selectedObject; + private Vector2 _objectNameTextSize; + private int _columns = 30; + + private List _objectList = new List(); + + public ObjectSelectionScreen() + { + _camera.Location = new Point(400, 250); + } + + public void Load() + { + foreach (var gameObjItem in GameObjectTemplates.ObjectTemplates) + { + if (gameObjItem.Value != null) + _objectList.Add(gameObjItem.Key); + else + { + // create "line break" for the object selection + var count = _columns - _objectList.Count % _columns; + for (var i = 0; i < count; i++) + _objectList.Add(""); + } + } + + _drawSize = new Point(_columns * 32, (int)Math.Ceiling(_objectList.Count / (float)_columns) * 32); + } + + public void Update(GameTime gameTime) + { + Game1.EditorUi.CurrentScreen = Values.EditorUiObjectSelection; + + var position = InputHandler.MousePosition(); + + // update tileset scale + if (InputHandler.MouseWheelUp() && _camera.Scale < 10) + { + _camera.Scale += 0.25f; + var scale = _camera.Scale / (_camera.Scale - 0.25f); + _camera.Location.X = InputHandler.MousePosition().X - (int)((InputHandler.MousePosition().X - _camera.Location.X) * scale); + _camera.Location.Y = InputHandler.MousePosition().Y - (int)((InputHandler.MousePosition().Y - _camera.Location.Y) * scale); + } + if (InputHandler.MouseWheelDown() && _camera.Scale > 1) + { + _camera.Scale -= 0.25f; + var scale = _camera.Scale / (_camera.Scale + 0.25f); + _camera.Location.X = InputHandler.MousePosition().X - (int)((InputHandler.MousePosition().X - _camera.Location.X) * scale); + _camera.Location.Y = InputHandler.MousePosition().Y - (int)((InputHandler.MousePosition().Y - _camera.Location.Y) * scale); + } + + // move the tileset + if (!InputHandler.MouseMiddleStart() && InputHandler.MouseMiddleDown()) + _camera.Location += position - InputHandler.LastMousePosition(); + + // update currentSelection + if (InputHandler.MouseLeftPressed(new Rectangle( + _camera.Location.X, _camera.Location.Y, + (int)(_drawSize.X * _camera.Scale), + (int)(_drawSize.Y * _camera.Scale)))) + { + var selectionIndex = (int)((position.X - _camera.Location.X) / (32 * _camera.Scale)) + + (int)((position.Y - _camera.Location.Y) / (32 * _camera.Scale)) * _columns; + + if (_objectList[selectionIndex] != "" && selectionIndex < _objectList.Count) + SelectObject(_objectList[selectionIndex]); + } + } + + public void Draw(SpriteBatch spriteBatch) + { + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, _camera.TransformMatrix); + + // draw the tiled background + spriteBatch.Draw(Resources.SprTiledBlock, + new Rectangle(0, 0, _drawSize.X, _drawSize.Y), + new Rectangle(0, 0, _drawSize.X / Values.TileSize * 2, + _drawSize.Y / Values.TileSize * 2), Color.LightGray); + + // draw the objects + var objIndex = 0; + foreach (var objKey in _objectList) + { + if (objKey == "") + { + objIndex++; + continue; + } + + // draw the selection + if (SelectedObjectIndex == objKey) + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + objIndex % _columns * 32, + objIndex / _columns * 32, 32, 32), Color.Red * 0.5f); + + var objTemplate = ObjectEditorScreen.EditorObjectTemplates[objKey]; + objTemplate.DrawEditor(spriteBatch, new Vector2( + objIndex % _columns * 32 + 16 - objTemplate.EditorIconSource.Width * objTemplate.EditorIconScale / 2, + objIndex / _columns * 32 + 16 - objTemplate.EditorIconSource.Height * objTemplate.EditorIconScale / 2)); + + objIndex++; + } + + spriteBatch.End(); + + spriteBatch.Begin(); + + // draw the name of the selected object + if (SelectedObjectIndex != null) + { + spriteBatch.DrawString(Resources.EditorFont, SelectedObjectIndex, + new Vector2(5, Game1.WindowHeight - Resources.EditorFontHeight - 5), Color.Red); + } + + spriteBatch.End(); + } + + public void SelectObject(string objIndex) + { + SelectedObjectIndex = objIndex; + SelectedObjectParameter = MapData.GetParameterArray(SelectedObjectIndex); + _selectedObject = ObjectEditorScreen.EditorObjectTemplates[SelectedObjectIndex]; + + // measure the size + _objectNameTextSize = Resources.EditorFont.MeasureString(SelectedObjectIndex); + } + + public void DrawSelectedObject(SpriteBatch spriteBatch, Rectangle rectangle) + { + rectangle.Y -= Resources.EditorFontHeight + 10; + + // draw the background + spriteBatch.Draw(Resources.SprWhite, rectangle, Color.White * 0.25f); + + if (_selectedObject == null) return; + + // draw the name + spriteBatch.DrawString(Resources.EditorFont, SelectedObjectIndex, + new Vector2(rectangle.Right - _objectNameTextSize.X - 10, rectangle.Bottom + 5), Color.White); + + var scale = MathHelper.Min( + rectangle.Width / (_selectedObject.EditorIconSource.Width * _selectedObject.EditorIconScale), + rectangle.Height / (_selectedObject.EditorIconSource.Height * _selectedObject.EditorIconScale)); + + var drawWidth = (int)(scale * _selectedObject.EditorIconSource.Width * _selectedObject.EditorIconScale); + var drawHeight = (int)(scale * _selectedObject.EditorIconSource.Height * _selectedObject.EditorIconScale); + + _singleObjectCamera.Scale = scale; + _singleObjectCamera.Location = new Point( + rectangle.X + rectangle.Width / 2 - drawWidth / 2, + rectangle.Y + rectangle.Height / 2 - drawHeight / 2); + + spriteBatch.End(); + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, _singleObjectCamera.TransformMatrix); + + // draw the selected object + _selectedObject.DrawEditor(spriteBatch, new Vector2(0, 0)); + + spriteBatch.End(); + spriteBatch.Begin(); + } + } +} diff --git a/Editor/SpriteAtlasScreen.cs b/Editor/SpriteAtlasScreen.cs new file mode 100644 index 0000000..3a5cae0 --- /dev/null +++ b/Editor/SpriteAtlasScreen.cs @@ -0,0 +1,588 @@ +using System; +using System.Collections.Generic; +using System.IO; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.Base.UI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using Keys = Microsoft.Xna.Framework.Input.Keys; +#if WINDOWS +using System.Windows.Forms; +#endif + +namespace ProjectZ.Editor +{ + internal class SpriteAtlasScreen : InGame.Screens.Screen + { + private readonly EditorCamera _camera = new EditorCamera(); + + private readonly SpriteAtlasSerialization.SpriteAtlas _spriteAtlas = new SpriteAtlasSerialization.SpriteAtlas(); + private List _sourceData => _spriteAtlas.Data; + private UiEditList _spriteAtlasList; + + private int _spriteIndex; + private SpriteAtlasSerialization.AtlasEntry _selectedEntry; + + private List _moveEntries = new List(); + + private Texture2D _sprTexture; + private Color[] _colorData; + + private Texture2D _sprSelectionTexture; + private Color[] _colorDataSelection; + + private Point _lastPosition; + private Point _currentPosition; + private Point _selectionStart; + private Point _selectionEnd; + + private UiNumberInput _atlasScale; + private UiNumberInput _inputSourceX; + private UiNumberInput _inputSourceY; + private UiNumberInput _inputSourceWidth; + private UiNumberInput _inputSourceHeight; + private UiNumberInput _inputSourceOriginX; + private UiNumberInput _inputSourceOriginY; + private UiTextInput _inputEntryName; + + private string _lastFileName; + + private const int LeftBarWidth = 200; + private const int RightBarWidth = 250; + private const int TileSize = 2; + + private bool _selecting; + private bool _imageWasEdited; + + public SpriteAtlasScreen(string screenId) : base(screenId) { } + + public override void Load(ContentManager content) + { + var buttonDist = 5; + var buttonWidth = LeftBarWidth - buttonDist * 2; + var buttonWidthHalf = (LeftBarWidth - buttonDist * 3) / 2; + var buttonHeight = 30; + var labelHeight = Resources.EditorFontHeight; + var buttonQWidth = LeftBarWidth - 15 - buttonHeight; + var posY = Values.ToolBarHeight + buttonDist; + + var screenId = Values.EditorUiSpriteAtlas; + + Game1.EditorUi.AddElement(new UiRectangle(new Rectangle(0, 0, 0, 0), "leftBar", screenId, Values.ColorBackgroundLight, Color.White, + ui => { ui.Rectangle = new Rectangle(0, Values.ToolBarHeight, LeftBarWidth, Game1.WindowHeight - Values.ToolBarHeight); })); + + Game1.EditorUi.AddElement(new UiRectangle(new Rectangle(0, 0, 0, 0), "rightBar", screenId, Values.ColorBackgroundLight, Color.White, + ui => { ui.Rectangle = new Rectangle(Game1.WindowWidth - RightBarWidth, Values.ToolBarHeight, RightBarWidth, Game1.WindowHeight - Values.ToolBarHeight); })); + + posY = Values.ToolBarHeight + buttonDist; + + // load button + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY, buttonWidth, buttonHeight), Resources.EditorFont, + "load", "bt1", screenId, null, ui => { LoadSprite(); })); + // save button + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight), Resources.EditorFont, + "save as...", "bt1", screenId, null, ui => { SaveSpriteAtlasDialog(); })); + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight), Resources.EditorFont, + "save...", "bt1", screenId, null, ui => { SaveSpriteAtlas(_lastFileName); })); + + Game1.EditorUi.AddElement(_atlasScale = new UiNumberInput(new Rectangle(5, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight), + Resources.EditorFont, 0, 1, 16, 1, "Scaling", screenId, null, + ui => + { + _spriteAtlas.Scale = (int)((UiNumberInput)ui).Value; + })); + + Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist, posY += buttonHeight + buttonDist * 3, buttonWidth, labelHeight), + Resources.EditorFont, "Source Rectangle", "sourceHeader", screenId, null)); + + var minValue = 0; + var maxValue = 10000; + + _inputSourceX = new UiNumberInput(new Rectangle(buttonDist, posY += labelHeight + buttonDist, buttonWidthHalf, buttonHeight), + Resources.EditorFont, 0, minValue, maxValue, 1, "sourceX", screenId, null, + ui => + { + FixSelectedPart(); + _sourceData[_spriteIndex].SourceRectangle.X = (int)((UiNumberInput)ui).Value; + }); + _inputSourceY = new UiNumberInput(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, buttonWidthHalf, buttonHeight), + Resources.EditorFont, 0, minValue, maxValue, 1, "sourceY", screenId, null, + ui => + { + FixSelectedPart(); + _sourceData[_spriteIndex].SourceRectangle.Y = (int)((UiNumberInput)ui).Value; + }); + _inputSourceWidth = new UiNumberInput(new Rectangle(buttonDist, posY += buttonHeight + buttonDist, buttonWidthHalf, buttonHeight), + Resources.EditorFont, 0, minValue, maxValue, 1, "sourceWidth", screenId, null, ui => + { + FixSelectedPart(); + _sourceData[_spriteIndex].SourceRectangle.Width = (int)((UiNumberInput)ui).Value; + }); + _inputSourceHeight = new UiNumberInput(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, buttonWidthHalf, buttonHeight), + Resources.EditorFont, 0, minValue, maxValue, 1, "sourceHeight", screenId, null, ui => + { + FixSelectedPart(); + _sourceData[_spriteIndex].SourceRectangle.Height = (int)((UiNumberInput)ui).Value; + }); + + Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist, posY += buttonHeight + buttonDist * 3, buttonWidth, labelHeight), + Resources.EditorFont, "Origin", "originLabel", screenId, null)); + + Game1.EditorUi.AddElement(_inputSourceOriginX = new UiNumberInput(new Rectangle(buttonDist, posY += labelHeight + buttonDist, buttonWidthHalf, buttonHeight), + Resources.EditorFont, 0, minValue, maxValue, 1, "originX", screenId, null, + ui => + { + _sourceData[_spriteIndex].Origin.X = (int)((UiNumberInput)ui).Value; + })); + Game1.EditorUi.AddElement(_inputSourceOriginY = new UiNumberInput(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, buttonWidthHalf, buttonHeight), + Resources.EditorFont, 0, minValue, maxValue, 1, "originY", screenId, null, + ui => + { + _sourceData[_spriteIndex].Origin.Y = (int)((UiNumberInput)ui).Value; + })); + + Game1.EditorUi.AddElement(_inputSourceX); + Game1.EditorUi.AddElement(_inputSourceY); + Game1.EditorUi.AddElement(_inputSourceWidth); + Game1.EditorUi.AddElement(_inputSourceHeight); + + var buttonWidthRight = RightBarWidth - buttonDist * 2; + var buttonWidthHalfRight = (RightBarWidth - buttonDist * 3) / 2; + var buttonHeightRight = 25; + + posY = Values.ToolBarHeight + buttonDist; + var inputPosY = posY; + _inputEntryName = new UiTextInput(new Rectangle(0, 0, buttonWidthRight, 35), Resources.EditorFontMonoSpace, 32, "inputSpriteName", screenId, + element => element.Rectangle = new Rectangle(Game1.WindowWidth - RightBarWidth + buttonDist, inputPosY, buttonWidthRight, 45), + element => + { + if (_sourceData.Count > _spriteIndex) + _sourceData[_spriteIndex].EntryId = ((UiTextInput)element).StrValue; + }); + Game1.EditorUi.AddElement(_inputEntryName); + + posY += 45 + buttonDist; + var buttonPosY0 = posY; + Game1.EditorUi.AddElement(new UiButton(Rectangle.Empty, Resources.EditorFont, "add", "bt1", screenId, + element => element.Rectangle = new Rectangle(Game1.WindowWidth - RightBarWidth + buttonDist, buttonPosY0, buttonWidthHalfRight, buttonHeight), + ui => { AddAtlasEntry(); })); + + var buttonPosY1 = posY; + Game1.EditorUi.AddElement(new UiButton(Rectangle.Empty, Resources.EditorFont, "remove", "bt2", screenId, + element => element.Rectangle = new Rectangle(Game1.WindowWidth - RightBarWidth + buttonDist * 2 + buttonWidthHalfRight, buttonPosY1, buttonWidthHalfRight, buttonHeight), + ui => { RemoveAtlasEntry(); })); + + posY += buttonHeight + buttonDist; + var buttonPosY2 = posY; + Game1.EditorUi.AddElement(new UiButton(Rectangle.Empty, Resources.EditorFont, "sort", "bt3", screenId, + element => element.Rectangle = new Rectangle(Game1.WindowWidth - RightBarWidth + buttonDist, buttonPosY2, buttonWidthRight, buttonHeight), + ui => { SortAtlasEntry(); })); + + posY += buttonHeight + buttonDist; + Game1.EditorUi.AddElement(_spriteAtlasList = new UiEditList( + Rectangle.Empty, Resources.EditorFontSmallMonoSpace, _sourceData, "bt4", screenId, element => + { + element.Rectangle = new Rectangle(Game1.WindowWidth - RightBarWidth, posY, RightBarWidth, Game1.WindowHeight - posY); + var selectedEntry = ((UiEditList)element).SelectedEntry; + if (selectedEntry != _spriteIndex) + { + // do not fix anything if just the order of the list was changed + if (_sourceData[selectedEntry] != _selectedEntry) + FixSelectedPart(); + + _spriteIndex = selectedEntry; + _selectedEntry = _sourceData[_spriteIndex]; + + UpdateInputUi(); + } + })); + } + + public override void Update(GameTime gameTime) + { + Game1.EditorUi.CurrentScreen = Values.EditorUiSpriteAtlas; + + if (_sprTexture == null) + return; + + // update the camera + var mousePosition = InputHandler.MousePosition(); + + if (InputHandler.MouseIntersect(new Rectangle(LeftBarWidth, Values.ToolBarHeight, + Game1.WindowWidth - LeftBarWidth - RightBarWidth, Game1.WindowHeight - Values.ToolBarHeight))) + { + _currentPosition = new Point( + (int)((InputHandler.MousePosition().X - _camera.Location.X) / _camera.Scale), + (int)((InputHandler.MousePosition().Y - _camera.Location.Y) / _camera.Scale)); + + if (InputHandler.MouseLeftStart()) + { + FixSelectedPart(); + + if (InputHandler.KeyDown(Keys.LeftShift)) + { + SelectSprite(_currentPosition); + } + else + { + _selecting = true; + _selectionStart = _currentPosition; + } + } + if (InputHandler.MouseLeftDown() && _selecting) + { + _selectionEnd = _currentPosition; + + var selectionStart = new Point(Math.Min(_selectionStart.X, _selectionEnd.X), Math.Min(_selectionStart.Y, _selectionEnd.Y)); + var selectionEnd = new Point(Math.Max(_selectionStart.X, _selectionEnd.X) + 1, Math.Max(_selectionStart.Y, _selectionEnd.Y) + 1); + + _sourceData[_spriteIndex].SourceRectangle.X = selectionStart.X; + _sourceData[_spriteIndex].SourceRectangle.Y = selectionStart.Y; + _sourceData[_spriteIndex].SourceRectangle.Width = selectionEnd.X - selectionStart.X; + _sourceData[_spriteIndex].SourceRectangle.Height = selectionEnd.Y - selectionStart.Y; + + UpdateInputUi(); + } + if (InputHandler.MouseLeftReleased()) + { + _selecting = false; + } + + if (InputHandler.MouseRightStart() && _sprSelectionTexture == null) + { + var selectionSource = _sourceData[_spriteIndex].SourceRectangle; + + if (selectionSource.Width > 0 && selectionSource.Height > 0) + { + _colorDataSelection = new Color[selectionSource.Width * selectionSource.Height]; + + // fill the color data array + for (var y = 0; y < selectionSource.Height; y++) + for (var x = 0; x < selectionSource.Width; x++) + { + var originX = selectionSource.X + x; + var originY = selectionSource.Y + y; + + if (0 <= originX && originX < _sprTexture.Width && + 0 <= originY && originY < _sprTexture.Height) + { + _colorDataSelection[x + y * selectionSource.Width] = + _colorData[originX + originY * _sprTexture.Width]; + + // remove the data from the base texture + _colorData[originX + originY * _sprTexture.Width] = Color.Transparent; + } + else + _colorDataSelection[x + y * selectionSource.Width] = Color.Transparent; + } + + _sprSelectionTexture = new Texture2D(Game1.Graphics.GraphicsDevice, selectionSource.Width, selectionSource.Height); + _sprSelectionTexture.SetData(_colorDataSelection); + + _sprTexture.SetData(_colorData); + + // get a list of entries that will be moved + _moveEntries.Clear(); + for (var i = 0; i < _sourceData.Count; i++) + { + if (i != _spriteIndex && + _sourceData[_spriteIndex].SourceRectangle.Contains(_sourceData[i].SourceRectangle)) + { + _moveEntries.Add(i); + } + } + } + } + if (InputHandler.MouseRightDown()) + { + var offset = new Point(_currentPosition.X - _lastPosition.X, _currentPosition.Y - _lastPosition.Y); + MoveSelection(offset); + } + + if (InputHandler.MouseWheelUp()) + _camera.Zoom(1, mousePosition); + if (InputHandler.MouseWheelDown()) + _camera.Zoom(-1, mousePosition); + } + + if (!InputHandler.MouseMiddleStart() && InputHandler.MouseMiddleDown()) + _camera.Location += mousePosition - InputHandler.LastMousePosition(); + + _lastPosition = _currentPosition; + } + + public override void Draw(SpriteBatch spriteBatch) + { + if (_sprTexture == null) + return; + + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, _camera.TransformMatrix); + + // draw the tiled background + spriteBatch.Draw(Resources.SprTiledBlock, new Rectangle(0, 0, _sprTexture.Width, _sprTexture.Height), + new Rectangle(0, 0, (int)(_sprTexture.Width / (float)TileSize * 2), (int)(_sprTexture.Height / (float)TileSize * 2)), Color.White); + + // draw the sprite + spriteBatch.Draw(_sprTexture, Vector2.Zero, Color.White); + + // draw the sprite selection + if (_sprSelectionTexture != null) + spriteBatch.Draw(_sprSelectionTexture, + new Vector2(_sourceData[_spriteIndex].SourceRectangle.X, + _sourceData[_spriteIndex].SourceRectangle.Y), Color.White); + + // draw current position of the mouse + spriteBatch.Draw(Resources.SprWhite, + new Rectangle(_currentPosition.X, _currentPosition.Y, 1, 1), Color.Red * 0.5f); + + for (var i = 0; i < _sourceData.Count; i++) + { + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + _sourceData[i].SourceRectangle.X, _sourceData[i].SourceRectangle.Y, + _sourceData[i].SourceRectangle.Width, _sourceData[i].SourceRectangle.Height), + _spriteIndex == i ? Color.Red * (0.5f + MathF.Sin((float)Game1.TotalTime / 100) * 0.125f) : Color.Red * 0.25f); + } + + spriteBatch.End(); + spriteBatch.Begin(); + + // draw the origin xy axis + if (0 <= _spriteIndex && _spriteIndex <= _sourceData.Count) + { + var originPosition = new Vector2( + _camera.Location.X + (_sourceData[_spriteIndex].SourceRectangle.X + _sourceData[_spriteIndex].Origin.X) * _camera.Scale, + _camera.Location.Y + (_sourceData[_spriteIndex].SourceRectangle.Y + _sourceData[_spriteIndex].Origin.Y) * _camera.Scale); + spriteBatch.Draw(Resources.SprWhite, new Vector2(originPosition.X - 1, originPosition.Y - 10), new Rectangle(0, 0, 2, 20), Color.Green); + spriteBatch.Draw(Resources.SprWhite, new Vector2(originPosition.X - 10, originPosition.Y - 1), new Rectangle(0, 0, 20, 2), Color.Red); + } + + spriteBatch.End(); + } + + private void MoveSelection(Point offset) + { + foreach (var entryIndex in _moveEntries) + { + _sourceData[entryIndex].SourceRectangle.X += offset.X; + _sourceData[entryIndex].SourceRectangle.Y += offset.Y; + } + + _sourceData[_spriteIndex].SourceRectangle.X += offset.X; + _sourceData[_spriteIndex].SourceRectangle.Y += offset.Y; + } + + private void FixSelectedPart() + { + if (_sprSelectionTexture == null) + return; + + _imageWasEdited = true; + + var selectionSource = _sourceData[_spriteIndex].SourceRectangle; + + // need to resize the texture? + var offset = Point.Zero; + if (selectionSource.X < 0) + offset.X = -selectionSource.X; + if (selectionSource.Y < 0) + offset.Y = -selectionSource.Y; + + var newSizeX = Math.Max(offset.X + selectionSource.Right, offset.X + _sprTexture.Width); + var newSizeY = Math.Max(offset.Y + selectionSource.Bottom, offset.Y + _sprTexture.Height); + + // clamp the max texture size + var maxSize = 4096; + if (newSizeX > maxSize) + { + if (offset.X > 0) + offset.X = Math.Clamp(offset.X, 0, maxSize - _sprTexture.Width); + newSizeX = maxSize; + } + if (newSizeY > maxSize) + { + if (offset.Y > 0) + offset.X = Math.Clamp(offset.Y, 0, maxSize - _sprTexture.Height); + newSizeY = maxSize; + } + + if (newSizeX != _sprTexture.Width || newSizeY != _sprTexture.Height) + { + var newColorData = new Color[newSizeX * newSizeY]; + for (var y = 0; y < _sprTexture.Height; y++) + for (var x = 0; x < _sprTexture.Width; x++) + { + newColorData[(x + offset.X) + (y + offset.Y) * newSizeX] = _colorData[x + y * _sprTexture.Width]; + } + + _colorData = newColorData; + _sprTexture = new Texture2D(Game1.Graphics.GraphicsDevice, newSizeX, newSizeY); + _sprTexture.SetData(_colorData); + + _currentPosition += offset; + _camera.Location -= new Point((int)(offset.X * _camera.Scale), (int)(offset.Y * _camera.Scale)); + } + + // fill the color data array + for (var y = 0; y < _sprSelectionTexture.Height; y++) + for (var x = 0; x < _sprSelectionTexture.Width; x++) + { + var originX = selectionSource.X + x + offset.X; + var originY = selectionSource.Y + y + offset.Y; + + if (0 <= originX && originX < _sprTexture.Width && + 0 <= originY && originY < _sprTexture.Height && + _colorDataSelection[x + y * selectionSource.Width] != Color.Transparent) + _colorData[originX + originY * _sprTexture.Width] = _colorDataSelection[x + y * selectionSource.Width]; + } + _sprTexture.SetData(_colorData); + + _sprSelectionTexture = null; + + // move the source data if the texture gets expanded on the left or top + foreach (var source in _sourceData) + { + source.SourceRectangle.X += offset.X; + source.SourceRectangle.Y += offset.Y; + } + } + + private void SelectSprite(Point position) + { + for (var i = 0; i < _sourceData.Count; i++) + if (_sourceData[i].SourceRectangle.Contains(position)) + { + _spriteIndex = i; + _selectedEntry = _sourceData[_spriteIndex]; + _spriteAtlasList.SelectedEntry = _spriteIndex; + UpdateInputUi(); + return; + } + } + + private void UpdateInputUi() + { + _inputSourceX.Value = _sourceData[_spriteIndex].SourceRectangle.X; + _inputSourceY.Value = _sourceData[_spriteIndex].SourceRectangle.Y; + _inputSourceWidth.Value = _sourceData[_spriteIndex].SourceRectangle.Width; + _inputSourceHeight.Value = _sourceData[_spriteIndex].SourceRectangle.Height; + _inputSourceOriginX.Value = _sourceData[_spriteIndex].Origin.X; + _inputSourceOriginY.Value = _sourceData[_spriteIndex].Origin.Y; + _inputEntryName.StrValue = _sourceData[_spriteIndex].EntryId; + } + + private void AddAtlasEntry() + { + _sourceData.Add(new SpriteAtlasSerialization.AtlasEntry { EntryId = "" }); + } + + private void RemoveAtlasEntry() + { + if (_spriteIndex >= 0 && _sourceData.Count > _spriteIndex) + _sourceData.RemoveAt(_spriteIndex); + + // move the selection up if we are at the bottom + if (_spriteIndex >= _sourceData.Count) + { + _spriteIndex--; + _spriteAtlasList.SelectedEntry = _spriteIndex; + } + } + + private void SortAtlasEntry() + { + _sourceData.Sort((x, y) => x.EntryId.CompareTo(y.EntryId)); + } + + private void LoadSprite() + { +#if WINDOWS + var openFileDialog = new OpenFileDialog() + { + Filter = "sprite file (*.png)|*.png" + }; + + if (openFileDialog.ShowDialog() != DialogResult.OK) + return; + + LoadSpriteEditor(openFileDialog.FileName); +#endif + } + + public void LoadSpriteEditor(string filePath) + { + _imageWasEdited = false; + + // load the sprite + using var stream = File.OpenRead(filePath); + _sprTexture = Texture2D.FromStream(Game1.Graphics.GraphicsDevice, stream); + _lastFileName = filePath; + + _colorData = new Color[_sprTexture.Width * _sprTexture.Height]; + _sprTexture.GetData(_colorData); + + _spriteAtlas.Scale = 1; + _sourceData.Clear(); + + // load the sprite atlas if there is one + var atlasFileName = _lastFileName.Replace(".png", ".atlas"); + if (!SpriteAtlasSerialization.LoadSpriteAtlas(atlasFileName, _spriteAtlas)) + AddAtlasEntry(); + + // need to be scaled to actually have the source rectangle + foreach (var entry in _spriteAtlas.Data) + { + entry.SourceRectangle.X *= _spriteAtlas.Scale; + entry.SourceRectangle.Y *= _spriteAtlas.Scale; + entry.SourceRectangle.Width *= _spriteAtlas.Scale; + entry.SourceRectangle.Height *= _spriteAtlas.Scale; + entry.Origin.X *= _spriteAtlas.Scale; + entry.Origin.Y *= _spriteAtlas.Scale; + } + + _atlasScale.Value = _spriteAtlas.Scale; + + _spriteIndex = 0; + _selectedEntry = _sourceData[_spriteIndex]; + UpdateInputUi(); + } + + private void SaveSpriteAtlasDialog() + { +#if WINDOWS + var saveFileDialog = new SaveFileDialog() + { + RestoreDirectory = true, + Filter = "sprite file (*.png)|*.png", + }; + + if (_lastFileName != null) + { + saveFileDialog.FileName = Path.GetFileName(_lastFileName); + saveFileDialog.InitialDirectory = Path.GetFullPath(Path.GetDirectoryName(_lastFileName)); + } + + if (saveFileDialog.ShowDialog() == DialogResult.OK) + SaveSpriteAtlas(saveFileDialog.FileName); +#endif + } + + private void SaveSpriteAtlas(string filePath) + { + FixSelectedPart(); + + // save the texture? + if (_imageWasEdited) + { + using Stream stream = File.Create(filePath); + _sprTexture.SaveAsPng(stream, _sprTexture.Width, _sprTexture.Height); + } + + // save the sprite atlas + var atlasFileName = filePath.Replace(".png", ".atlas"); + SpriteAtlasSerialization.SaveSpriteAtlas(atlasFileName, _spriteAtlas); + } + } +} diff --git a/Editor/TileEditorScreen.cs b/Editor/TileEditorScreen.cs new file mode 100644 index 0000000..b74d3c1 --- /dev/null +++ b/Editor/TileEditorScreen.cs @@ -0,0 +1,673 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using ProjectZ.Base; +using ProjectZ.Base.UI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.Editor +{ + class TileEditorScreen + { + public Map Map; + private TileMap TileMap => Map.TileMap; + + public Point Selection; + public Point SelectionStart; + public Point SelectionEnd; + + public bool DrawMode; + public bool Drawing; + public bool MarkSelectedTiles; + public bool MultiSelect; + public bool IsSelecting; + + public bool[] LayerVisibility = { true, true, false }; + + private readonly EditorCamera _camera; + private readonly TileSelectionScreen _tileSelectionScreen = new TileSelectionScreen(); + + private Point _mousePosition; + + private int _replaceSelections; + private int _currentLayer; + private int _toolBarWidth = 200; + + private bool _removedTile; + + public TileEditorScreen(EditorCamera camera) + { + _camera = camera; + } + + public void Load(ContentManager content) + { + _tileSelectionScreen.Load(content); + } + + public void SetupUi(int posY) + { + var buttonWidth = _toolBarWidth - 10; + var buttonHalfWidth = _toolBarWidth / 2 - 15; + var buttonHeight = 30; + var lableHeight = 20; + var buttonQWidth = buttonWidth - 2 * 5 - buttonHeight * 2; + var dist = 5; + var bigDist = 16; + + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY, buttonWidth, buttonHeight), + Resources.EditorFont, "import tilemap", "bt1", Values.EditorUiTileEditor, null, ui => { SaveLoadMap.ImportTilemap(); })); + + posY += 11; + for (var i = 0; i < 3; i++) + { + var layer = i; + Game1.EditorUi.AddElement(new UiButton( + new Rectangle(5, posY += buttonHeight + dist, buttonQWidth, buttonHeight), Resources.EditorFont, + "layer " + layer, "bt1", Values.EditorUiTileEditor, + ui => { ((UiButton)ui).Marked = _currentLayer == layer; }, + ui => { ButtonPressedLayer(layer); })); + + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5 + buttonQWidth + dist, posY, buttonHeight, buttonHeight), + Resources.EditorFont, "", "bt1", Values.EditorUiTileEditor, null, ui => ButtonUpdate(ui, layer)) + { ButtonIcon = LayerVisibility[i] ? Resources.EditorEyeOpen : Resources.EditorEyeClosed }); + + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5 + buttonQWidth + dist * 2 + buttonHeight, posY, buttonHeight, buttonHeight), + Resources.EditorFont, "", "bt1", Values.EditorUiTileEditor, null, ui => RemoveTileContent(layer)) + { ButtonIcon = Resources.EditorIconDelete }); + } + + Game1.EditorUi.AddElement(new UiCheckBox( + new Rectangle(5, posY += buttonHeight + bigDist, buttonWidth, buttonHeight), Resources.EditorFont, + "mark selected tiles", "cb", Values.EditorUiTileEditor, false, null, + ui => { MarkSelectedTiles = ((UiCheckBox)ui).CurrentState; })); + + Game1.EditorUi.AddElement(new UiLabel(new Rectangle(5, posY += buttonHeight + bigDist, buttonHalfWidth, buttonHeight), "from:", Values.EditorUiTileEditor)); + + Game1.EditorUi.AddElement(new UiImage(null, + new Rectangle(10 + buttonHalfWidth, posY, 16 * 2, 16 * 2), + new Rectangle(0, 0, 16, 16), "from", Values.EditorUiTileEditor, Color.White, UpdateImageFrom)); + + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + bigDist, buttonWidth, buttonHeight), + Resources.EditorFont, + "change tiles", "bt1", Values.EditorUiTileEditor, null, ui => { ReplaceTiles(); })); + + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + dist, buttonWidth, buttonHeight), + Resources.EditorFont, + "create blur map", "bt1", Values.EditorUiTileEditor, null, ui => { CreateBlurMap(); })); + Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + dist, buttonWidth, buttonHeight), + Resources.EditorFont, + "create blur sides", "bt1", Values.EditorUiTileEditor, null, ui => { CreateBlurMapSides(); })); + } + + public void UpdateTileSelection(GameTime gameTime) + { + // update tile selection + _tileSelectionScreen.Update(gameTime); + } + + public void Update(GameTime gameTime) + { + Game1.EditorUi.CurrentScreen = Values.EditorUiTileEditor; + + if (TileMap.ArrayTileMap == null) + return; + + _removedTile = false; + + _mousePosition = InputHandler.MousePosition(); + + // update the tiled and the object cursor + Selection = GetTiledCursor(); + + // select the current tile + if (InputHandler.KeyPressed(Keys.Space)) + { + var selection = GetSelection(Selection); + _tileSelectionScreen.SelectedTiles = new[,] { { selection } }; + + _replaceSelections = selection; + } + if (InputHandler.KeyDown(Keys.Space)) + IsSelecting = true; + + // draw + if (!MultiSelect) + SelectionStart = Selection; + + SelectionEnd = Selection; + + // cursor outside the map? -> resize map + if (InputHandler.MouseLeftDown() && InsideEditor() && !IsInsideTileMap(Selection)) + { + ResizeMap(); + Update(gameTime); + return; + } + + if (InsideEditor() && !Drawing) + { + if (InputHandler.MouseLeftStart()) + { + DrawMode = true; + Drawing = true; + } + else if (InputHandler.MouseRightStart()) + { + DrawMode = false; + Drawing = true; + } + } + + if ((DrawMode && (InputHandler.MouseLeftDown() || InputHandler.MouseLeftReleased()) || + !DrawMode && (InputHandler.MouseRightDown() || InputHandler.MouseRightReleased())) && Drawing) + { + if ((InputHandler.KeyDown(Keys.LeftShift) || InputHandler.KeyDown(Keys.Space)) && + (DrawMode && InputHandler.MouseLeftDown() || !DrawMode && InputHandler.MouseRightDown())) + { + MultiSelect = true; + } + else + { + // no longer in multiselect + if (MultiSelect) + { + MultiSelect = false; + + if (IsSelecting) + SelectArea(); + else + FillMultiSelection(); + } + else + { + if (!IsSelecting) + FillSelection(); + } + } + } + else + { + IsSelecting = false; + MultiSelect = false; + Drawing = false; + } + + // delete the tiles that are marked + if (InputHandler.KeyPressed(Keys.Delete) && MarkSelectedTiles) + { + if (_tileSelectionScreen.SelectedTiles != null) + { + for (int z = 0; z < TileMap.ArrayTileMap.GetLength(2); z++) + for (var y = 0; y < TileMap.ArrayTileMap.GetLength(1); y++) + for (var x = 0; x < TileMap.ArrayTileMap.GetLength(0); x++) + { + if (TileMap.ArrayTileMap[x, y, z] >= 0 && + TileMap.ArrayTileMap[x, y, z] == _tileSelectionScreen.SelectedTiles[0, 0]) + TileMap.ArrayTileMap[x, y, z] = -1; + } + } + } + + if (_removedTile && CutCorners()) + Update(gameTime); + } + + public void DrawTileSelection(SpriteBatch spriteBatch) + { + // draw the tileset + _tileSelectionScreen.Draw(spriteBatch, _currentLayer == TileMap.ArrayTileMap.GetLength(2) - 1); + } + + public void Draw(SpriteBatch spriteBatch, bool drawCursor) + { + if (TileMap.ArrayTileMap == null) + return; + + // draw the visible layers of the map + for (var z = 0; z < TileMap.ArrayTileMap.GetLength(2); z++) + if (LayerVisibility[z]) + DrawLayer(spriteBatch, z); + + // draw the cursor + // only draw the cursor when the update function was called + if (drawCursor) + spriteBatch.Draw(Resources.SprWhite, + new Rectangle(Selection.X * Values.TileSize, Selection.Y * Values.TileSize, + Values.TileSize, Values.TileSize), Color.Red * 0.75f); + + // draw the selection + if (MultiSelect) + { + var left = Math.Min(SelectionStart.X, SelectionEnd.X); + var right = Math.Max(SelectionStart.X, SelectionEnd.X); + var top = Math.Min(SelectionStart.Y, SelectionEnd.Y); + var down = Math.Max(SelectionStart.Y, SelectionEnd.Y); + + spriteBatch.Draw(Resources.SprWhite, + new Rectangle( + left * Values.TileSize, + top * Values.TileSize, + (right - left + 1) * Values.TileSize, + (down - top + 1) * Values.TileSize), Color.White * 0.5f); + + // draw the preview + for (var y = top; y <= down; y++) + for (var x = left; x <= right; x++) + if (!DrawMode) + { + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + x * Values.TileSize, y * Values.TileSize, + Values.TileSize, Values.TileSize), Color.Red * 0.5f); + } + } + } + + private void DrawLayer(SpriteBatch spriteBatch, int layer) + { + // only draw the visible tiles + var startX = Math.Max(0, (int)(-_camera.Location.X / (_camera.Scale * Values.TileSize))); + var startY = Math.Max(0, (int)(-_camera.Location.Y / (_camera.Scale * Values.TileSize))); + var endX = Math.Min(TileMap.ArrayTileMap.GetLength(0), + (int)((Game1.WindowWidth - _camera.Location.X) / (_camera.Scale * Values.TileSize)) + 1); + var endY = Math.Min(TileMap.ArrayTileMap.GetLength(1), + (int)((Game1.WindowHeight - _camera.Location.Y) / (_camera.Scale * Values.TileSize)) + 1); + + // draw the tilemap + for (var y = startY; y < endY; y++) + for (var x = startX; x < endX; x++) + if (TileMap.ArrayTileMap[x, y, layer] >= 0) + { + var tileset = layer + 1 == TileMap.ArrayTileMap.GetLength(2) ? TileMap.SprTilesetBlur : TileMap.SprTileset; + spriteBatch.Draw(tileset, + new Rectangle(x * Values.TileSize, y * Values.TileSize, Values.TileSize, Values.TileSize), + new Rectangle( + TileMap.ArrayTileMap[x, y, layer] % (TileMap.SprTileset.Width / TileMap.TileSize) * TileMap.TileSize, + TileMap.ArrayTileMap[x, y, layer] / (TileMap.SprTileset.Width / TileMap.TileSize) * TileMap.TileSize, TileMap.TileSize, TileMap.TileSize), Color.White); + + if (MarkSelectedTiles && _tileSelectionScreen.SelectedTiles != null && + TileMap.ArrayTileMap[x, y, layer] == _tileSelectionScreen.SelectedTiles[0, 0]) + spriteBatch.Draw(Resources.SprWhite, + new Rectangle(x * Values.TileSize, y * Values.TileSize, + Values.TileSize, Values.TileSize), Color.Red * (float)(Math.Sin(Game1.TotalGameTime / 100f) * 0.25f + 0.5f)); + } + } + + public void DrawTop(SpriteBatch spriteBatch) + { + // draw the background + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + 0, Game1.WindowHeight - _toolBarWidth, _toolBarWidth, _toolBarWidth), Color.White * 0.25f); + + if (_tileSelectionScreen.SelectedTiles == null) + return; + + var width = _toolBarWidth - 10; + var height = _toolBarWidth - 10; + var max = MathHelper.Max(_tileSelectionScreen.SelectedTiles.GetLength(0), _tileSelectionScreen.SelectedTiles.GetLength(1)); + var tileWidth = width / max; + var tileHeight = height / max; + + var posX = width / 2 - (_tileSelectionScreen.SelectedTiles.GetLength(0) * tileWidth) / 2; + var posY = width / 2 - (_tileSelectionScreen.SelectedTiles.GetLength(1) * tileHeight) / 2; + + for (var y = 0; y < _tileSelectionScreen.SelectedTiles.GetLength(1); y++) + for (var x = 0; x < _tileSelectionScreen.SelectedTiles.GetLength(0); x++) + { + var tileset = _currentLayer + 1 == TileMap.ArrayTileMap.GetLength(2) ? TileMap.SprTilesetBlur : TileMap.SprTileset; + if (_tileSelectionScreen.SelectedTiles[x, y] >= 0) + spriteBatch.Draw(tileset, new Rectangle( + 5 + posX + x * tileWidth, Game1.WindowHeight - _toolBarWidth + posY + 5 + y * tileHeight, tileWidth, tileHeight), new Rectangle( + _tileSelectionScreen.SelectedTiles[x, y] % (TileMap.SprTileset.Width / Values.TileSize) * Values.TileSize, + _tileSelectionScreen.SelectedTiles[x, y] / (TileMap.SprTileset.Width / Values.TileSize) * Values.TileSize, + Values.TileSize, Values.TileSize), Color.White); + } + } + + private void ResizeMap() + { + var posX = 0; + var posY = 0; + var newWidth = TileMap.ArrayTileMap.GetLength(0); + var newHeight = TileMap.ArrayTileMap.GetLength(1); + + if (Selection.X < 0) + { + posX = -Selection.X; + newWidth -= Selection.X; + _camera.Location.X += (int)(Selection.X * _camera.Scale * 16); + } + else if (Selection.X >= newWidth) + { + newWidth = Selection.X + 1; + } + if (Selection.Y < 0) + { + posY = -Selection.Y; + newHeight -= Selection.Y; + _camera.Location.Y += (int)(Selection.Y * _camera.Scale * 16); + } + else if (Selection.Y >= newHeight) + { + newHeight = Selection.Y + 1; + } + + Map.ResizeMap(newWidth, newHeight, posX, posY); + } + + private bool IsInsideTileMap(Point selection) + { + return 0 <= selection.X && selection.X < TileMap.ArrayTileMap.GetLength(0) && + 0 <= selection.Y && selection.Y < TileMap.ArrayTileMap.GetLength(1); + } + + private bool InsideEditor() + { + return InputHandler.MouseIntersect(new Rectangle( + _toolBarWidth, Values.ToolBarHeight, + Game1.WindowWidth - _toolBarWidth * 2, + Game1.WindowHeight - Values.ToolBarHeight)); + } + + private int GetSelection(Point position) + { + if (IsInsideTileMap(position)) + return TileMap.ArrayTileMap[position.X, position.Y, _currentLayer]; + + return -1; + } + + private Point GetTiledCursor() + { + var position = new Point( + (int)((_mousePosition.X - _camera.Location.X) / (Values.TileSize * _camera.Scale)), + (int)((_mousePosition.Y - _camera.Location.Y) / (Values.TileSize * _camera.Scale))); + + // fix + if (_mousePosition.X - _camera.Location.X < 0) + position.X--; + if (_mousePosition.Y - _camera.Location.Y < 0) + position.Y--; + + return position; + } + + /// + /// replace a tile with a different one + /// + private void ReplaceTiles() + { + // return if no tile is select + if (_tileSelectionScreen.SelectedTiles == null || + _tileSelectionScreen.SelectedTiles.GetLength(0) <= 0 || + _tileSelectionScreen.SelectedTiles.GetLength(1) <= 0) + return; + + var toSelection = _tileSelectionScreen.SelectedTiles[0, 0]; + + for (var z = 0; z < TileMap.ArrayTileMap.GetLength(2); z++) + for (var y = 0; y < TileMap.ArrayTileMap.GetLength(1); y++) + for (var x = 0; x < TileMap.ArrayTileMap.GetLength(0); x++) + if (TileMap.ArrayTileMap[x, y, z] == _replaceSelections) + TileMap.ArrayTileMap[x, y, z] = toSelection; + } + + private void CreateBlurMap() + { + for (var y = 0; y < TileMap.ArrayTileMap.GetLength(1); y++) + for (var x = 0; x < TileMap.ArrayTileMap.GetLength(0); x++) + { + if (TileMap.ArrayTileMap[x, y, 0] == -1 && ( + TileNotEmpty(x - 1, y, 0) || TileNotEmpty(x + 1, y, 0) || TileNotEmpty(x, y - 1, 0) || TileNotEmpty(x, y + 1, 0) || + TileNotEmpty(x - 1, y - 1, 0) || TileNotEmpty(x + 1, y - 1, 0) || TileNotEmpty(x - 1, y + 1, 0) || TileNotEmpty(x + 1, y + 1, 0))) + { + TileMap.ArrayTileMap[x, y, TileMap.ArrayTileMap.GetLength(2) - 1] = 0; + } + } + } + + private void CreateBlurMapSides() + { + for (var y = 0; y < TileMap.ArrayTileMap.GetLength(1); y++) + for (var x = 0; x < TileMap.ArrayTileMap.GetLength(0); x++) + { + if (TileMap.ArrayTileMap[x, y, 0] == -1) + continue; + + if (!TileNotEmpty(x - 1, y, 0) && !TileNotEmpty(x, y - 1, 0) && TileNotEmpty(x + 1, y, 0) && TileNotEmpty(x, y + 1, 0)) + TileMap.ArrayTileMap[x, y, TileMap.ArrayTileMap.GetLength(2) - 1] = 3; + if (!TileNotEmpty(x - 1, y, 0) && TileNotEmpty(x, y - 1, 0) && TileNotEmpty(x + 1, y, 0) && !TileNotEmpty(x, y + 1, 0)) + TileMap.ArrayTileMap[x, y, TileMap.ArrayTileMap.GetLength(2) - 1] = 1; + if (TileNotEmpty(x - 1, y, 0) && !TileNotEmpty(x, y - 1, 0) && !TileNotEmpty(x + 1, y, 0) && TileNotEmpty(x, y + 1, 0)) + TileMap.ArrayTileMap[x, y, TileMap.ArrayTileMap.GetLength(2) - 1] = 4; + if (TileNotEmpty(x - 1, y, 0) && TileNotEmpty(x, y - 1, 0) && !TileNotEmpty(x + 1, y, 0) && !TileNotEmpty(x, y + 1, 0)) + TileMap.ArrayTileMap[x, y, TileMap.ArrayTileMap.GetLength(2) - 1] = 2; + } + } + + private bool TileNotEmpty(int x, int y, int z) + { + if (x < 0 || TileMap.ArrayTileMap.GetLength(0) <= x || + y < 0 || TileMap.ArrayTileMap.GetLength(1) <= y || + z < 0 || TileMap.ArrayTileMap.GetLength(2) <= z) + return false; + + return TileMap.ArrayTileMap[x, y, z] >= 0; + } + + private void SelectArea() + { + var left = Math.Min(SelectionStart.X, SelectionEnd.X); + var right = Math.Max(SelectionStart.X, SelectionEnd.X); + var top = Math.Min(SelectionStart.Y, SelectionEnd.Y); + var down = Math.Max(SelectionStart.Y, SelectionEnd.Y); + + _tileSelectionScreen.SelectedTiles = new int[right - left + 1, down - top + 1]; + + for (var y = top; y <= down; y++) + for (var x = left; x <= right; x++) + { + _tileSelectionScreen.SelectedTiles[x - left, y - top] = GetSelection(new Point(x, y)); + } + } + + private void FillMultiSelection() + { + if (_tileSelectionScreen.SelectedTiles == null) + return; + + var left = Math.Min(SelectionStart.X, SelectionEnd.X); + var right = Math.Max(SelectionStart.X, SelectionEnd.X); + var top = Math.Min(SelectionStart.Y, SelectionEnd.Y); + var down = Math.Max(SelectionStart.Y, SelectionEnd.Y); + + for (var y = top; y <= down; y++) + for (var x = left; x <= right; x++) + { + var index = DrawMode ? _tileSelectionScreen.SelectedTiles[ + (x - left) % _tileSelectionScreen.SelectedTiles.GetLength(0), + (y - top) % _tileSelectionScreen.SelectedTiles.GetLength(1)] : -1; + + // do not erase stuff in draw mode + if (DrawMode && index < 0) + continue; + + DrawTileAt(x, y, _currentLayer, index); + } + } + + private void DrawTileAt(int x, int y, int z, int index) + { + // check if the position is inside the tilemap + if (x < 0 || x >= TileMap.ArrayTileMap.GetLength(0) || + y < 0 || y >= TileMap.ArrayTileMap.GetLength(1) || + z < 0 || z >= TileMap.ArrayTileMap.GetLength(2)) + return; + + if (index < 0) + _removedTile = true; + + TileMap.ArrayTileMap[x, y, z] = index; + } + + private bool CutCorners() + { + var posX = TileMap.ArrayTileMap.GetLength(0); + var posY = TileMap.ArrayTileMap.GetLength(1); + var newWidth = 0; + var newHeight = 0; + + for (var z = 0; z < TileMap.ArrayTileMap.GetLength(2); z++) + { + for (var y = 0; y < TileMap.ArrayTileMap.GetLength(1); y++) + { + for (var x = 0; x < TileMap.ArrayTileMap.GetLength(0); x++) + { + if (TileMap.ArrayTileMap[x, y, z] >= 0) + { + if (posX > x) + posX = x; + if (newWidth < x + 1) + newWidth = x + 1; + if (posY > y) + posY = y; + if (newHeight < y + 1) + newHeight = y + 1; + } + } + } + } + + // did not change the size? + if (posX == 0 && posY == 0 && + newWidth == TileMap.ArrayTileMap.GetLength(0) && + newHeight == TileMap.ArrayTileMap.GetLength(1)) + return false; + + newWidth -= posX; + newHeight -= posY; + + Map.ResizeMap(newWidth, newHeight, -posX, -posY); + + _camera.Location.X += (int)(posX * _camera.Scale * 16); + _camera.Location.Y += (int)(posY * _camera.Scale * 16); + + return true; + } + + private void FillSelection() + { + if (DrawMode && _tileSelectionScreen.SelectedTiles != null) + { + // draw selected tiles + var left = Selection.X; + var right = Selection.X + _tileSelectionScreen.SelectedTiles.GetLength(0); + var top = SelectionEnd.Y; + var down = SelectionEnd.Y + _tileSelectionScreen.SelectedTiles.GetLength(1); + + for (var y = top; y < down; y++) + for (var x = left; x < right; x++) + // do not erase stuff in draw mode + if (_tileSelectionScreen.SelectedTiles[x - left, y - top] >= 0) + DrawTileAt(x, y, _currentLayer, _tileSelectionScreen.SelectedTiles[x - left, y - top]); + } + else if (!DrawMode) + { + // remove tile + DrawTileAt(Selection.X, Selection.Y, _currentLayer, -1); + } + } + + private void ButtonPressedLayer(int layer) + { + _currentLayer = layer; + } + + private void ButtonUpdate(UiElement ui, int layer) + { + LayerVisibility[layer] = !LayerVisibility[layer]; + ((UiButton)ui).ButtonIcon = LayerVisibility[layer] ? Resources.EditorEyeOpen : Resources.EditorEyeClosed; + } + + private void DeleteTilelayer(int layer) + { + if (layer >= TileMap.ArrayTileMap.GetLength(2) || + TileMap.ArrayTileMap.GetLength(2) <= 0) + return; + + var newTilemap = new int[ + TileMap.ArrayTileMap.GetLength(0), + TileMap.ArrayTileMap.GetLength(1), + TileMap.ArrayTileMap.GetLength(2) - 1]; + + // move the content to a new tilemap without copying the deleted layer + for (var z = 0; z < newTilemap.GetLength(2); z++) + for (var y = 0; y < newTilemap.GetLength(1); y++) + for (var x = 0; x < newTilemap.GetLength(0); x++) + { + var posZ = z == layer ? z + 1 : z; + newTilemap[x, y, posZ] = TileMap.ArrayTileMap[x, y, z]; + } + + TileMap.ArrayTileMap = newTilemap; + } + + private void RemoveTileContent(int layer) + { + if (layer >= TileMap.ArrayTileMap.GetLength(2) || + TileMap.ArrayTileMap.GetLength(2) <= 0) + return; + + for (var y = 0; y < TileMap.ArrayTileMap.GetLength(1); y++) + for (var x = 0; x < TileMap.ArrayTileMap.GetLength(0); x++) + TileMap.ArrayTileMap[x, y, layer] = -1; + } + + private void UpdateImageFrom(UiElement ui) + { + if (TileMap.SprTileset == null) return; + + if (_replaceSelections < 0) + { + ((UiImage)ui).SprImage = null; + return; + } + + ((UiImage)ui).SprImage = TileMap.SprTileset; + ((UiImage)ui).SourceRectangle = + new Rectangle( + _replaceSelections % (TileMap.SprTileset.Width / Values.TileSize) * Values.TileSize, + _replaceSelections / (TileMap.SprTileset.Width / Values.TileSize) * Values.TileSize, Values.TileSize, Values.TileSize); + } + + public void OffsetTileMap(int offsetX, int offsetY) + { + var dirY = offsetY < 0 ? 1 : -1; + var dirX = offsetX < 0 ? 1 : -1; + + for (var z = 0; z < TileMap.ArrayTileMap.GetLength(2); z++) + { + for (var y = dirY == 1 ? 0 : TileMap.ArrayTileMap.GetLength(1) - 1; + (dirY == 1 && y < TileMap.ArrayTileMap.GetLength(1)) || (dirY == -1 && y >= 0); y += dirY) + { + for (var x = dirX == 1 ? 0 : TileMap.ArrayTileMap.GetLength(0) - 1; + (dirX == 1 && x < TileMap.ArrayTileMap.GetLength(0)) || (dirX == -1 && x >= 0); x += dirX) + { + var newX = x - offsetX; + var newY = y - offsetY; + + if (0 <= newX && newX < TileMap.ArrayTileMap.GetLength(0) && + 0 <= newY && newY < TileMap.ArrayTileMap.GetLength(1)) + TileMap.ArrayTileMap[x, y, z] = TileMap.ArrayTileMap[newX, newY, z]; + else + TileMap.ArrayTileMap[x, y, z] = -1; + } + } + } + } + } +} diff --git a/Editor/TileExtractor.cs b/Editor/TileExtractor.cs new file mode 100644 index 0000000..5c1993a --- /dev/null +++ b/Editor/TileExtractor.cs @@ -0,0 +1,581 @@ +using System; +using System.Collections.Generic; +using System.IO; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.Base.UI; +using ProjectZ.InGame.Screens; +using ProjectZ.InGame.Things; + +namespace ProjectZ.Editor +{ + class TileExtractor : Screen + { + private List _sprTiled = new List(); + private List _sprTiledRemoved = new List(); + + private List _untiledParts = new List(); + private List _tiledInput; + + private RenderTarget2D _textureRenderTarget; + + private Texture2D _inputTexture; + private Texture2D _outputTexture; + private Texture2D _outputTextureRemoved; + private Texture2D _outputTextureUntiled; + + private EditorCamera _camera = new EditorCamera(); + + private Vector2 _tilesetPosition; + + private Point _distance; + private Point _tileSize = new Point(16, 16); + + private string _imageName; + + private int[,,] _tileMap; + + private int _selectedInputTile; + private int _selectedOutputTile; + private int _maxWidth = 10; + private int _toolBarWidth = 200; + + private int MaxWidth + { + get => _maxWidth; + set + { + _maxWidth = value; + _maxWidth = (int)MathHelper.Clamp(_maxWidth, 1, 100); + LoadOutput(); + } + } + + private Point Distance + { + get => _distance; + set + { + _distance = value; + _distance = new Point((int)MathHelper.Clamp(_distance.X, -TileSize.X, TileSize.X), (int)MathHelper.Clamp(_distance.Y, -TileSize.Y, TileSize.Y)); + LoadOutput(); + } + } + + private Point TileSize + { + get => _tileSize; + set + { + _tileSize = value; + TileTexture(); + LoadOutput(); + } + } + + public TileExtractor(string screenId) : base(screenId) { } + + public override void Load(ContentManager content) + { + var buttonDist = 5; + + var buttonWidth = _toolBarWidth - buttonDist * 2; + var buttonWidthHalf = _toolBarWidth / 2 - (int)(buttonDist * 1.5); + var buttonHeight = 30; + + var buttonDistY = buttonHeight + 5; + var posY = Values.ToolBarHeight + buttonDist; + + // set the init camera position + _camera.Location = new Point(_toolBarWidth + 10, Values.ToolBarHeight + 10 + 20); + + // left background bar + Game1.EditorUi.AddElement(new UiRectangle(new Rectangle(0, Values.ToolBarHeight, _toolBarWidth, 0), "left", Values.EditorUiTileExtractor, Color.Transparent, Color.Black * 0.5f, + ui => { ui.Rectangle = new Rectangle(0, Values.ToolBarHeight, _toolBarWidth, Game1.WindowHeight - Values.ToolBarHeight); })); + + Game1.EditorUi.AddElement(new UiButton(new Rectangle(buttonDist, posY, buttonWidth, buttonHeight), Resources.EditorFont, "load image", "default", Values.EditorUiTileExtractor, null, Button_LoadImage)); + Game1.EditorUi.AddElement(new UiButton(new Rectangle(buttonDist, posY += buttonDistY, buttonWidth, buttonHeight), Resources.EditorFont, "save tileSet", "default", Values.EditorUiTileExtractor, null, ButtonSaveTileset)); + Game1.EditorUi.AddElement(new UiButton(new Rectangle(buttonDist, posY += buttonDistY, buttonWidth, buttonHeight), Resources.EditorFont, "save removed", "default", Values.EditorUiTileExtractor, null, ButtonSaveRemoveTileset)); + Game1.EditorUi.AddElement(new UiButton(new Rectangle(buttonDist, posY += buttonDistY, buttonWidth, buttonHeight), Resources.EditorFont, "save .txt", "default", Values.EditorUiTileExtractor, null, ButtonSaveTilemap)); + + //Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonDistY, buttonWidth, 25), Resources.EditorFont, "reload", "default", Values.EditorUiTileExtractor, null, ui => { TileTexture(); })); + + //Game1.EditorUi.AddElement(new UiCheckBox(new Rectangle(5, posY += buttonDistY + 20, buttonWidth, 25), Resources.EditorFont, "add del txt", "checkBox", screenId, false, null, (UiElement _ui) => { addDeletedTextures = ((CheckBox)_ui).currentState; })); + //Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonDistY, buttonWidth, 25), Resources.EditorFont, "add to map", "default", screenId, null, (UiElement _ui) => { AddToMap(); })); + + //Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonDistY + 20, buttonWidth, 25), Resources.EditorFont, "remove untiled", "default", screenId, null, (UiElement _ui) => { untiledParts.Clear(); LoadOutput(); })); + + //output width + Game1.EditorUi.AddElement(new UiLabel(new Rectangle(5, posY += buttonDistY, buttonWidth, 25), Resources.EditorFont, "output width", "default", Values.EditorUiTileExtractor, null)); + Game1.EditorUi.AddElement(new UiNumberInput(new Rectangle(5, posY += buttonDistY, buttonWidth, 25), Resources.EditorFont, _maxWidth, 5, 25, 1, + "outputWidth", Values.EditorUiTileExtractor, null, ui => { MaxWidth = (int)((UiNumberInput)ui).Value; })); + + // padding + Game1.EditorUi.AddElement(new UiLabel(new Rectangle(5, posY += buttonDistY, buttonWidth, 25), Resources.EditorFont, "padding", "default", Values.EditorUiTileExtractor, null)); + Game1.EditorUi.AddElement(new UiLabel(new Rectangle(5, posY += 15, buttonWidthHalf, 25), Resources.EditorFont, "x", "default", Values.EditorUiTileExtractor, null)); + Game1.EditorUi.AddElement(new UiLabel(new Rectangle(10 + buttonWidthHalf, posY, buttonWidthHalf, 25), Resources.EditorFont, "y", "default", Values.EditorUiTileExtractor, null)); + + Game1.EditorUi.AddElement(new UiNumberInput(new Rectangle(5, posY += buttonDistY, buttonWidthHalf, 25), Resources.EditorFont, _distance.X, -10, 10, 1, + "outputWidth", Values.EditorUiTileExtractor, null, ui => { Distance = new Point((int)((UiNumberInput)ui).Value, _distance.Y); })); + Game1.EditorUi.AddElement(new UiNumberInput(new Rectangle(10 + buttonWidthHalf, posY, buttonWidthHalf, 25), Resources.EditorFont, _distance.Y, -10, 10, 1, + "outputWidth", Values.EditorUiTileExtractor, null, ui => { Distance = new Point(_distance.X, (int)((UiNumberInput)ui).Value); })); + + // tilesize + Game1.EditorUi.AddElement(new UiLabel(new Rectangle(5, posY += buttonDistY, buttonWidth, 25), Resources.EditorFont, "tile size", "default", Values.EditorUiTileExtractor, null)); + Game1.EditorUi.AddElement(new UiLabel(new Rectangle(5, posY += 15, buttonWidthHalf, 25), Resources.EditorFont, "x", "default", Values.EditorUiTileExtractor, null)); + Game1.EditorUi.AddElement(new UiLabel(new Rectangle(10 + buttonWidthHalf, posY, buttonWidthHalf, 25), Resources.EditorFont, "y", "default", Values.EditorUiTileExtractor, null)); + + Game1.EditorUi.AddElement(new UiNumberInput(new Rectangle(5, posY += buttonDistY, buttonWidthHalf, 25), Resources.EditorFont, _tileSize.X, 1, 200, 1, + "outputWidth", Values.EditorUiTileExtractor, null, ui => { TileSize = new Point((int)((UiNumberInput)ui).Value, _tileSize.Y); })); + Game1.EditorUi.AddElement(new UiNumberInput(new Rectangle(10 + buttonWidthHalf, posY, buttonWidthHalf, 25), Resources.EditorFont, _tileSize.Y, 1, 200, 1, + "outputWidth", Values.EditorUiTileExtractor, null, ui => { TileSize = new Point(_tileSize.X, (int)((UiNumberInput)ui).Value); })); + } + + public override void Update(GameTime gameTime) + { + Game1.EditorUi.CurrentScreen = Values.EditorUiTileExtractor; + + var mousePosition = InputHandler.MousePosition(); + + // update tileset scale + if (InputHandler.MouseWheelUp() && _camera.Scale < 10) + { + _camera.Scale += 0.25f; + var scale = _camera.Scale / (_camera.Scale - 0.25f); + _camera.Location.X = InputHandler.MousePosition().X - (int)((InputHandler.MousePosition().X - _camera.Location.X) * scale); + _camera.Location.Y = InputHandler.MousePosition().Y - (int)((InputHandler.MousePosition().Y - _camera.Location.Y) * scale); + } + if (InputHandler.MouseWheelDown() && _camera.Scale > 0.25f) + { + _camera.Scale -= 0.25f; + var scale = _camera.Scale / (_camera.Scale + 0.25f); + _camera.Location.X = InputHandler.MousePosition().X - (int)((InputHandler.MousePosition().X - _camera.Location.X) * scale); + _camera.Location.Y = InputHandler.MousePosition().Y - (int)((InputHandler.MousePosition().Y - _camera.Location.Y) * scale); + } + + // move the tileset + if (!InputHandler.MouseMiddleStart() && InputHandler.MouseMiddleDown()) + _camera.Location += mousePosition - InputHandler.LastMousePosition(); + + + //select a tile from the input texture + if (_inputTexture != null && + InputHandler.MouseIntersect(new Rectangle(_camera.Location.X, _camera.Location.Y, + (int)(_inputTexture.Width * _camera.Scale), (int)(_inputTexture.Height * _camera.Scale)))) + { + _selectedInputTile = (int)((mousePosition.X - _camera.Location.X) / (TileSize.X * _camera.Scale)) + + (int)((mousePosition.Y - _camera.Location.Y) / (TileSize.Y * _camera.Scale)) * (_inputTexture.Width / TileSize.X); + } + else + _selectedInputTile = -1; + + _tilesetPosition = Vector2.Zero; + + if (_inputTexture != null && _inputTexture.Width <= _inputTexture.Height) + _tilesetPosition.X += _inputTexture.Width + 15; + else if (_inputTexture != null) + _tilesetPosition.Y += _inputTexture.Height + 40; + + //select a tile from the output texture + if (_outputTexture != null && + InputHandler.MouseIntersect(new Rectangle( + _camera.Location.X + (int)(_tilesetPosition.X * _camera.Scale), + _camera.Location.Y + (int)(_tilesetPosition.Y * _camera.Scale), + (int)(_outputTexture.Width * _camera.Scale), (int)(_outputTexture.Height * _camera.Scale)))) + { + _selectedOutputTile = (int)((mousePosition.X - _camera.Location.X - (int)(_tilesetPosition.X * _camera.Scale)) / ((TileSize.X + Distance.X) * _camera.Scale)) + + (int)((mousePosition.Y - _camera.Location.Y - (int)(_tilesetPosition.Y * _camera.Scale)) / ((TileSize.Y + Distance.Y) * _camera.Scale)) * + (_outputTexture.Width / (TileSize.X + Distance.X)); + } + else + _selectedOutputTile = -1; + + // remove selected tile + if (InputHandler.MouseLeftPressed() && _selectedOutputTile >= 0 && _selectedOutputTile < _sprTiled.Count) + RemoveSelectedTile(); + + //if (InputHandler.MouseLeftStart() && selectedInputTile >= 0) + // startPosition = selectedInputTile; + //if (InputHandler.MouseLeftReleased() && startPosition >= 0 && selectedInputTile >= 0) + //{ + // int left = Math.Min(startPosition % (inputTexture.Width / tileSize.X), + // selectedInputTile % (inputTexture.Width / tileSize.X)); + // int right = Math.Max(startPosition % (inputTexture.Width / tileSize.X), + // selectedInputTile % (inputTexture.Width / tileSize.X)); + // int upper = Math.Min(startPosition / (inputTexture.Width / tileSize.X), + // selectedInputTile / (inputTexture.Width / tileSize.X)); + // int down = Math.Max(startPosition / (inputTexture.Width / tileSize.X), + // selectedInputTile / (inputTexture.Width / tileSize.X)); + + // untiledParts.Add(new Rectangle(left * tileSize.X, upper * tileSize.Y, + // (right - left + 1) * tileSize.X, (down - upper + 1) * tileSize.Y)); + + // startPosition = -1; + + // LoadOutput(); + //} + } + + public override void Draw(SpriteBatch spriteBatch) + { + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, _camera.TransformMatrix); + + //draw input + if (_inputTexture != null) + { + // draw the header + spriteBatch.DrawString(Resources.EditorFont, "input", new Vector2(0, 0 - Resources.EditorFont.MeasureString("input").Y), Color.White); + // draw the texture + spriteBatch.Draw(_inputTexture, Vector2.Zero, Color.White); + + // draw selection + if (_selectedInputTile >= 0) + Game1.SpriteBatch.Draw(Resources.SprWhite, new Rectangle( + _selectedInputTile % (_inputTexture.Width / _tileSize.X) * _tileSize.X, + _selectedInputTile / (_inputTexture.Width / _tileSize.Y) * _tileSize.Y, _tileSize.X, _tileSize.Y), Color.Red * 0.5f); + } + + //draw output as texture + if (_outputTexture != null) + { + // draw the header + spriteBatch.DrawString(Resources.EditorFont, "tileset", _tilesetPosition - new Vector2(0, Resources.EditorFont.MeasureString("A").Y), Color.White); + // draw the texture + spriteBatch.Draw(_outputTexture, _tilesetPosition, Color.White); + + // draw output selection + if (_selectedOutputTile >= 0) + { + var rectangle = new Rectangle( + (int)_tilesetPosition.X + _selectedOutputTile % (_outputTexture.Width / (_tileSize.X + _distance.X)) * (_tileSize.X + _distance.X), + (int)_tilesetPosition.Y + _selectedOutputTile / (_outputTexture.Width / (_tileSize.X + _distance.X)) * (_tileSize.Y + _distance.Y), + (_tileSize.X + _distance.X), (_tileSize.Y + _distance.Y)); + Game1.SpriteBatch.Draw(Resources.SprWhite, rectangle, new Rectangle(0, 0, 1, 1), Color.Red * 0.5f); + } + + _tilesetPosition.Y += _outputTexture.Height + 10; + } + + // draw output as texture + if (_outputTextureUntiled != null) + { + // draw the header + spriteBatch.DrawString(Resources.EditorFont, "tileset untiled", _tilesetPosition, Color.White); + _tilesetPosition.Y += Resources.EditorFont.MeasureString("A").Y; + // draw the untiled output + spriteBatch.Draw(_outputTextureUntiled, _tilesetPosition, Color.White); + _tilesetPosition.Y += _outputTextureUntiled.Height + 10; + } + + // draw removed tile texture + if (_outputTextureRemoved != null) + { + // draw the header + spriteBatch.DrawString(Resources.EditorFont, "removed", _tilesetPosition, Color.White); + _tilesetPosition.Y += Resources.EditorFont.MeasureString("A").Y; + // draw the removed tiles + spriteBatch.Draw(_outputTextureRemoved, _tilesetPosition, Color.White); + _tilesetPosition.Y += _outputTextureRemoved.Height; + } + + //draw the back darker + //Basics.DrawRectangle(new Rectangle(0, upperPos, leftPos, Values.windowSize.Height - upperPos), Color.Black * 0.25f); + + spriteBatch.End(); + } + + private void Button_LoadImage(UiElement element) + { +#if WINDOWS + System.Windows.Forms.OpenFileDialog openFileDialog = new System.Windows.Forms.OpenFileDialog(); + openFileDialog.Filter = "(*.png)|*.png"; + if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + var path = openFileDialog.FileName; + + //try to load the texture + try + { + Resources.LoadTexture(out _inputTexture, path); + + // get the file name + var info = new FileInfo(path); + _imageName = info.Name.Replace(".png", ""); + + } + catch { } + + //could not load the texture + if (_inputTexture == null) + return; + + _tileMap = TileTexture(); + + LoadOutput(); + } +#endif + } + + private int[,,] TileTexture() + { + if (_inputTexture == null) + return null; + + var tileMap = new int[_inputTexture.Width / _tileSize.X, _inputTexture.Height / _tileSize.Y, 2]; + + var colorTexture = new Color[_inputTexture.Width * _inputTexture.Height]; + _inputTexture.GetData(colorTexture); + + _sprTiledRemoved = new List(); + + _tiledInput = new List(); + _tiledInput = ExtractTiles(colorTexture, _inputTexture.Width, _inputTexture.Height, _tileSize.X, _tileSize.Y); + _tiledInput = RemoveDuplicates(_tiledInput, ref tileMap); + + _sprTiled = new List(); + for (var i = 0; i < _tiledInput.Count; i++) + { + var spr = new Texture2D(Game1.Graphics.GraphicsDevice, _tileSize.X, _tileSize.Y); + spr.SetData(_tiledInput[i]); + _sprTiled.Add(spr); + } + + return tileMap; + } + + private List ExtractTiles(Color[] colorInput, int textureWidth, int textureHeight, int sizeX, int sizeY) + { + var tiledOutput = new List(); + + for (var y = 0; y <= textureHeight - sizeY; y += sizeY) + for (var x = 0; x <= textureWidth - sizeX; x += sizeX) + { + var colorTile = new Color[sizeX * sizeY]; + + for (var height = 0; height < sizeY; height++) + for (var width = 0; width < sizeX; width++) + colorTile[width + sizeX * height] = (colorInput[x + width + (y + height) * textureWidth]); + + tiledOutput.Add(colorTile); + } + + return tiledOutput; + } + + private List RemoveDuplicates(List tileList, ref int[,,] tileMap) + { + var outputTileList = new List(); + + for (var i = 0; i < tileList.Count; i++) + { + tileMap[i % tileMap.GetLength(0), i / tileMap.GetLength(0), 0] = outputTileList.Count; + + //look if there is already one + var used = false; + for (var y = 0; y < outputTileList.Count; y++) + { + // is the tile already in the tile list + if (ColorArrayIsEqual(tileList[i], outputTileList[y])) + { + used = true; + tileMap[i % tileMap.GetLength(0), i / tileMap.GetLength(0), 0] = y; + break; + } + } + + if (!used) + outputTileList.Add(tileList[i]); + } + + return outputTileList; + } + + private bool ColorArrayIsEqual(Color[] first, Color[] second) + { + if (first.Length != second.Length) + return false; + + for (var i = 0; i < first.Length; i++) + if (first[i] != second[i]) + return false; + + return true; + } + + private void LoadOutput() + { + _outputTexture = RenderTileTexture(Game1.Graphics.GraphicsDevice, _sprTiled, _tileSize.X, _tileSize.Y, _distance); + _outputTextureRemoved = RenderTileTexture(Game1.Graphics.GraphicsDevice, _sprTiledRemoved, _tileSize.X, _tileSize.Y, _distance); + RenderUntiledTexture(Game1.Graphics.GraphicsDevice); + } + + private Texture2D RenderTileTexture(GraphicsDevice graphicDevice, List tiledInput, int tileWidth, int tileHeight, Point tilePadding) + { + try + { + var newTextureWidth = tiledInput.Count <= _maxWidth ? tiledInput.Count : _maxWidth; + var newTextureHeight = (int)Math.Ceiling((double)tiledInput.Count / (double)_maxWidth); + + var sizeWidth = (tileWidth + tilePadding.X) * newTextureWidth; + var sizeHeight = (tileHeight + tilePadding.Y) * newTextureHeight; + _textureRenderTarget = new RenderTarget2D(graphicDevice, sizeWidth, sizeHeight); + + Game1.Graphics.GraphicsDevice.SetRenderTarget(_textureRenderTarget); + Game1.Graphics.GraphicsDevice.Clear(Color.Transparent); + Game1.SpriteBatch.Begin(); + + for (int y = 0; y < newTextureHeight; y++) + for (int x = 0; x < newTextureWidth; x++) + { + if (x + newTextureWidth * y >= tiledInput.Count) + break; + + //draw the tile + Game1.SpriteBatch.Draw(tiledInput[x + y * newTextureWidth], new Vector2(x * (tileWidth + tilePadding.X), + y * (tileHeight + tilePadding.Y)), Color.White); + } + + Game1.SpriteBatch.End(); + Game1.Graphics.GraphicsDevice.SetRenderTarget(null); + + return _textureRenderTarget; + } + catch + { + return null; + } + } + + private void RenderUntiledTexture(GraphicsDevice graphicDevice) + { + if (_untiledParts == null || _untiledParts.Count <= 0) + return; + + var width = 0; + var height = 0; + + //get height + for (var i = 0; i < _untiledParts.Count; i++) + { + width += _untiledParts[i].Width; + + if (height < _untiledParts[i].Height) + height = _untiledParts[i].Height; + } + + _textureRenderTarget = new RenderTarget2D(graphicDevice, width, height); + + Game1.Graphics.GraphicsDevice.SetRenderTarget(_textureRenderTarget); + Game1.Graphics.GraphicsDevice.Clear(Color.Transparent); + Game1.SpriteBatch.Begin(); + + var pos = 0; + for (var i = 0; i < _untiledParts.Count; i++) + { + //draw the tile + Game1.SpriteBatch.Draw(_inputTexture, new Rectangle(pos, 0, _untiledParts[i].Width, _untiledParts[i].Height), _untiledParts[i], Color.White); + + pos += _untiledParts[i].Width; + } + + Game1.SpriteBatch.End(); + Game1.Graphics.GraphicsDevice.SetRenderTarget(null); + + _outputTextureUntiled = _textureRenderTarget; + } + + private void RemoveSelectedTile() + { + for (var y = 0; y < _tileMap.GetLength(1); y++) + for (var x = 0; x < _tileMap.GetLength(0); x++) + { + if (_tileMap[x, y, 0] == _selectedOutputTile) + _tileMap[x, y, 1] = _sprTiledRemoved.Count + 1; + + if (_tileMap[x, y, 0] >= _selectedOutputTile) + _tileMap[x, y, 0]--; + } + + _sprTiledRemoved.Add(_sprTiled[_selectedOutputTile]); + _sprTiled.Remove(_sprTiled[_selectedOutputTile]); + + LoadOutput(); + } + + public void ButtonSaveTileset(UiElement element) + { +#if WINDOWS + string filePath; + + var openFileDialog = new System.Windows.Forms.SaveFileDialog(); + openFileDialog.Filter = "png files (*.png)|*.png|All files (*.*)|*.*"; + openFileDialog.FileName = _imageName; + if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) + filePath = openFileDialog.FileName; + else + return; + + // save the map + var saveFile = File.Create(filePath); + _outputTexture.SaveAsPng(saveFile, _outputTexture.Width, _outputTexture.Height); + saveFile.Close(); +#endif + } + + public void ButtonSaveRemoveTileset(UiElement element) + { +#if WINDOWS + string filePath; + + var openFileDialog = new System.Windows.Forms.SaveFileDialog(); + openFileDialog.Filter = "png files (*.png)|*.png|All files (*.*)|*.*"; + openFileDialog.FileName = _imageName + "Deleted"; + if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) + filePath = openFileDialog.FileName; + else + return; + + // save the map + var saveFile = File.Create(filePath); + _outputTextureRemoved.SaveAsPng(saveFile, _outputTextureRemoved.Width, _outputTextureRemoved.Height); + saveFile.Close(); +#endif + } + + public void ButtonSaveTilemap(UiElement element) + { +#if WINDOWS + // open save dialog + var openFileDialog = new System.Windows.Forms.SaveFileDialog(); + openFileDialog.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*"; + openFileDialog.FileName = _imageName; + + if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) + SaveTilemap(openFileDialog.FileName); +#endif + } + + private void SaveTilemap(string path) + { + var writer = new StreamWriter(path); + writer.WriteLine(_tileMap.GetLength(0)); + writer.WriteLine(_tileMap.GetLength(1)); + + for (var y = 0; y < _tileMap.GetLength(1); y++) + { + var strLine = ""; + for (var x = 0; x < _tileMap.GetLength(0); x++) + { + strLine += _tileMap[x, y, 0]; + if (x < _tileMap.GetLength(0) - 1) + strLine += ","; + } + writer.WriteLine(strLine); + } + + writer.Close(); + } + } +} diff --git a/Editor/TileSelectionScreen.cs b/Editor/TileSelectionScreen.cs new file mode 100644 index 0000000..5f493cf --- /dev/null +++ b/Editor/TileSelectionScreen.cs @@ -0,0 +1,158 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.Editor +{ + internal class TileSelectionScreen + { + private readonly EditorCamera _camera = new EditorCamera(); + + private TileMap _tileMap; + public int[,] SelectedTiles; + + private string _currentMapFileName; + + private int _currentSelection; + private int _selectionEnd; + private int _selectionStart; + + private bool _selecting; + + public void Load(ContentManager content) + { + _camera.Scale = 5; + } + + public void Update(GameTime gameTime) + { + Game1.EditorUi.CurrentScreen = Values.EditorUiTileSelection; + + _tileMap = Game1.GameManager.MapManager.CurrentMap.TileMap; + + // center the tileset + if (Game1.GameManager.MapManager.CurrentMap.MapName != _currentMapFileName) + { + _currentMapFileName = Game1.GameManager.MapManager.CurrentMap.MapName; + + _camera.Location.X = (int)(Game1.WindowWidth - _tileMap.SprTileset.Width * _camera.Scale) / 2; + _camera.Location.Y = (int)(Game1.WindowHeight - _tileMap.SprTileset.Height * _camera.Scale) / 2; + } + + var mousePosition = InputHandler.MousePosition(); + + // move the tileset + if (!InputHandler.MouseMiddleStart() && InputHandler.MouseMiddleDown()) + _camera.Location += mousePosition - InputHandler.LastMousePosition(); + + // update tileset scale + if (InputHandler.MouseWheelUp()) + _camera.Zoom(1, mousePosition); + if (InputHandler.MouseWheelDown()) + _camera.Zoom(-1, mousePosition); + + // clamp the position of the tileset to stay inside the _camera.Scale + var minVisible = 48; + _camera.Location.X = (int)MathHelper.Clamp(_camera.Location.X, + -_tileMap.SprTileset.Width * _camera.Scale + minVisible * _camera.Scale, + Game1.WindowWidth - minVisible * _camera.Scale); + _camera.Location.Y = (int)MathHelper.Clamp(_camera.Location.Y, + -_tileMap.SprTileset.Height * _camera.Scale + minVisible * _camera.Scale, + Game1.WindowHeight - minVisible * _camera.Scale); + + // update currentSelection + if (InputHandler.MouseIntersect(new Rectangle( + _camera.Location.X, _camera.Location.Y, + (int)(_tileMap.SprTileset.Width * _camera.Scale), + (int)(_tileMap.SprTileset.Height * _camera.Scale)))) + { + _currentSelection = + (mousePosition.X - _camera.Location.X) / (int)(_tileMap.TileSize * _camera.Scale) % _tileMap.TileCountX + + (mousePosition.Y - _camera.Location.Y) / (int)(_tileMap.TileSize * _camera.Scale) * _tileMap.TileCountX; + + _selectionEnd = _currentSelection; + } + else + _currentSelection = -1; + + // select a tile + if (InputHandler.MouseLeftStart() && _currentSelection != -1) + { + _selecting = true; + _selectionStart = _currentSelection; + } + + if (InputHandler.MouseLeftReleased() && _selecting) + { + _selecting = false; + + // select multiple tiles + var start = Math.Min(_selectionStart, _selectionEnd); + var end = Math.Max(_selectionStart, _selectionEnd); + SelectedTiles = new int[Math.Abs( + end % _tileMap.TileCountX - start % _tileMap.TileCountX) + 1, + end / _tileMap.TileCountX - start / _tileMap.TileCountX + 1]; + + for (var y = start / _tileMap.TileCountX; y <= end / _tileMap.TileCountX; y++) + for (var x = Math.Min(start % _tileMap.TileCountX, end % _tileMap.TileCountX); + x <= Math.Max(start % _tileMap.TileCountX, end % _tileMap.TileCountX); x++) + { + SelectedTiles[ + x - Math.Min(start % _tileMap.TileCountX, end % _tileMap.TileCountX), + y - start / _tileMap.TileCountX] = x + y * _tileMap.TileCountX; + } + } + } + public void Draw(SpriteBatch spriteBatch, bool blurTileset) + { + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, _camera.TransformMatrix); + + var tileset = blurTileset ? _tileMap.SprTilesetBlur : _tileMap.SprTileset; + + // draw the tiled background + spriteBatch.Draw(Resources.SprTiledBlock, Vector2.Zero, + new Rectangle(0, 0, + (tileset.Width / _tileMap.TileSize) * 16, + (tileset.Height / _tileMap.TileSize) * 16), Color.White); + + // draw the tileset + spriteBatch.Draw(tileset, Vector2.Zero, Color.White); + + // draw the current selection + if (_currentSelection >= 0) + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + _currentSelection % _tileMap.TileCountX * _tileMap.TileSize, + _currentSelection / _tileMap.TileCountX * _tileMap.TileSize, + _tileMap.TileSize, _tileMap.TileSize), Color.White * 0.5f); + + // draw the selection + if (SelectedTiles != null) + { + for (var y = 0; y < SelectedTiles.GetLength(1); y++) + for (var x = 0; x < SelectedTiles.GetLength(0); x++) + { + if (SelectedTiles[x, y] >= 0) + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + (SelectedTiles[x, y] % _tileMap.TileCountX) * _tileMap.TileSize, + (SelectedTiles[x, y] / _tileMap.TileCountX) * _tileMap.TileSize, + _tileMap.TileSize, _tileMap.TileSize), Color.Red * 0.5f); + } + } + + if (_selecting) + { + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + Math.Min(_selectionStart % _tileMap.TileCountX, _selectionEnd % _tileMap.TileCountX) * _tileMap.TileSize, + Math.Min(_selectionStart / _tileMap.TileCountX, _selectionEnd / _tileMap.TileCountX) * _tileMap.TileSize, + (Math.Abs(_selectionStart % _tileMap.TileCountX - _selectionEnd % _tileMap.TileCountX) + 1) * _tileMap.TileSize, + (Math.Abs(_selectionStart / _tileMap.TileCountX - _selectionEnd / _tileMap.TileCountX) + 1) * _tileMap.TileSize), Color.PaleVioletRed * 0.5f); + } + + spriteBatch.End(); + } + } +} diff --git a/Editor/TilesetEdit.cs b/Editor/TilesetEdit.cs new file mode 100644 index 0000000..c26d418 --- /dev/null +++ b/Editor/TilesetEdit.cs @@ -0,0 +1,478 @@ +using System; +using System.Collections.Generic; +using System.IO; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.Base.UI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +#if WINDOWS +using System.Windows.Forms; +#endif + +namespace ProjectZ.Editor +{ + internal class TilesetEdit : InGame.Screens.Screen + { + private class MapData + { + public string FilePath; + public Map Map; + } + + private class Tile : IComparable + { + public Texture2D SprTile; + public Color[] Data; + public uint Value; + + // needed for mapping after sorting the tile list + public int Position; + + public int CompareTo(Tile other) => (int)(other.Value - Value); + } + + private readonly List _loadedMaps = new List(); + private readonly List _tileSetData = new List(); + private readonly EditorCamera _camera = new EditorCamera(); + + private RenderTarget2D _renderTarget; + + private int _toolBarWidth = 200; + private int _currentSelection; + private int _selctionEnd; + private int _tileSize = 16; + + private int _selectionStart; + public int[,] SelectedTiles; + + private bool _selecting; + private int _outputWidth = 15; + private int _outputHeight; + + public TilesetEdit(string screenId) : base(screenId) { } + + public override void Load(ContentManager content) + { + var buttonDist = 5; + var buttonWidth = _toolBarWidth - buttonDist * 2; + var buttonWidthHalf = _toolBarWidth - buttonDist * 3; + var buttonHeight = 30; + var posY = Values.ToolBarHeight + buttonDist; + + Game1.EditorUi.AddElement(new UiRectangle(new Rectangle(0, Values.ToolBarHeight, _toolBarWidth, 0), "left", Values.EditorUiTilesetEditor, Color.Transparent, Color.Black * 0.5f, + ui => { ui.Rectangle = new Rectangle(0, Values.ToolBarHeight, _toolBarWidth, Game1.WindowHeight - Values.ToolBarHeight); })); + + Game1.EditorUi.AddElement(new UiButton(new Rectangle(buttonDist, posY, buttonWidth, buttonHeight), Resources.EditorFont, + "add map", "bt1", Values.EditorUiTilesetEditor, null, ui => { LoadMaps(); })); + + Game1.EditorUi.AddElement(new UiButton(new Rectangle(buttonDist, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight), Resources.EditorFont, + "save", "bt1", Values.EditorUiTilesetEditor, null, ui => { SaveChanges(); })); + + Game1.EditorUi.AddElement(new UiButton(new Rectangle(buttonDist, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight), Resources.EditorFont, + "remove all", "bt1", Values.EditorUiTilesetEditor, null, ui => { RemoveAll(); })); + + _camera.Location = new Point(400, 250); + } + + public override void Update(GameTime gameTime) + { + Game1.EditorUi.CurrentScreen = Values.EditorUiTilesetEditor; + + var position = InputHandler.MousePosition(); + + // update tileset scale + if (InputHandler.MouseWheelUp() && _camera.Scale < 10) + { + _camera.Scale += 0.25f; + var scale = _camera.Scale / (_camera.Scale - 0.25f); + _camera.Location.X = InputHandler.MousePosition().X - (int)((InputHandler.MousePosition().X - _camera.Location.X) * scale); + _camera.Location.Y = InputHandler.MousePosition().Y - (int)((InputHandler.MousePosition().Y - _camera.Location.Y) * scale); + } + if (InputHandler.MouseWheelDown() && _camera.Scale > 0.25f) + { + _camera.Scale -= 0.25f; + var scale = _camera.Scale / (_camera.Scale + 0.25f); + _camera.Location.X = InputHandler.MousePosition().X - (int)((InputHandler.MousePosition().X - _camera.Location.X) * scale); + _camera.Location.Y = InputHandler.MousePosition().Y - (int)((InputHandler.MousePosition().Y - _camera.Location.Y) * scale); + } + + // move the tileset + if (!InputHandler.MouseMiddleStart() && InputHandler.MouseMiddleDown()) + _camera.Location += position - InputHandler.LastMousePosition(); + + // update currentSelection + if (InputHandler.MouseIntersect(new Rectangle(_camera.Location.X, _camera.Location.Y, + (int)(_outputWidth * _tileSize * _camera.Scale), + (int)(_outputHeight * _tileSize * _camera.Scale)))) + { + _currentSelection = + ((position.X - _camera.Location.X) / (int)(_tileSize * _camera.Scale)) % _outputWidth + + ((position.Y - _camera.Location.Y) / (int)(_tileSize * _camera.Scale)) * _outputWidth; + _selctionEnd = _currentSelection; + + if (_currentSelection >= _tileSetData.Count) + _currentSelection = -1; + } + else + _currentSelection = -1; + + //if (InputHandler.MouseRightStart() && currentSelection != -1) + //{ + // selectionStart = currentSelection; + //} + + //if (InputHandler.MouseRightPressed()) + //{ + // if (_currentSelection != -1) + // { + // for (var y = 0; y < SelectedTiles.GetLength(1); y++) + // { + // for (var x = 0; x < SelectedTiles.GetLength(0); x++) + // { + // var pos = SelectedTiles[x, y]; + // var dir = pos - SelectedTiles[0, 0] + _currentSelection; + + // var temp = _tiles[pos]; + // _tiles[pos] = _tiles[dir]; + // _tiles[dir] = temp; + + // // UpdatePosition(pos, dir); + // } + // } + // } + //} + + //// select a tile + //if (InputHandler.MouseLeftStart() && _currentSelection != -1) + //{ + // _selecting = true; + // _selectionStart = _currentSelection; + //} + //if (InputHandler.MouseLeftReleased() && _selecting) + //{ + // _selecting = false; + + // // select multiple tiles + // var start = Math.Min(_selectionStart, _selctionEnd); + // var end = Math.Max(_selectionStart, _selctionEnd); + // SelectedTiles = new int[Math.Abs(end % _world.TileMap.TileCountX - start % _world.TileMap.TileCountX) + 1, + // end / _world.TileMap.TileCountX - start / _world.TileMap.TileCountX + 1]; + + // for (var y = start / _world.TileMap.TileCountX; y <= end / _world.TileMap.TileCountX; y++) + // for (var x = Math.Min(start % _world.TileMap.TileCountX, end % _world.TileMap.TileCountX); + // x <= Math.Max(start % _world.TileMap.TileCountX, end % _world.TileMap.TileCountX); x++) + // { + // SelectedTiles[x - Math.Min(start % _world.TileMap.TileCountX, end % _world.TileMap.TileCountX), + // y - start / _world.TileMap.TileCountX] = x + y * _world.TileMap.TileCountX; + // } + //} + } + + public override void Draw(SpriteBatch spriteBatch) + { + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, _camera.TransformMatrix); + + // draw the tiled background + spriteBatch.Draw(Resources.SprTiledBlock, new Rectangle(0, 0, + _outputWidth * _tileSize, _outputHeight * _tileSize), + new Rectangle(0, 0, + (_outputWidth * _tileSize) / _tileSize * 2, + (_outputHeight * _tileSize) / _tileSize * 2), Color.White); + + // draw the tileset + //spriteBatch.Draw(Resources.sprTileset, new Rectangle(drawPosition.X, drawPosition.Y, (int)(Resources.sprTileset.Width * drawScale), (int)(Resources.sprTileset.Height * drawScale)), Color.White); + + // draw all the tiles + for (var i = 0; i < _tileSetData.Count; i++) + spriteBatch.Draw(_tileSetData[i].SprTile, new Rectangle( + i % _outputWidth * _tileSize, i / _outputWidth * _tileSize, + _tileSetData[i].SprTile.Width, _tileSetData[i].SprTile.Height), Color.White); + + // draw the current selection + if (_currentSelection >= 0) + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + _currentSelection % _outputWidth * _tileSize, + _currentSelection / _outputWidth * _tileSize, + _tileSize, _tileSize), Color.Red * 0.5f); + + + // draw all the loaded tilemap + var posY = 0; + foreach (var map in _loadedMaps) + { + var tileMap = map.Map.TileMap; + + for (var z = 0; z < tileMap.ArrayTileMap.GetLength(2) - (tileMap.BlurLayer ? 1 : 0); z++) + for (var y = 0; y < tileMap.ArrayTileMap.GetLength(1); y++) + for (var x = 0; x < tileMap.ArrayTileMap.GetLength(0); x++) + if (tileMap.ArrayTileMap[x, y, z] >= 0) + spriteBatch.Draw(_tileSetData[tileMap.ArrayTileMap[x, y, z]].SprTile, + new Vector2(x * _tileSize + _outputWidth * 16 + 8, posY + y * _tileSize), Color.White); + + posY += tileMap.ArrayTileMap.GetLength(1) * 16 + 8; + } + //// draw the selection + //if (SelectedTiles != null) + //{ + // for (var y = 0; y < SelectedTiles.GetLength(1); y++) + // for (var x = 0; x < SelectedTiles.GetLength(0); x++) + // { + // spriteBatch.Draw(Resources.SprWhite, new Rectangle(_drawPosition.X + (SelectedTiles[x, y] % _world.TileMap.TileCountX) * (int)(_tileSize * _drawScale), + // _drawPosition.Y + (SelectedTiles[x, y] / _world.TileMap.TileCountX) * (int)(_tileSize * _drawScale), + // (int)(_tileSize * _drawScale), (int)(_tileSize * _drawScale)), Color.Red * 0.5f); + // } + //} + + //if (_selecting) + //{ + // var start = Math.Min(_selectionStart, _selctionEnd); + // var end = Math.Max(_selectionStart, _selctionEnd); + + // spriteBatch.Draw(Resources.SprWhite, new Rectangle( + // _drawPosition.X + Math.Min(_selectionStart % _world.TileMap.TileCountX, _selctionEnd % _world.TileMap.TileCountX) * (int)(_tileSize * _drawScale), + // _drawPosition.Y + Math.Min(_selectionStart / _world.TileMap.TileCountX, _selctionEnd / _world.TileMap.TileCountX) * (int)(_tileSize * _drawScale), + // (Math.Abs(_selectionStart % _world.TileMap.TileCountX - _selctionEnd % _world.TileMap.TileCountX) + 1) * (int)(_tileSize * _drawScale), + // (Math.Abs(_selectionStart / _world.TileMap.TileCountX - _selctionEnd / _world.TileMap.TileCountX) + 1) * (int)(_tileSize * _drawScale)), Color.PaleVioletRed * 0.5f); + //} + + spriteBatch.End(); + } + + public void RemoveAll() + { + _loadedMaps.Clear(); + _tileSetData.Clear(); + } + + public void LoadMaps() + { +#if WINDOWS + var openFileDialog = new OpenFileDialog + { + Filter = "Map file (*.map)|*.map", + Multiselect = true + }; + + if (openFileDialog.ShowDialog() != DialogResult.OK) return; + + // add the selected maps + foreach (var fileName in openFileDialog.FileNames) + AddMap(fileName); + + _outputHeight = (int)Math.Ceiling(_tileSetData.Count / (float)_outputWidth); + + // sort the tiles + _tileSetData.Sort(); + + RemapTiles(); +#endif + } + + public void SaveChanges() + { +#if WINDOWS + var saveFileDialog = new SaveFileDialog() + { + Filter = "Map file (*.png)|*.png" + }; + + if (saveFileDialog.ShowDialog() != DialogResult.OK) return; + + var filePath = saveFileDialog.FileName; + var fileName = Path.GetFileName(filePath); + + // save the tileset + SaveTileset(saveFileDialog.FileName); + + // save the changes to the map + foreach (var map in _loadedMaps) + { + // set the path of the new tileset + map.Map.TileMap.TilesetPath = fileName; + // save the map to the original path + SaveLoadMap.SaveMapFile(map.FilePath, map.Map); + } +#endif + } + + public void SaveTileset(string path) + { + _renderTarget = new RenderTarget2D(Game1.Graphics.GraphicsDevice, _outputWidth * _tileSize, _outputHeight * _tileSize); + + Game1.Graphics.GraphicsDevice.SetRenderTarget(_renderTarget); + Game1.Graphics.GraphicsDevice.Clear(Color.Transparent); + Game1.SpriteBatch.Begin(); + + for (var i = 0; i < _tileSetData.Count; i++) + Game1.SpriteBatch.Draw(_tileSetData[i].SprTile, new Rectangle( + i % _outputWidth * _tileSize, i / _outputWidth * _tileSize, + _tileSetData[i].SprTile.Width, _tileSetData[i].SprTile.Height), Color.White); + + Game1.SpriteBatch.End(); + Game1.Graphics.GraphicsDevice.SetRenderTarget(null); + + using Stream stream = File.Create(path); + _renderTarget.SaveAsPng(stream, _renderTarget.Width, _renderTarget.Height); + } + + public void RemapTiles() + { + var tileMapping = new int[_tileSetData.Count]; + + for (var i = 0; i < _tileSetData.Count; i++) + tileMapping[_tileSetData[i].Position] = i; + + // map all tiles to the new order + foreach (var maps in _loadedMaps) + { + var tileMap = maps.Map.TileMap; + MapTileArray(tileMap, tileMapping); + } + + // reset the tile position + for (var i = 0; i < _tileSetData.Count; i++) + _tileSetData[i].Position = i; + } + + public void AddMap(string strPath) + { + var map = new Map(); + + SaveLoadMap.LoadMapFile(strPath, map); + + var mapData = new MapData() { FilePath = strPath, Map = map }; + + // get the Color[] data of each tile + var tiles = SplitTileset(map.TileMap.SprTileset); + var tileMapping = new int[tiles.Count]; + + // add the tiles + for (var i = 0; i < tiles.Count; i++) + { + // remove tile if it is not used in the image + if (IsTileUsed(map.TileMap, i)) + tileMapping[i] = AddTexture(tiles[i]); + } + + // map the tiles from the tilemap to the tiles of the output tileset + MapTileArray(map.TileMap, tileMapping); + + _loadedMaps.Add(mapData); + } + + private bool IsTileUsed(TileMap tileMap, int index) + { + for (var z = 0; z < tileMap.ArrayTileMap.GetLength(2) - (tileMap.BlurLayer ? 1 : 0); z++) + for (var y = 0; y < tileMap.ArrayTileMap.GetLength(1); y++) + for (var x = 0; x < tileMap.ArrayTileMap.GetLength(0); x++) + if (tileMap.ArrayTileMap[x, y, z] == index) + return true; + + return false; + } + + public void MapTileArray(TileMap tileMap, int[] mapping) + { + for (var z = 0; z < tileMap.ArrayTileMap.GetLength(2) - (tileMap.BlurLayer ? 1 : 0); z++) + for (var y = 0; y < tileMap.ArrayTileMap.GetLength(1); y++) + for (var x = 0; x < tileMap.ArrayTileMap.GetLength(0); x++) + if (tileMap.ArrayTileMap[x, y, z] >= 0) + tileMap.ArrayTileMap[x, y, z] = mapping[tileMap.ArrayTileMap[x, y, z]]; + } + + public List SplitTileset(Texture2D sprTexture) + { + var colorData = new Color[sprTexture.Width * sprTexture.Height]; + sprTexture.GetData(colorData); + + var tileDataList = new List(); + + for (var y = 0; y < sprTexture.Height / _tileSize; y++) + for (var x = 0; x < sprTexture.Width / _tileSize; x++) + { + var data = new Color[_tileSize * _tileSize]; + + for (var iy = 0; iy < _tileSize; iy++) + { + for (var ix = 0; ix < _tileSize; ix++) + { + data[ix + iy * _tileSize] = colorData[y * _tileSize * sprTexture.Width + x * _tileSize + ix + iy * sprTexture.Width]; + } + } + + tileDataList.Add(data); + } + + return tileDataList; + } + + /// + /// returns the index of the tile inside the new tileset + /// + /// + /// + public int AddTexture(Color[] data) + { + var texture = new Texture2D(Game1.Graphics.GraphicsDevice, _tileSize, _tileSize); + + // check if the tile is already in use + for (var i = 0; i < _tileSetData.Count; i++) + if (ColorEquals(_tileSetData[i].Data, data)) + return i; + + uint r = 0; + uint g = 0; + uint b = 0; + uint a = 0; + + foreach (var color in data) + { + r += color.R; + g += color.G; + b += color.B; + a += color.A; + } + + // only works when the tiles are 16x16 + uint max = 255 * 16 * 16; + uint value = + ((uint)(r / (float)max * 256) << 0) + + ((uint)(g / (float)max * 256) << 8) + + ((uint)(b / (float)max * 256) << 16) + + ((uint)(a / (float)max * 256) << 24); + + texture.SetData(data); + _tileSetData.Add(new Tile { Data = data, SprTile = texture, Value = value, Position = _tileSetData.Count }); + + return _tileSetData.Count - 1; + } + + public bool ColorEquals(Color[] first, Color[] second) + { + if (first.Length != second.Length) + return false; + + for (var i = 0; i < first.Length; i++) + { + var diff = ColorDiff(first[i], second[i]); + // why is this 30 and not 0? + if (diff > 30) + return false; + } + + return true; + } + + public int ColorDiff(Color first, Color second) + { + return Math.Abs(first.R - second.R) + + Math.Abs(first.G - second.G) + + Math.Abs(first.B - second.B) + + Math.Abs(first.A - second.A); + } + } +} diff --git a/Game1.cs b/Game1.cs new file mode 100644 index 0000000..d08eaaf --- /dev/null +++ b/Game1.cs @@ -0,0 +1,965 @@ +using System; +using System.Threading; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using ProjectZ.Base; +using ProjectZ.Base.UI; +using ProjectZ.Editor; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.GameObjects; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Pages; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Screens; +using ProjectZ.InGame.Things; + +#if WINDOWS +using Forms = System.Windows.Forms; +#endif + +#if DEBUG +using ProjectZ.InGame.Tests; +#endif + +namespace ProjectZ +{ + public class Game1 : Game + { + public static GraphicsDeviceManager Graphics; + public static SpriteBatch SpriteBatch; + + public static UiManager EditorUi = new UiManager(); + public static ScreenManager ScreenManager = new ScreenManager(); + public static PageManager UiPageManager = new PageManager(); + public static GameManager GameManager = new GameManager(); + public static Language LanguageManager = new Language(); + + public static GbsPlayer.GbsPlayer GbsPlayer = new GbsPlayer.GbsPlayer(); + + public static StopWatchTracker StopWatchTracker = new StopWatchTracker(120); + public static Random RandomNumber = new Random(); + public static RenderTarget2D MainRenderTarget; + + public static Matrix GetMatrix => Matrix.CreateScale(new Vector3( + (float)Graphics.PreferredBackBufferWidth / WindowWidth, + (float)Graphics.PreferredBackBufferHeight / WindowHeight, 0)); + + private static float gameScale; + private static float gameScaleStart; + + public static float GameScaleChange => gameScale / gameScaleStart; + + public static string DebugText; + + public static float TimeMultiplier; + public static float DeltaTime; + public static double TotalTime; + + public static double TotalGameTime; + public static double TotalGameTimeLast; + + public static float DebugTimeScale = 1.0f; + + public static int WindowWidth; + public static int WindowHeight; + public static int WindowWidthEnd; + public static int WindowHeightEnd; + public static int ScreenScale; + public static int UiScale; + public static int UiRtScale; + + public static int RenderWidth; + public static int RenderHeight; + + public static bool ScaleSettingChanged; + + private bool _wasMinimized; + private static DoubleAverage _avgTotalMs = new DoubleAverage(30); + private static DoubleAverage _avgTimeMult = new DoubleAverage(30); + public static int DebugLightMode; + public static int DebugBoxMode; + public static bool DebugMode; + public static bool ShowDebugText; + + public static double FreezeTime; + + public static bool WasActive; + public static bool UpdateGame; + public static bool ForceDialogUpdate; + public static bool FpsSettingChanged; + public static bool DebugStepper; + public static bool EditorMode; + +#if WINDOWS + private static Forms.Form _windowForm; + private static Forms.FormWindowState _lastWindowState; +#endif + + private static System.Drawing.Rectangle _lastWindowBounds; + private static System.Drawing.Rectangle _lastWindowRestoreBounds; + private static int _lastWindowWidth; + private static int _lastWindowHeight; + private static bool _isFullscreen; + private bool _isResizing; + + private static RenderTarget2D _renderTarget1; + private static RenderTarget2D _renderTarget2; + + private float _blurValue = 0.2f; + + private readonly SimpleFps _fpsCounter = new SimpleFps(); + private Vector2 _debugTextSize; + + private string _lastGameScreen = Values.ScreenNameGame; + private string _lastEditorScreen = Values.ScreenNameEditor; + + private string _debugLog; + + private int _currentFrameTimeIndex; + private double[] _debugFrameTimes = + { + 1000 / 30.0, + 1000 / 60.0, + 1000 / 90.0, + 1000 / 120.0, + 1000 / 144.0, + 1000 / 288.0, + 1 + }; + + private string _consoleLine; + private bool _stopConsoleThread; + + private static bool _finishedLoading; + private static bool _initRenderTargets; + public static bool FinishedLoading => _finishedLoading; + public static bool LoadFirstSave; + +#if DEBUG + private MapTest _mapTest; + private SequenceTester _sequenceTester; + private DialogTester _dialogTester; +#endif + + public Game1(bool editorMode, bool loadFirstSave) + { +#if WINDOWS + _windowForm = (Forms.Form)Forms.Control.FromHandle(Window.Handle); + _windowForm.Icon = Properties.Resources.Icon; + + // set the min size of the game + // not sure why you can not simply set the min size of the client size directly... + var deltaWidth = _windowForm.Width - _windowForm.ClientSize.Width; + var deltaHeight = _windowForm.Height - _windowForm.ClientSize.Height; + _windowForm.MinimumSize = new System.Drawing.Size(Values.MinWidth + deltaWidth, Values.MinHeight + deltaHeight); +#endif + + Graphics = new GraphicsDeviceManager(this); + Content.RootDirectory = "Content"; + + Graphics.GraphicsProfile = GraphicsProfile.HiDef; + Graphics.PreferredBackBufferWidth = 1500; + Graphics.PreferredBackBufferHeight = 1000; + +#if MACOSX + Window.ClientSizeChanged += ClientSizeChanged; +#endif + + Window.AllowUserResizing = true; + IsMouseVisible = editorMode; + + EditorMode = editorMode; + LoadFirstSave = loadFirstSave; + + var thread = new Thread(ConsoleReaderThread); + thread.Start(); + } + + private void ClientSizeChanged(object sender, EventArgs e) + { + OnResize(); + Graphics.PreferredBackBufferWidth = Window.ClientBounds.Width; + Graphics.PreferredBackBufferHeight = Window.ClientBounds.Height; + } + + private void ConsoleReaderThread() + { + while (true) + { + if (_stopConsoleThread) + return; + + if (Console.In.Peek() != -1) + _consoleLine = Console.ReadLine(); + + Thread.Sleep(20); + } + } + + protected override void OnExiting(object sender, EventArgs args) + { + _stopConsoleThread = true; + GbsPlayer.OnExit(); + + base.OnExiting(sender, args); + } + + protected override void LoadContent() + { +#if MACOSX + // not sure how to copy the files in the correct directory... + Content.RootDirectory += "/bin/MacOSX"; +#endif + + // load game settings + SettingsSaveLoad.LoadSettings(); + + // init gbs player; load gbs file + GbsPlayer.LoadFile(Values.PathContentFolder + "Music/awakening.gbs"); + GbsPlayer.StartThread(); + + // start loading the resources that are needed after the intro + ThreadPool.QueueUserWorkItem(LoadContentThreaded); + + // Create a new SpriteBatch, which can be used to draw textures. + SpriteBatch = new SpriteBatch(GraphicsDevice); + + // Input Handler + Components.Add(new InputHandler(this)); + + // game control stuff + ControlHandler.Initialize(); + + // load the intro screen + the resources needed for it + Resources.LoadIntro(Graphics.GraphicsDevice, Content); + ScreenManager.LoadIntro(Content); + + // toggle fullscreen + if (GameSettings.IsFullscreen) + { + GameSettings.IsFullscreen = false; + ToggleFullscreen(); + } + + // set the fps settings of the game + UpdateFpsSettings(); + +#if WINDOWS + _windowForm.ResizeBegin += OnResizeBegin; + _windowForm.Resize += OnResize; + _windowForm.ResizeEnd += OnResizeEnd; +#endif + +#if DEBUG + SaveCondition.TestCondition(); + _mapTest = new MapTest(); + _sequenceTester = new SequenceTester(); +#endif + } + + private void LoadContentThreaded(Object obj) + { + // load resources + Resources.LoadTextures(Graphics.GraphicsDevice, Content); + Resources.LoadSounds(Content); + + GameManager.Load(Content); + + GameObjectTemplates.SetUpGameObjects(); + + ScreenManager.Load(Content); + + // load the language files + LanguageManager.Load(); + + UiPageManager.Load(); + + if (EditorMode) + SetUpEditorUi(); + +#if DEBUG + _dialogTester = new DialogTester(); +#endif + + _finishedLoading = true; + } + + private void UpdateConsoleInput() + { + if (_consoleLine == null) + return; + + // open file in map editor + if (_consoleLine.Contains(".map")) + { + SaveLoadMap.EditorLoadMap(_consoleLine, Game1.GameManager.MapManager.CurrentMap); + } + // open file in animation editor + else if (_consoleLine.Contains(".ani")) + { + var animationScreen = (AnimationScreen)ScreenManager.GetScreen(Values.ScreenNameEditorAnimation); + animationScreen.EditorLoadAnimation(_consoleLine); + } + // open file in sprite atlas editor + else if (_consoleLine.Contains(".png")) + { + var spriteAtlasScreen = (SpriteAtlasScreen)ScreenManager.GetScreen(Values.ScreenNameSpriteAtlasEditor); + spriteAtlasScreen.LoadSpriteEditor(_consoleLine); + } + + _consoleLine = null; + } + + protected override void Update(GameTime gameTime) + { + WasActive = IsActive; + + // mute the music if the window is not focused + //if (!IsActive) + // GbsPlayer.SetVolumeMultiplier(0); + //else + // GbsPlayer.SetVolumeMultiplier(1); + + UpdateConsoleInput(); + + // SetTransparency _fpsCounter counter + _fpsCounter.Update(gameTime); + + // toggle fullscreen + if (InputHandler.KeyDown(Keys.LeftAlt) && InputHandler.KeyPressed(Keys.Enter)) + { + ToggleFullscreen(); + InputHandler.ResetInputState(); + SettingsSaveLoad.SaveSettings(); + } + + if(_finishedLoading && !_initRenderTargets) + { + _initRenderTargets = true; + + // @HACK to update the rendertargets + WindowWidth = 0; + WindowHeightEnd = 0; + } + + // check if the window is resized + if (WindowWidth != Window.ClientBounds.Width || + WindowHeight != Window.ClientBounds.Height) + OnResize(); + + UpdateRenderTargets(); + + if (FpsSettingChanged) + { + UpdateFpsSettings(); + FpsSettingChanged = false; + } + + if (ScaleSettingChanged) + { + ScaleSettingChanged = false; + OnUpdateScale(); + } + + ControlHandler.Update(); + + if (EditorMode && InputHandler.KeyPressed(Values.DebugToggleDebugText)) + ShowDebugText = !ShowDebugText; + + if (!DebugStepper) + { + TimeMultiplier = gameTime.ElapsedGameTime.Ticks / 166667f * DebugTimeScale; + TotalGameTimeLast = TotalGameTime; + + // limit the game time so that it slows down if the steps are bigger than they would be for 30fps + // if the timesteps get too big it would be hard (wast of time) to make the logic still function 100% correctly + if (TimeMultiplier > 2.0f) + { + TimeMultiplier = 2.0f; + DeltaTime = (TimeMultiplier * 1000.0f) / 60.0f; + TotalTime += (TimeMultiplier * 1000.0) / 60.0; + DebugText += "\nLow Framerate"; + + if (UpdateGame) + TotalGameTime += (TimeMultiplier * 1000.0) / 60.0; + } + else + { + DeltaTime = (float)gameTime.ElapsedGameTime.TotalMilliseconds * DebugTimeScale; + TotalTime += gameTime.ElapsedGameTime.TotalMilliseconds * DebugTimeScale; + if (UpdateGame) + TotalGameTime += gameTime.ElapsedGameTime.TotalMilliseconds * DebugTimeScale; + } + } + + if (_finishedLoading) + { + + if (EditorMode) + { + // update the ui + // need to be at the first place to be able to block input from the screen + EditorUi.Update(); + + EditorUpdate(gameTime); + } + + EditorUi.CurrentScreen = ""; + + // update the game ui + UiPageManager.Update(gameTime); + } + +#if DEBUG + _mapTest.Update(); + _sequenceTester.Update(); + if (_finishedLoading) + _dialogTester.Update(); +#endif + + // update the screen manager + UpdateGame = true; + if (!DebugStepper || InputHandler.KeyPressed(Keys.M)) + ScreenManager.Update(gameTime); + + if (_finishedLoading) + { + DebugText += _fpsCounter.Msg; + + _avgTotalMs.AddValue(gameTime.ElapsedGameTime.TotalMilliseconds); + _avgTimeMult.AddValue(TimeMultiplier); + DebugText += $"\ntotal ms: {_avgTotalMs.Average,6:N3}" + + $"\ntime mult: {_avgTimeMult.Average,6:N3}" + + $"\ntime scale: {DebugTimeScale}" + + $"\ntime: {TotalGameTime}"; + + DebugText += "\nHistory Enabled: " + GameManager.SaveManager.HistoryEnabled + "\n"; + } + + base.Update(gameTime); + } + + protected override void Draw(GameTime gameTime) + { + if (!_finishedLoading) + { + ScreenManager.Draw(SpriteBatch); + return; + } + + _fpsCounter.CountDraw(); + + ScreenManager.DrawRT(SpriteBatch); + + Graphics.GraphicsDevice.SetRenderTarget(MainRenderTarget); + GraphicsDevice.Clear(Color.CadetBlue); + + // draw the current screen + ScreenManager.Draw(SpriteBatch); + + BlurImage(); + + { + Graphics.GraphicsDevice.SetRenderTarget(null); + + SpriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap); + + //draw the original image + SpriteBatch.Draw(MainRenderTarget, new Rectangle(0, 0, MainRenderTarget.Width, MainRenderTarget.Height), Color.White); + + SpriteBatch.End(); + } + + { + Resources.BlurEffect.Parameters["sprBlur"].SetValue(_renderTarget2); + Resources.RoundedCornerBlurEffect.Parameters["sprBlur"].SetValue(_renderTarget2); + + SpriteBatch.Begin(SpriteSortMode.Immediate, null, SamplerState.AnisotropicClamp, null, null, Resources.RoundedCornerBlurEffect, GetMatrix); + + // blurred ui parts + EditorUi.DrawBlur(SpriteBatch); + + // blured stuff + GameManager.InGameOverlay.InGameHud.DrawBlur(SpriteBatch); + + // background for the debug text + DebugTextBackground(); + + SpriteBatch.End(); + } + + { + // draw the top part + SpriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, GetMatrix); + + // draw the ui part + EditorUi.Draw(SpriteBatch); + + // draw the game ui + UiPageManager.Draw(SpriteBatch); + + // draw the screen tops + ScreenManager.DrawTop(SpriteBatch); + + // draw the debug text + DrawDebugText(); + DebugText = ""; + +#if DEBUG + if (GameManager.SaveManager.HistoryEnabled) + SpriteBatch.Draw(Resources.SprWhite, new Rectangle(0, WindowHeight - 6, WindowWidth, 6), Color.Red); +#endif + + SpriteBatch.End(); + } + + base.Draw(gameTime); + } + + private void BlurImage() + { + Resources.BlurEffectH.Parameters["pixelX"].SetValue(1.0f / _renderTarget1.Width); + Resources.BlurEffectV.Parameters["pixelY"].SetValue(1.0f / _renderTarget1.Height); + + var mult0 = _blurValue; + var mult1 = (1 - _blurValue * 2) / 2; + Resources.BlurEffectH.Parameters["mult0"].SetValue(mult0); + Resources.BlurEffectH.Parameters["mult1"].SetValue(mult1); + Resources.BlurEffectV.Parameters["mult0"].SetValue(mult0); + Resources.BlurEffectV.Parameters["mult1"].SetValue(mult1); + + // resize + Graphics.GraphicsDevice.SetRenderTarget(_renderTarget2); + SpriteBatch.Begin(SpriteSortMode.Immediate, null, SamplerState.AnisotropicClamp, null, null, null, null); + SpriteBatch.Draw(MainRenderTarget, new Rectangle(0, 0, _renderTarget2.Width, _renderTarget2.Height), Color.White); + SpriteBatch.End(); + + for (var i = 0; i < 2; i++) + { + // v blur + Graphics.GraphicsDevice.SetRenderTarget(_renderTarget1); + SpriteBatch.Begin(SpriteSortMode.Immediate, null, SamplerState.AnisotropicClamp, null, null, Resources.BlurEffectV, null); + SpriteBatch.Draw(_renderTarget2, Vector2.Zero, Color.White); + SpriteBatch.End(); + + // h blur + Graphics.GraphicsDevice.SetRenderTarget(_renderTarget2); + SpriteBatch.Begin(SpriteSortMode.Immediate, null, SamplerState.AnisotropicClamp, null, null, Resources.BlurEffectH, null); + SpriteBatch.Draw(_renderTarget1, Vector2.Zero, Color.White); + SpriteBatch.End(); + } + } + + private void SetUpEditorUi() + { + var strScreen = $"{Values.EditorUiObjectEditor}:" + + $"{Values.EditorUiObjectSelection}:" + + $"{Values.EditorUiTileEditor}:" + + $"{Values.EditorUiTileSelection}:" + + $"{Values.EditorUiDigTileEditor}:" + + $"{Values.EditorUiMusicTileEditor}:" + + $"{Values.EditorUiTileExtractor}:" + + $"{Values.EditorUiTilesetEditor}:" + + $"{Values.EditorUiAnimation}:" + + $"{Values.EditorUiSpriteAtlas}"; + + EditorUi.AddElement(new UiRectangle(new Rectangle(0, 0, WindowWidth, Values.ToolBarHeight), + "top", strScreen, Values.ColorBackgroundDark, Color.White, + ui => { ui.Rectangle = new Rectangle(0, 0, WindowWidth, Values.ToolBarHeight); })); + + var pos = 0; + EditorUi.AddElement(new UiButton(new Rectangle(0, 0, 200, Values.ToolBarHeight), Resources.EditorFont, + "Editor", "bt1", strScreen, + ui => { ((UiButton)ui).Marked = ScreenManager.CurrentScreenId == Values.ScreenNameEditor; }, + element => { ScreenManager.ChangeScreen(Values.ScreenNameEditor); })); + + EditorUi.AddElement(new UiButton(new Rectangle(pos += 205, 0, 200, Values.ToolBarHeight), Resources.EditorFont, + "Tileset Editor", "bt1", strScreen, + ui => { ((UiButton)ui).Marked = ScreenManager.CurrentScreenId == Values.ScreenNameEditorTileset; }, + element => { ScreenManager.ChangeScreen(Values.ScreenNameEditorTileset); })); + + EditorUi.AddElement(new UiButton(new Rectangle(pos += 205, 0, 200, Values.ToolBarHeight), Resources.EditorFont, + "Tileset Extractor", "bt1", strScreen, + ui => { ((UiButton)ui).Marked = ScreenManager.CurrentScreenId == Values.ScreenNameEditorTilesetExtractor; }, + element => { ScreenManager.ChangeScreen(Values.ScreenNameEditorTilesetExtractor); })); + + EditorUi.AddElement(new UiButton(new Rectangle(pos += 205, 0, 200, Values.ToolBarHeight), Resources.EditorFont, + "Animation Editor", "bt1", strScreen, + ui => { ((UiButton)ui).Marked = ScreenManager.CurrentScreenId == Values.ScreenNameEditorAnimation; }, + element => { ScreenManager.ChangeScreen(Values.ScreenNameEditorAnimation); })); + + EditorUi.AddElement(new UiButton(new Rectangle(pos += 205, 0, 200, Values.ToolBarHeight), Resources.EditorFont, + "Sprite Atlas Editor", "bt1", strScreen, + ui => { ((UiButton)ui).Marked = ScreenManager.CurrentScreenId == Values.ScreenNameSpriteAtlasEditor; }, + element => { ScreenManager.ChangeScreen(Values.ScreenNameSpriteAtlasEditor); })); + } + + private void EditorUpdate(GameTime gameTime) + { + if (InputHandler.KeyPressed(Keys.N)) + DebugStepper = !DebugStepper; + if (ScreenManager.CurrentScreenId != Values.ScreenNameGame) + DebugStepper = false; + + // debug step + if (DebugStepper && InputHandler.KeyPressed(Keys.M)) + { + TimeMultiplier = TargetElapsedTime.Ticks / 166667f; + DeltaTime = (float)TargetElapsedTime.TotalMilliseconds; + + TotalGameTimeLast = TotalTime; + TotalTime += TargetElapsedTime.Milliseconds; + TotalGameTime += TargetElapsedTime.Milliseconds; + } + + // reload all objects + if (InputHandler.KeyPressed(Keys.Q)) + GameManager.MapManager.ReloadMap(); + + // slow down or speed up the game + if (InputHandler.KeyPressed(Keys.Add)) + DebugTimeScale += 0.125f; + if (InputHandler.KeyPressed(Keys.Subtract) && DebugTimeScale > 0) + DebugTimeScale -= 0.125f; + + if (InputHandler.KeyPressed(Values.DebugShadowKey)) + GameSettings.EnableShadows = !GameSettings.EnableShadows; + + if (ScreenManager.CurrentScreenId != Values.ScreenNameEditor && + ScreenManager.CurrentScreenId != Values.ScreenNameEditorTileset && + ScreenManager.CurrentScreenId != Values.ScreenNameEditorTilesetExtractor && + ScreenManager.CurrentScreenId != Values.ScreenNameEditorAnimation && + ScreenManager.CurrentScreenId != Values.ScreenNameSpriteAtlasEditor) + { + if (InputHandler.KeyPressed(Keys.D0)) + TriggerFpsSettings(); + + if (InputHandler.KeyPressed(Keys.D1)) + { + _currentFrameTimeIndex--; + if (_currentFrameTimeIndex < 0) + _currentFrameTimeIndex = _debugFrameTimes.Length - 1; + TargetElapsedTime = new TimeSpan((long)Math.Ceiling(_debugFrameTimes[_currentFrameTimeIndex] * 10000)); + } + + if (InputHandler.KeyPressed(Keys.D2)) + { + _currentFrameTimeIndex = (_currentFrameTimeIndex + 1) % _debugFrameTimes.Length; + TargetElapsedTime = new TimeSpan((long)Math.Ceiling(_debugFrameTimes[_currentFrameTimeIndex] * 10000)); + } + } + + if (InputHandler.KeyPressed(Keys.Escape) || InputHandler.KeyPressed(Keys.OemPeriod)) + { + // open the editor + if (ScreenManager.CurrentScreenId != Values.ScreenNameEditor && + ScreenManager.CurrentScreenId != Values.ScreenNameEditorTileset && + ScreenManager.CurrentScreenId != Values.ScreenNameEditorTilesetExtractor && + ScreenManager.CurrentScreenId != Values.ScreenNameEditorAnimation && + ScreenManager.CurrentScreenId != Values.ScreenNameSpriteAtlasEditor) + { + UiPageManager.PopAllPages(PageManager.TransitionAnimation.TopToBottom, PageManager.TransitionAnimation.TopToBottom); + + _lastGameScreen = ScreenManager.CurrentScreenId; + ScreenManager.ChangeScreen(_lastEditorScreen); + } + // go back to the game + else + { + _lastEditorScreen = ScreenManager.CurrentScreenId; + ScreenManager.ChangeScreen(_lastGameScreen); + + // set the player position + var editorScreen = (MapEditorScreen)ScreenManager.GetScreen(Values.ScreenNameEditor); + + if (_lastEditorScreen == Values.ScreenNameEditor) + MapManager.ObjLink.SetPosition(new Vector2( + editorScreen.MousePixelPosition.X, + editorScreen.MousePixelPosition.Y)); + } + } + + if (InputHandler.KeyPressed(Values.DebugToggleDebugModeKey)) + DebugMode = !DebugMode; + + if (InputHandler.KeyPressed(Values.DebugBox)) + DebugBoxMode = (DebugBoxMode + 1) % 6; + + // save/load + if (InputHandler.KeyPressed(Values.DebugSaveKey)) + { + MapManager.ObjLink.SaveMap = GameManager.MapManager.CurrentMap.MapName; + MapManager.ObjLink.SavePosition = MapManager.ObjLink.EntityPosition.Position; + MapManager.ObjLink.SaveDirection = MapManager.ObjLink.Direction; + + SaveGameSaveLoad.SaveGame(GameManager); + GameManager.InGameOverlay.InGameHud.ShowSaveIcon(); + } + if (InputHandler.KeyPressed(Values.DebugLoadKey)) + GameManager.LoadSaveFile(GameManager.SaveSlot); + + // save the debug log to the clipboard + if (InputHandler.KeyDown(Keys.H)) + _debugLog += "\n" + DebugText; +#if WINDOWS + else if (InputHandler.KeyReleased(Keys.H)) + Forms.Clipboard.SetText(_debugLog); +#endif + } + + private void TriggerFpsSettings() + { + if (!IsFixedTimeStep) + { + IsFixedTimeStep = true; + Graphics.SynchronizeWithVerticalRetrace = false; + } + else + { + IsFixedTimeStep = false; + Graphics.SynchronizeWithVerticalRetrace = true; + } + + Graphics.ApplyChanges(); + } + + public static void SwitchFullscreenWindowedSetting() + { + // switch from hardware fullscreen to borderless windows + if (!GameSettings.BorderlessWindowed && Graphics.IsFullScreen || + GameSettings.BorderlessWindowed && _isFullscreen) + { + ToggleFullscreen(); + GameSettings.BorderlessWindowed = !GameSettings.BorderlessWindowed; + ToggleFullscreen(); + } + else + { + GameSettings.BorderlessWindowed = !GameSettings.BorderlessWindowed; + } + } + + public static void ToggleFullscreen() + { +#if WINDOWS + GameSettings.IsFullscreen = !GameSettings.IsFullscreen; + + var screenBounds = System.Windows.Forms.Screen.GetBounds(_windowForm); + + if (!GameSettings.BorderlessWindowed) + { + if (!Graphics.IsFullScreen) + { + _lastWindowWidth = Graphics.PreferredBackBufferWidth; + _lastWindowHeight = Graphics.PreferredBackBufferHeight; + + _lastWindowRestoreBounds = _windowForm.RestoreBounds; + + Graphics.PreferredBackBufferWidth = screenBounds.Width; + Graphics.PreferredBackBufferHeight = screenBounds.Height; + + _lastWindowState = _windowForm.WindowState; + } + else + { + if (_lastWindowState != Forms.FormWindowState.Maximized) + { + Graphics.PreferredBackBufferWidth = _lastWindowWidth; + Graphics.PreferredBackBufferHeight = _lastWindowHeight; + } + } + + Graphics.ToggleFullScreen(); + + if (_lastWindowState == Forms.FormWindowState.Maximized) + { + // restore the window size of the normal sized window + _windowForm.Bounds = _lastWindowRestoreBounds; + + _windowForm.WindowState = _lastWindowState; + } + } + else + { + _isFullscreen = !_isFullscreen; + + // change to fullscreen + if (_isFullscreen) + { + _lastWindowState = _windowForm.WindowState; + _lastWindowBounds = _windowForm.Bounds; + + _windowForm.FormBorderStyle = Forms.FormBorderStyle.None; + _windowForm.WindowState = Forms.FormWindowState.Normal; + _windowForm.Bounds = screenBounds; + } + else + { + _windowForm.FormBorderStyle = Forms.FormBorderStyle.Sizable; + + if (_lastWindowState == Forms.FormWindowState.Maximized) + { + // this is set to not loose the old state because fullscreen and windowed are both using the "Normal" state + _windowForm.Bounds = _lastWindowRestoreBounds; + + _windowForm.WindowState = _lastWindowState; + } + else + { + _windowForm.WindowState = _lastWindowState; + _windowForm.Bounds = _lastWindowBounds; + } + } + } +#endif + } + + public void DebugTextBackground() + { + if (!ShowDebugText) + return; + + _debugTextSize = Resources.GameFont.MeasureString(DebugText); + + // draw the background + SpriteBatch.Draw(_renderTarget2, new Rectangle(0, 0, + (int)(_debugTextSize.X * 2) + 20, (int)(_debugTextSize.Y * 2) + 20), Color.White); + } + + public void DrawDebugText() + { + if (!ShowDebugText) + return; + + SpriteBatch.Draw(Resources.SprWhite, new Rectangle(0, 0, + (int)(_debugTextSize.X * 2) + 20, (int)(_debugTextSize.Y * 2) + 20), Color.Black * 0.75f); + + SpriteBatch.DrawString(Resources.GameFont, DebugText, new Vector2(10), Color.White, + 0, Vector2.Zero, new Vector2(2f), SpriteEffects.None, 0); + } + + public void UpdateFpsSettings() + { + IsFixedTimeStep = false; + Graphics.SynchronizeWithVerticalRetrace = GameSettings.LockFps; + Graphics.ApplyChanges(); + } + + private void OnResizeBegin(object? sender, EventArgs e) + { + _isResizing = true; + gameScaleStart = gameScale; + } + + private void OnResize(object? sender, EventArgs e) + { +#if WINDOWS + // save the restore bounds when going into borderless fullscreen mode from an maximized state + if (_isFullscreen && _windowForm.WindowState == Forms.FormWindowState.Maximized) + _lastWindowRestoreBounds = _windowForm.RestoreBounds; + + // minimize the fullscreen window + if (!GameSettings.BorderlessWindowed && Graphics.IsFullScreen && _windowForm.WindowState == Forms.FormWindowState.Minimized && !_wasMinimized) + { + _wasMinimized = true; + + Graphics.ToggleFullScreen(); + _windowForm.WindowState = Forms.FormWindowState.Minimized; + } + // reopen the fullscreen window + if (!GameSettings.BorderlessWindowed && _windowForm.WindowState == Forms.FormWindowState.Normal && _wasMinimized) + { + _wasMinimized = false; + ToggleFullscreen(); + } +#endif + } + + private void OnResizeEnd(object? sender, EventArgs e) + { + _isResizing = false; + gameScaleStart = gameScale; + } + + private void OnResize() + { + if (Window.ClientBounds.Width <= 0 && + Window.ClientBounds.Height <= 0) + return; + + WindowWidth = Window.ClientBounds.Width; + WindowHeight = Window.ClientBounds.Height; + + OnUpdateScale(); + } + + private void OnUpdateScale() + { + // scale of the game + ScreenScale = MathHelper.Clamp(Math.Min(WindowWidth / Values.MinWidth, WindowHeight / Values.MinHeight), 1, 25); + + // float scale + gameScale = MathHelper.Clamp(Math.Min(WindowWidth / (float)Values.MinWidth, WindowHeight / (float)Values.MinHeight), 1, 25); + + // autoscale or size set in the menu + MapManager.Camera.Scale = GameSettings.GameScale == 11 ? MathF.Ceiling(gameScale) : GameSettings.GameScale; + if (MapManager.Camera.Scale < 1) + { + MapManager.Camera.Scale = 1 / (2 - MapManager.Camera.Scale); + GameManager.SetGameScale(1); + } + else + { + GameManager.SetGameScale(GameSettings.GameScale == 11 ? gameScale : GameSettings.GameScale); + } + + UiScale = GameSettings.UiScale == 0 ? ScreenScale : MathHelper.Clamp(GameSettings.UiScale, 1, ScreenScale); + + // update the ui manager + EditorUi.SizeChanged(); + + ScreenManager.OnResize(WindowWidth, WindowHeight); + } + + private void UpdateRenderTargets() + { + if (_isResizing || + WindowWidthEnd == WindowWidth && WindowHeightEnd == WindowHeight) + return; + + UiRtScale = UiScale; + + WindowWidthEnd = WindowWidth; + WindowHeightEnd = WindowHeight; + + UpdateRenderTargetSizes(WindowWidth, WindowHeight); + + ScreenManager.OnResizeEnd(WindowWidth, WindowHeight); + } + + private void UpdateRenderTargetSizes(int width, int height) + { + // @TODO: width must be bigger than 0 + + MainRenderTarget?.Dispose(); + MainRenderTarget = new RenderTarget2D(Graphics.GraphicsDevice, width, height); + Resources.BlurEffect.Parameters["width"].SetValue(width); + Resources.BlurEffect.Parameters["height"].SetValue(height); + + Resources.RoundedCornerBlurEffect.Parameters["textureWidth"].SetValue(width); + Resources.RoundedCornerBlurEffect.Parameters["textureHeight"].SetValue(height); + + // update the blur rendertargets + var blurScale = MathHelper.Clamp(MapManager.Camera.Scale / 2, 1, 10); + var blurRtWidth = (int)(width / blurScale); + var blurRtHeight = (int)(height / blurScale); + + _renderTarget1?.Dispose(); + _renderTarget2?.Dispose(); + + _renderTarget1 = new RenderTarget2D(Graphics.GraphicsDevice, blurRtWidth, blurRtHeight); + _renderTarget2 = new RenderTarget2D(Graphics.GraphicsDevice, blurRtWidth, blurRtHeight); + } + } +} diff --git a/GbsPlayer/ByteBufferPool.cs b/GbsPlayer/ByteBufferPool.cs new file mode 100644 index 0000000..42719a5 --- /dev/null +++ b/GbsPlayer/ByteBufferPool.cs @@ -0,0 +1,99 @@ +using System.Collections.Generic; + +namespace GbsPlayer +{ + internal class ByteBufferPool + { + private readonly int _minBufferSize; + private readonly int _maxBuffers; + + public int FreeAmount + { + get { return _freeBuffers.Count; } + } + + private readonly List _freeBuffers; + + public ByteBufferPool(int minBufferSize = 0, int maxBuffers = int.MaxValue) + { + _minBufferSize = minBufferSize; + _maxBuffers = maxBuffers; + _freeBuffers = new List(); + } + + /// + /// Get a buffer that is at least as big as size. + /// + public byte[] Get(int size) + { + if (size < _minBufferSize) + size = _minBufferSize; + + byte[] result; + lock (_freeBuffers) + { + var index = FirstLargerThan(size); + + if (index == -1) + { + if (_freeBuffers.Count > 0) + _freeBuffers.RemoveAt(0); + result = new byte[size]; + } + else + { + result = _freeBuffers[index]; + _freeBuffers.RemoveAt(index); + } + } + return result; + } + + /// + /// Return the given buffer to the pool. + /// + public void Return(byte[] buffer) + { + lock (_freeBuffers) + { + if (FreeAmount >= _maxBuffers) + return; + var index = FirstLargerThan(buffer.Length); + if (index == -1) + _freeBuffers.Add(buffer); + else + _freeBuffers.Insert(index, buffer); + } + } + + // Find the smallest buffer that is larger than or equally large as size or -1 if none exist + private int FirstLargerThan(int size) + { + if (_freeBuffers.Count == 0) return -1; + + var l = 0; + var r = _freeBuffers.Count - 1; + + while (l <= r) + { + var m = (l + r) / 2; + var buffer = _freeBuffers[m]; + if (buffer.Length < size) + { + l = m + 1; + } + else if (buffer.Length > size) + { + r = m; + if (l == r) return l; + } + else + { + return m; + } + } + + return -1; + } + } +} \ No newline at end of file diff --git a/GbsPlayer/CDynamicEffectInstance.cs b/GbsPlayer/CDynamicEffectInstance.cs new file mode 100644 index 0000000..5b51c07 --- /dev/null +++ b/GbsPlayer/CDynamicEffectInstance.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework.Audio; +using SharpDX; +using SharpDX.Multimedia; +using SharpDX.XAudio2; + +namespace GbsPlayer +{ + public class CDynamicEffectInstance + { + struct AudioBlock + { + public AudioBuffer AudioBuffer; + public byte[] ByteBuffer; + } + + private object _voiceLock = new Object(); + + private static ByteBufferPool _bufferPool = new ByteBufferPool(); + + private Queue _queuedBlocks = new Queue(); + + private SourceVoice _voice; + private WaveFormat _format; + + public SoundState State = SoundState.Stopped; + + public CDynamicEffectInstance(int sampleRate) + { + var xaudio2 = new XAudio2(); + var masteringVoice = new MasteringVoice(xaudio2); + + _format = new WaveFormat(sampleRate, 1); + _voice = new SourceVoice(xaudio2, _format, true); + _voice.BufferEnd += OnBufferEnd; + } + + public int GetPendingBufferCount() + { + lock (_voiceLock) + { + return _queuedBlocks.Count; + } + } + + public void Play() + { + lock (_voiceLock) + { + State = SoundState.Playing; + _voice.Start(); + } + } + + public void Pause() + { + lock (_voiceLock) + { + State = SoundState.Paused; + _voice.Stop(); + } + } + + public void Resume() + { + lock (_voiceLock) + { + State = SoundState.Playing; + _voice.Start(); + } + } + + public void Stop() + { + lock (_voiceLock) + { + State = SoundState.Stopped; + + _voice.Stop(); + // Dequeue all the submitted buffers + _voice.FlushSourceBuffers(); + } + } + + public void SetVolume(float volume) + { + lock (_voiceLock) + { + _voice.SetVolume(volume); + } + } + + public void SubmitBuffer(byte[] buffer, int offset, int count) + { + var audioBlock = new AudioBlock(); + + audioBlock.ByteBuffer = _bufferPool.Get(count); + + // we need to copy so datastream does not pin the buffer that the user might modify later + Buffer.BlockCopy(buffer, offset, audioBlock.ByteBuffer, 0, count); + + var stream = DataStream.Create(audioBlock.ByteBuffer, true, false, 0, true); + audioBlock.AudioBuffer = new AudioBuffer(stream); + audioBlock.AudioBuffer.AudioBytes = count; + + _queuedBlocks.Enqueue(audioBlock); + + lock (_voiceLock) + _voice.SubmitSourceBuffer(audioBlock.AudioBuffer, null); + } + + private void OnBufferEnd(IntPtr obj) + { + // Release the buffer + if (_queuedBlocks.Count > 0) + { + var block = _queuedBlocks.Dequeue(); + block.AudioBuffer.Stream.Dispose(); + _bufferPool.Return(block.ByteBuffer); + } + } + } +} diff --git a/GbsPlayer/Cartridge.cs b/GbsPlayer/Cartridge.cs new file mode 100644 index 0000000..a09abea --- /dev/null +++ b/GbsPlayer/Cartridge.cs @@ -0,0 +1,114 @@ +using System; + +namespace GbsPlayer +{ + public class Cartridge + { + public byte[] ROM; + + public byte SelectedRomBank = 1; + + // gbs + public byte Version; + public byte TrackCount; + public byte FirstSong; + + public ushort LoadAddress; + public ushort InitAddress; + public ushort PlayAddress; + + public ushort StackPointer; + + public byte TimeModulo; + public byte TimeControl; + + public string Title; + public string Author; + public string Copyright; + + public ushort RomOffset; + + public void Init() + { + // Reset values + SelectedRomBank = 1; + + // GBS Header + Version = ROM[0x03]; + TrackCount = ROM[0x04]; + FirstSong = ROM[0x05]; + + LoadAddress = (ushort)(ROM[0x07] << 0x08 | ROM[0x06]); + InitAddress = (ushort)(ROM[0x09] << 0x08 | ROM[0x08]); + PlayAddress = (ushort)(ROM[0x0b] << 0x08 | ROM[0x0a]); + + StackPointer = (ushort)(ROM[0x0d] << 0x08 | ROM[0x0c]); + + TimeModulo = ROM[0x0e]; + TimeControl = ROM[0x0f]; + + var charArray = new char[32]; + for (var i = 0; i < 32; i++) + charArray[i] = (char)ROM[0x10 + i]; + Title = new string(charArray); + + for (var i = 0; i < 32; i++) + charArray[i] = (char)ROM[0x30 + i]; + Author = new string(charArray); + + for (var i = 0; i < 32; i++) + charArray[i] = (char)ROM[0x50 + i]; + Copyright = new string(charArray); + + RomOffset = (ushort)(LoadAddress - 0x70); + } + + public byte this[int index] + { + get + { + // ROM Bank 00 + if (index < 0x4000) + { + if (index - RomOffset >= 0) + return ROM[index - RomOffset]; + } + // ROM Bank 01-.. + else if (index < 0x8000) + { + var romIndex = (SelectedRomBank) * 0x4000 + (index - 0x4000) - RomOffset; + if (romIndex < ROM.Length) + return ROM[romIndex]; + } + + Console.WriteLine("Cartridge Index unavailable: {0:X}", index); + return 0; + } + set + { + // normally enable RAM + if (index < 0x2000) + { + Console.WriteLine("Write to 0x{0:X} not supported", index); + } + // select ROM Bank + else if (index < 0x4000) + { + // GBS: + // A page is selected into Bank 1 by writing the page number as a byte value somewhere in the address range $2000 -$3fff. + + SelectedRomBank = value; + // Console.WriteLine("select ROM bank 0x{0:X}:" + value, index); + } + // RAM Bank Number - or - Upper Bits of ROM Bank Number + else if (index < 0x6000) + { + // GBS: + // Player authors: you should disregard writes to $4000-$5fff and $ff70, and just implement main RAM from $a000 to $dfff. + } + else + Console.WriteLine("Write to 0x{0:X} not supported", index); + } + } + } +} diff --git a/GbsPlayer/GameBoyCPU.cs b/GbsPlayer/GameBoyCPU.cs new file mode 100644 index 0000000..66b9b06 --- /dev/null +++ b/GbsPlayer/GameBoyCPU.cs @@ -0,0 +1,302 @@ +using System; + +namespace GbsPlayer +{ + public partial class GameBoyCPU + { + private readonly GeneralMemory _memory; + private readonly Cartridge _cartridge; + private readonly Sound _gbSound; + + // Interrupt Master Enable Flag (write only) + public bool IME; + + // registers + public byte reg_A, reg_F; + public byte reg_B, reg_C; + public byte reg_D, reg_E; + public byte reg_H, reg_L; + + public ushort reg_AF { get => (ushort)(reg_A << 8 | reg_F); set { reg_A = (byte)(value >> 8); reg_F = (byte)(value & 0xF0); } } + public ushort reg_BC { get => (ushort)(reg_B << 8 | reg_C); set { reg_B = (byte)(value >> 8); reg_C = (byte)(value & 0xFF); } } + public ushort reg_DE { get => (ushort)(reg_D << 8 | reg_E); set { reg_D = (byte)(value >> 8); reg_E = (byte)(value & 0xFF); } } + public ushort reg_HL { get => (ushort)(reg_H << 8 | reg_L); set { reg_H = (byte)(value >> 8); reg_L = (byte)(value & 0xFF); } } + + // flags (reg_F) + public bool flag_Z { get => (reg_F & 0x80) == 0x80; set { reg_F = (byte)((reg_F & 0x70) | (value ? 0x80 : 0x00)); } } + public bool flag_N { get => (reg_F & 0x40) == 0x40; set { reg_F = (byte)((reg_F & 0xB0) | (value ? 0x40 : 0x00)); } } + public bool flag_H { get => (reg_F & 0x20) == 0x20; set { reg_F = (byte)((reg_F & 0xD0) | (value ? 0x20 : 0x00)); } } + public bool flag_C { get => (reg_F & 0x10) == 0x10; set { reg_F = (byte)((reg_F & 0xE0) | (value ? 0x10 : 0x00)); } } + + private byte flag_CBit => (byte)(flag_C ? 1 : 0); + + // SP - stack point + public ushort reg_SP; + // PC - program counter + public ushort reg_PC; + + public byte data8 => _memory[reg_PC - 1]; + public ushort data16 => (ushort)((_memory[reg_PC - 1] << 8) | _memory[reg_PC - 2]); + + private bool CPUHalt; + + // list of functions + public Action[] ops; + public Action[] op_cb; + + // 4194304Hz / 59.73fps = 70221 + public const float UpdateRate = 59.73f; + public const int Clockrate = 4194304; + + private const float maxPlayCycles60 = Clockrate / UpdateRate; // Clockrate / 59.73; + + public int cycleCount; // 69905 70224 + public int lastCycleCount; // 69905 70224 + + private const float UpdateStepSize = 10; + private const int CycleTime = (int)(Clockrate / 1000.0f * UpdateStepSize); + + private float soundCount; + private float maxSoundCycles = 95.1089f; // 4194304 / 44100 + + private float updateCycleCounter; + private float maxPlayCycles = maxPlayCycles60; + + private int divCounter; + private int timerCounter; + + private int currentInstruction; + + private double updateCount; + + private double soundDebugCounter; + + private bool _finishedInit; + private bool _calledPlay; + + // init stack pointer + public ushort IdleAddress = 0xF00D; + + public bool IsRunning; + + public GameBoyCPU(GeneralMemory memory, Cartridge cartridge, Sound gbSound) + { + _memory = memory; + _cartridge = cartridge; + _gbSound = gbSound; + + ops = new Action[] { + NOP, LD_BC_d16, LD_aBC_A, INC_BC, INC_B, DEC_B, LD_B_d8, RLCA, LD_a16_SP, ADD_HL_BC, LD_A_aBC, DEC_BC, INC_C, DEC_C, LD_C_d8, RRCA, + STOP, LD_DE_d16, LD_aDE_A, INC_DE, INC_D, DEC_D, LD_D_d8, RLA, JR_d8, ADD_HL_DE, LD_A_aDE, DEC_DE, INC_E, DEC_E, LD_E_d8, RRA, + JR_NZ_a8, LD_HL_d16, LD_aHLp_A, INC_HL, INC_H, DEC_H, LD_H_d8, DAA, JR_Z_a8, ADD_HL_HL, LD_A_aHLp, DEC_HL, INC_L, DEC_L, LD_L_d8, CPL, + JR_NC_a8, LD_SP_d16, LD_aHLm_A, INC_SP, INC_aHL, DEC_aHL, LD_aHL_d8, SCF, JR_C_a8, ADD_HL_SP, LD_A_aHLm, DEC_SP, INC_A, DEC_A, LD_A_d8, CCF, + LD_B_B, LD_B_C, LD_B_D, LD_B_E, LD_B_H, LD_B_L, LD_B_aHL, LD_B_A, LD_C_B, LD_C_C, LD_C_D, LD_C_E, LD_C_H, LD_C_L, LD_C_aHL, LD_C_A, + LD_D_B, LD_D_C, LD_D_D, LD_D_E, LD_D_H, LD_D_L, LD_D_aHL, LD_D_A, LD_E_B, LD_E_C, LD_E_D, LD_E_E, LD_E_H, LD_E_L, LD_E_aHL, LD_E_A, + LD_H_B, LD_H_C, LD_H_D, LD_H_E, LD_H_H, LD_H_L, LD_H_aHL, LD_H_A, LD_L_B, LD_L_C, LD_L_D, LD_L_E, LD_L_H, LD_L_L, LD_L_aHL, LD_L_A, + LD_aHL_B, LD_aHL_C, LD_aHL_D, LD_aHL_E, LD_aHL_H, LD_aHL_L, HALT, LD_aHL_A, LD_A_B, LD_A_C, LD_A_D, LD_A_E, LD_A_H, LD_A_L, LD_A_aHL, LD_A_A, + ADD_A_B, ADD_A_C, ADD_A_D, ADD_A_E, ADD_A_H, ADD_A_L, ADD_A_aHL, ADD_A_A, ADC_A_B, ADC_A_C, ADC_A_D, ADC_A_E, ADC_A_H, ADC_A_L, ADC_A_aHL, ADC_A_A, + SUB_B, SUB_C, SUB_D, SUB_E, SUB_H, SUB_L, SUB_aHL, SUB_A, SBC_A_B, SBC_A_C, SBC_A_D, SBC_A_E, SBC_A_H, SBC_A_L, SBC_A_aHL, SBC_A_A, + AND_B, AND_C, AND_D, AND_E, AND_H, AND_L, AND_aHL, AND_A, XOR_B, XOR_C, XOR_D, XOR_E, XOR_H, XOR_L, XOR_aHL, XOR_A, + OR_B, OR_C, OR_D, OR_E, OR_H, OR_L, OR_aHL, OR_A, CP_B, CP_C, CP_D, CP_E, CP_H, CP_L, CP_aHL, CP_A, + RET_NZ, POP_BC, JP_NZ_a16, JP_a16, CALL_NZ_a16, PUSH_BC, ADD_A_d8, RST_00H, RET_Z, RET, JP_Z_a16, null, CALL_Z_a16, CALL_a16, ADC_A_d8, RST_08H, + RET_NC, POP_DE, JP_NC_a16, null, CALL_NC_a16, PUSH_DE, SUB_d8, RST_10H, RET_C, RETI, JP_C_a16, null, CALL_C_a16, null, SBC_A_d8, RST_18H, + LDH_a8_A, POP_HL, LD_aC_A, null, null, PUSH_HL, AND_d8, RST_20H, ADD_SP_r8, JP_aHL, LD_a16_A, null, null, null, XOR_d8, RST_28H, + LDH_A_a8, POP_AF, LD_A_aC, DI, null, PUSH_AF, OR_d8, RST_30H, LD_HL_SPr8, LD_SP_HL, LD_A_a16, EI, null, null, CP_d8, RST_38H}; + + op_cb = new Action[] { + RLC_B, RLC_C, RLC_D, RLC_E, RLC_H, RLC_L, RLC_aHL, RLC_A, RRC_B, RRC_C, RRC_D, RRC_E, RRC_H, RRC_L, RRC_aHL, RRC_A, + RL_B, RL_C, RL_D, RL_E, RL_H, RL_L, RL_aHL, RL_A, RR_B, RR_C, RR_D, RR_E, RR_H, RR_L, RR_aHL, RR_A , + SLA_B, SLA_C, SLA_D, SLA_E, SLA_H, SLA_L, SLA_aHL, SLA_A, SRA_B, SRA_C, SRA_D, SRA_E, SRA_H, SRA_L, SRA_aHL, SRA_A, + SWAP_B, SWAP_C, SWAP_D, SWAP_E, SWAP_H, SWAP_L, SWAP_aHL, SWAP_A, SRL_B, SRL_C, SRL_D, SRL_E, SRL_H, SRL_L, SRL_aHL, SRL_A, + BIT_0_B, BIT_0_C, BIT_0_D, BIT_0_E, BIT_0_H, BIT_0_L, BIT_0_aHL, BIT_0_A, BIT_1_B, BIT_1_C, BIT_1_D, BIT_1_E, BIT_1_H, BIT_1_L, BIT_1_aHL, BIT_1_A, + BIT_2_B, BIT_2_C, BIT_2_D, BIT_2_E, BIT_2_H, BIT_2_L, BIT_2_aHL, BIT_2_A, BIT_3_B, BIT_3_C, BIT_3_D, BIT_3_E, BIT_3_H, BIT_3_L, BIT_3_aHL, BIT_3_A, + BIT_4_B, BIT_4_C, BIT_4_D, BIT_4_E, BIT_4_H, BIT_4_L, BIT_4_aHL, BIT_4_A, BIT_5_B, BIT_5_C, BIT_5_D, BIT_5_E, BIT_5_H, BIT_5_L, BIT_5_aHL, BIT_5_A, + BIT_6_B, BIT_6_C, BIT_6_D, BIT_6_E, BIT_6_H, BIT_6_L, BIT_6_aHL, BIT_6_A, BIT_7_B, BIT_7_C, BIT_7_D, BIT_7_E, BIT_7_H, BIT_7_L, BIT_7_aHL, BIT_7_A, + RES_0_B, RES_0_C, RES_0_D, RES_0_E, RES_0_H, RES_0_L, RES_0_aHL, RES_0_A, RES_1_B, RES_1_C, RES_1_D, RES_1_E, RES_1_H, RES_1_L, RES_1_aHL, RES_1_A, + RES_2_B, RES_2_C, RES_2_D, RES_2_E, RES_2_H, RES_2_L, RES_2_aHL, RES_2_A, RES_3_B, RES_3_C, RES_3_D, RES_3_E, RES_3_H, RES_3_L, RES_3_aHL, RES_3_A, + RES_4_B, RES_4_C, RES_4_D, RES_4_E, RES_4_H, RES_4_L, RES_4_aHL, RES_4_A, RES_5_B, RES_5_C, RES_5_D, RES_5_E, RES_5_H, RES_5_L, RES_5_aHL, RES_5_A, + RES_6_B, RES_6_C, RES_6_D, RES_6_E, RES_6_H, RES_6_L, RES_6_aHL, RES_6_A, RES_7_B, RES_7_C, RES_7_D, RES_7_E, RES_7_H, RES_7_L, RES_7_aHL, RES_7_A, + SET_0_B, SET_0_C, SET_0_D, SET_0_E, SET_0_H, SET_0_L, SET_0_aHL, SET_0_A, SET_1_B, SET_1_C, SET_1_D, SET_1_E, SET_1_H, SET_1_L, SET_1_aHL, SET_1_A, + SET_2_B, SET_2_C, SET_2_D, SET_2_E, SET_2_H, SET_2_L, SET_2_aHL, SET_2_A, SET_3_B, SET_3_C, SET_3_D, SET_3_E, SET_3_H, SET_3_L, SET_3_aHL, SET_3_A, + SET_4_B, SET_4_C, SET_4_D, SET_4_E, SET_4_H, SET_4_L, SET_4_aHL, SET_4_A, SET_5_B, SET_5_C, SET_5_D, SET_5_E, SET_5_H, SET_5_L, SET_5_aHL, SET_5_A, + SET_6_B, SET_6_C, SET_6_D, SET_6_E, SET_6_H, SET_6_L, SET_6_aHL, SET_6_A, SET_7_B, SET_7_C, SET_7_D, SET_7_E, SET_7_H, SET_7_L, SET_7_aHL, SET_7_A }; + } + + public void Init() + { + _memory.Init(); + _gbSound.Init(); + + updateCount = 0; + cycleCount = 0; + lastCycleCount = 0; + + soundCount = 0; + updateCycleCounter = 0; + + CPUHalt = false; + + _finishedInit = false; + _calledPlay = false; + } + + public void Update() + { + if (!IsRunning) + return; + + // create a 5 buffer puffer + while (!_gbSound.WasStopped && _gbSound._soundOutput.GetPendingBufferCount() < 10) + { + while (cycleCount < CycleTime) + CPUCycle(); + + cycleCount -= CycleTime; + } + + // start playing music + if (_calledPlay && !_gbSound.IsPlaying()) + _gbSound.Play(); + } + + private void CPUCycle() + { + lastCycleCount = cycleCount; + + // execute next instruction + if (!CPUHalt) + ExecuteInstruction(); + else + cycleCount += 4; + + if (_finishedInit) + updateCycleCounter += (cycleCount - lastCycleCount); + + if (_calledPlay && !_gbSound.WasStopped) + { + soundCount += (cycleCount - lastCycleCount); + + while (soundCount >= maxSoundCycles) + { + soundCount -= maxSoundCycles; + _gbSound.UpdateBuffer(); + } + } + } + + private void ExecuteInstruction() + { + // gbs: finished init or play function? + if (reg_PC == IdleAddress) + { + _calledPlay = _finishedInit; + _finishedInit = true; + + if (updateCycleCounter >= maxPlayCycles) + { + updateCycleCounter -= maxPlayCycles; + + reg_PC = _cartridge.PlayAddress; + + if (reg_SP != _cartridge.StackPointer) + Console.WriteLine("StackPointer error"); + + // push the idleAddress on the stack + _memory[--reg_SP] = (byte)(IdleAddress >> 0x8); + _memory[--reg_SP] = (byte)(IdleAddress & 0xFF); + } + else + { + // skip cycles until the next relevant event + var instructionDiff = CycleTime - cycleCount; + var updateDiff = maxPlayCycles - updateCycleCounter; + + var minDiff = Math.Min(instructionDiff, updateDiff); + + cycleCount += (int)(maxSoundCycles * (int)(minDiff / maxSoundCycles)); + soundCount -= maxSoundCycles * (int)(minDiff / maxSoundCycles); + + while (minDiff >= maxSoundCycles && !_gbSound.WasStopped) + { + minDiff -= maxSoundCycles; + _gbSound.UpdateBuffer(); + } + + cycleCount += (int)minDiff + 1; + } + + return; + } + + currentInstruction = reg_PC; + + // update cycle count + cycleCount += OpCycle.CycleArray[_memory[reg_PC]]; + reg_PC += OpLength.LengthTable[_memory[reg_PC]]; + + // execute + if (ops[_memory[currentInstruction]] != null) + { + ops[_memory[currentInstruction]](); + } + // cb instruction + else if (_memory[currentInstruction] == 0xCB) + { + cycleCount += OpCycle.CycleCbArray[_memory[reg_PC]]; + op_cb[_memory[reg_PC]](); + reg_PC++; + } + else + { + reg_PC++; + } + } + + public void SkipBootROM() + { + reg_AF = 0x01B0; + reg_BC = 0x0013; + reg_DE = 0x00D8; + reg_HL = 0x014D; + + reg_PC = 0x0100; + reg_SP = 0xFFFE; + + _memory[0xFF06] = 0x00; + _memory[0xFF07] = 0x00; + _memory[0xFF10] = 0x80; + _memory[0xFF11] = 0xBF; + _memory[0xFF12] = 0xF3; + _memory[0xFF14] = 0xBF; + _memory[0xFF16] = 0x3F; + _memory[0xFF17] = 0x00; + _memory[0xFF19] = 0xBF; + _memory[0xFF1A] = 0x7F; + _memory[0xFF1B] = 0xFF; + _memory[0xFF1C] = 0x9F; + _memory[0xFF1E] = 0xBF; + _memory[0xFF20] = 0xFF; + _memory[0xFF21] = 0x00; + _memory[0xFF22] = 0x00; + _memory[0xFF23] = 0xBF; + _memory[0xFF24] = 0x77; + _memory[0xFF25] = 0xF3; + _memory[0xFF26] = 0xF0; + //_memory[0xFF40] = 0x91; + //_memory[0xFF42] = 0x00; + //_memory[0xFF43] = 0x00; + //_memory[0xFF45] = 0x00; + //_memory[0xFF47] = 0xFC; + //_memory[0xFF48] = 0xFF; + //_memory[0xFF49] = 0xFF; + //_memory[0xFF4A] = 0x00; + //_memory[0xFF4B] = 0x00; + _memory[0xFFFF] = 0x00; + } + + public void SetPlaybackSpeed(float multiplier) + { + maxPlayCycles = maxPlayCycles60 / multiplier; + } + } +} diff --git a/GbsPlayer/GameBoyCPUInstructions.cs b/GbsPlayer/GameBoyCPUInstructions.cs new file mode 100644 index 0000000..5694057 --- /dev/null +++ b/GbsPlayer/GameBoyCPUInstructions.cs @@ -0,0 +1,746 @@ +namespace GbsPlayer +{ + public partial class GameBoyCPU + { + // control + public void NOP() { } + public void STOP() { } + public void HALT() { CPUHalt = true; } + public void DI() { IME = false; } + public void EI() { IME = true; } + + public void LDH_a8_A() { _memory[0xFF00 + data8] = reg_A; } + // LD/LDH + public void LDH_A_a8() { reg_A = _memory[0xFF00 + data8]; } + + public void LD_A_a16() { reg_A = _memory[data16]; } + + public void LD_BC_d16() { reg_BC = data16; } + public void LD_DE_d16() { reg_DE = data16; } + public void LD_HL_d16() { reg_HL = data16; } + public void LD_SP_d16() { reg_SP = data16; } + + public void LD_aHLp_A() { LD_aHL_A(); INC_HL(); } + public void LD_aHLm_A() { LD_aHL_A(); DEC_HL(); } + public void LD_aHL_d8() { _memory[reg_HL] = data8; } + public void LD_aBC_A() { _memory[reg_BC] = reg_A; } + public void LD_aDE_A() { _memory[reg_DE] = reg_A; } + public void LD_a16_A() { _memory[data16] = reg_A; } + + public void LD_A_aC() { reg_A = _memory[0xFF00 + reg_C]; } + public void LD_A_aBC() { reg_A = _memory[reg_BC]; } + public void LD_A_aDE() { reg_A = _memory[reg_DE]; } + public void LD_A_aHLp() { LD_A_aHL(); INC_HL(); } + public void LD_A_aHLm() { LD_A_aHL(); DEC_HL(); } + + public void LD_aC_A() { _memory[0xFF00 + reg_C] = reg_A; } + + public void LD_a16_SP() { _memory[data16] = (byte)(reg_SP & 0xFF); _memory[data16 + 1] = (byte)(reg_SP >> 8); } + + public void LD_HL_SPr8() + { + reg_HL = (ushort)(reg_SP + (sbyte)data8); flag_Z = false; flag_N = false; + flag_H = (((reg_SP ^ (sbyte)data8 ^ ((reg_SP + (sbyte)data8) & 0xFFFF)) & 0x10) == 0x10); + flag_C = (((reg_SP ^ (sbyte)data8 ^ ((reg_SP + (sbyte)data8) & 0xFFFF)) & 0x100) == 0x100); + } + + public void LD_SP_HL() { reg_SP = reg_HL; } + + public void LD_A_d8() { reg_A = data8; } + public void LD_B_d8() { reg_B = data8; } + public void LD_C_d8() { reg_C = data8; } + public void LD_D_d8() { reg_D = data8; } + public void LD_E_d8() { reg_E = data8; } + public void LD_H_d8() { reg_H = data8; } + public void LD_L_d8() { reg_L = data8; } + + public void LD_aHL_A() { _memory[reg_HL] = reg_A; } + public void LD_aHL_B() { _memory[reg_HL] = reg_B; } + public void LD_aHL_C() { _memory[reg_HL] = reg_C; } + public void LD_aHL_D() { _memory[reg_HL] = reg_D; } + public void LD_aHL_E() { _memory[reg_HL] = reg_E; } + public void LD_aHL_H() { _memory[reg_HL] = reg_H; } + public void LD_aHL_L() { _memory[reg_HL] = reg_L; } + + public void LD_A_A() { } + public void LD_A_B() { reg_A = reg_B; } + public void LD_A_C() { reg_A = reg_C; } + public void LD_A_D() { reg_A = reg_D; } + public void LD_A_E() { reg_A = reg_E; } + public void LD_A_H() { reg_A = reg_H; } + public void LD_A_L() { reg_A = reg_L; } + public void LD_A_aHL() { reg_A = _memory[reg_HL]; } + + public void LD_B_A() { reg_B = reg_A; } + public void LD_B_B() { } + public void LD_B_C() { reg_B = reg_C; } + public void LD_B_D() { reg_B = reg_D; } + public void LD_B_E() { reg_B = reg_E; } + public void LD_B_H() { reg_B = reg_H; } + public void LD_B_L() { reg_B = reg_L; } + public void LD_B_aHL() { reg_B = _memory[reg_HL]; } + + public void LD_C_A() { reg_C = reg_A; } + public void LD_C_B() { reg_C = reg_B; } + public void LD_C_C() { } + public void LD_C_D() { reg_C = reg_D; } + public void LD_C_E() { reg_C = reg_E; } + public void LD_C_H() { reg_C = reg_H; } + public void LD_C_L() { reg_C = reg_L; } + public void LD_C_aHL() { reg_C = _memory[reg_HL]; } + + public void LD_D_A() { reg_D = reg_A; } + public void LD_D_B() { reg_D = reg_B; } + public void LD_D_C() { reg_D = reg_C; } + public void LD_D_D() { } + public void LD_D_E() { reg_D = reg_E; } + public void LD_D_H() { reg_D = reg_H; } + public void LD_D_L() { reg_D = reg_L; } + public void LD_D_aHL() { reg_D = _memory[reg_HL]; } + + public void LD_E_A() { reg_E = reg_A; } + public void LD_E_B() { reg_E = reg_B; } + public void LD_E_C() { reg_E = reg_C; } + public void LD_E_D() { reg_E = reg_D; } + public void LD_E_E() { } + public void LD_E_H() { reg_E = reg_H; } + public void LD_E_L() { reg_E = reg_L; } + public void LD_E_aHL() { reg_E = _memory[reg_HL]; } + + public void LD_H_A() { reg_H = reg_A; } + public void LD_H_B() { reg_H = reg_B; } + public void LD_H_C() { reg_H = reg_C; } + public void LD_H_D() { reg_H = reg_D; } + public void LD_H_E() { reg_H = reg_E; } + public void LD_H_H() { } + public void LD_H_L() { reg_H = reg_L; } + public void LD_H_aHL() { reg_H = _memory[reg_HL]; } + + public void LD_L_A() { reg_L = reg_A; } + public void LD_L_B() { reg_L = reg_B; } + public void LD_L_C() { reg_L = reg_C; } + public void LD_L_D() { reg_L = reg_D; } + public void LD_L_E() { reg_L = reg_E; } + public void LD_L_H() { reg_L = reg_H; } + public void LD_L_L() { } + public void LD_L_aHL() { reg_L = _memory[reg_HL]; } + + // INC 8bit + public void INC_A() { reg_A++; flag_Z = (reg_A == 0x00); flag_N = false; flag_H = ((reg_A & 0x0F) == 0x00); } + public void INC_B() { reg_B++; flag_Z = (reg_B == 0x00); flag_N = false; flag_H = ((reg_B & 0x0F) == 0x00); } + public void INC_C() { reg_C++; flag_Z = (reg_C == 0x00); flag_N = false; flag_H = ((reg_C & 0x0F) == 0x00); } + public void INC_D() { reg_D++; flag_Z = (reg_D == 0x00); flag_N = false; flag_H = ((reg_D & 0x0F) == 0x00); } + public void INC_E() { reg_E++; flag_Z = (reg_E == 0x00); flag_N = false; flag_H = ((reg_E & 0x0F) == 0x00); } + public void INC_H() { reg_H++; flag_Z = (reg_H == 0x00); flag_N = false; flag_H = ((reg_H & 0x0F) == 0x00); } + public void INC_L() { reg_L++; flag_Z = (reg_L == 0x00); flag_N = false; flag_H = ((reg_L & 0x0F) == 0x00); } + public void INC_aHL() { _memory[reg_HL]++; flag_Z = (_memory[reg_HL] == 0x00); flag_N = false; flag_H = ((_memory[reg_HL] & 0x0F) == 0x00); } + + // INC 16bit + public void INC_BC() { reg_BC++; } + public void INC_DE() { reg_DE++; } + public void INC_HL() { reg_HL++; } + public void INC_SP() { reg_SP++; } + + // DEC 8bit todo flag h right? + public void DEC_A() { reg_A--; flag_Z = (reg_A == 0x00); flag_N = true; flag_H = ((reg_A & 0x0F) == 0x0F); } + public void DEC_B() { reg_B--; flag_Z = (reg_B == 0x00); flag_N = true; flag_H = ((reg_B & 0x0F) == 0x0F); } + public void DEC_C() { reg_C--; flag_Z = (reg_C == 0x00); flag_N = true; flag_H = ((reg_C & 0x0F) == 0x0F); } + public void DEC_D() { reg_D--; flag_Z = (reg_D == 0x00); flag_N = true; flag_H = ((reg_D & 0x0F) == 0x0F); } + public void DEC_E() { reg_E--; flag_Z = (reg_E == 0x00); flag_N = true; flag_H = ((reg_E & 0x0F) == 0x0F); } + public void DEC_H() { reg_H--; flag_Z = (reg_H == 0x00); flag_N = true; flag_H = ((reg_H & 0x0F) == 0x0F); } + public void DEC_L() { reg_L--; flag_Z = (reg_L == 0x00); flag_N = true; flag_H = ((reg_L & 0x0F) == 0x0F); } + public void DEC_aHL() { _memory[reg_HL]--; flag_Z = (_memory[reg_HL] == 0x00); flag_N = true; flag_H = ((_memory[reg_HL] & 0x0F) == 0x0F); } + + // DEC 16bit + public void DEC_BC() { reg_BC--; } + public void DEC_DE() { reg_DE--; } + public void DEC_HL() { reg_HL--; } + public void DEC_SP() { reg_SP--; } + + // ADD/ADC 8bit + public void ADD_A_A() { flag_H = ((reg_A & 0x0F) + (reg_A & 0x0F)) > 0x0F; flag_C = (reg_A + reg_A) > 0xFF; reg_A += reg_A; flag_Z = reg_A == 0x00; flag_N = false; } + public void ADD_A_B() { flag_H = ((reg_A & 0x0F) + (reg_B & 0x0F)) > 0x0F; flag_C = (reg_A + reg_B) > 0xFF; reg_A += reg_B; flag_Z = reg_A == 0x00; flag_N = false; } + public void ADD_A_C() { flag_H = ((reg_A & 0x0F) + (reg_C & 0x0F)) > 0x0F; flag_C = (reg_A + reg_C) > 0xFF; reg_A += reg_C; flag_Z = reg_A == 0x00; flag_N = false; } + public void ADD_A_D() { flag_H = ((reg_A & 0x0F) + (reg_D & 0x0F)) > 0x0F; flag_C = (reg_A + reg_D) > 0xFF; reg_A += reg_D; flag_Z = reg_A == 0x00; flag_N = false; } + public void ADD_A_E() { flag_H = ((reg_A & 0x0F) + (reg_E & 0x0F)) > 0x0F; flag_C = (reg_A + reg_E) > 0xFF; reg_A += reg_E; flag_Z = reg_A == 0x00; flag_N = false; } + public void ADD_A_H() { flag_H = ((reg_A & 0x0F) + (reg_H & 0x0F)) > 0x0F; flag_C = (reg_A + reg_H) > 0xFF; reg_A += reg_H; flag_Z = reg_A == 0x00; flag_N = false; } + public void ADD_A_L() { flag_H = ((reg_A & 0x0F) + (reg_L & 0x0F)) > 0x0F; flag_C = (reg_A + reg_L) > 0xFF; reg_A += reg_L; flag_Z = reg_A == 0x00; flag_N = false; } + public void ADD_A_d8() { flag_H = ((reg_A & 0x0F) + (data8 & 0x0F)) > 0x0F; flag_C = (reg_A + data8) > 0xFF; reg_A += data8; flag_Z = reg_A == 0x00; flag_N = false; } + public void ADD_A_aHL() + { + flag_H = ((reg_A & 0x0F) + (_memory[reg_HL] & 0x0F)) > 0x0F; + flag_C = (reg_A + _memory[reg_HL]) > 0xFF; reg_A += _memory[reg_HL]; flag_Z = reg_A == 0x00; flag_N = false; + } + + public void ADD_SP_r8() + { + flag_Z = false; flag_N = false; flag_H = (((reg_SP ^ (sbyte)data8 ^ ((reg_SP + (sbyte)data8) & 0xFFFF)) & 0x10) == 0x10); + flag_C = (((reg_SP ^ (sbyte)data8 ^ ((reg_SP + (sbyte)data8) & 0xFFFF)) & 0x100) == 0x100); reg_SP = (ushort)(reg_SP + (sbyte)data8); + } + + // ADC todo: make it nicer + public void ADC_A_A() + { + var sum = reg_A + reg_A + (flag_C ? 1 : 0); + flag_H = ((reg_A & 0x0F) + (reg_A & 0x0F) + (flag_C ? 0x01 : 0x00)) > 0x0F; flag_C = sum > 0xFF; + reg_A = (byte)sum; flag_Z = reg_A == 0x00; flag_N = false; + } + public void ADC_A_B() + { + var sum = reg_A + reg_B + (flag_C ? 1 : 0); + flag_H = ((reg_A & 0x0F) + (reg_B & 0x0F) + (flag_C ? 0x01 : 0x00)) > 0x0F; flag_C = sum > 0xFF; + reg_A = (byte)sum; flag_Z = reg_A == 0x00; flag_N = false; + } + public void ADC_A_C() + { + var sum = reg_A + reg_C + (flag_C ? 1 : 0); + flag_H = ((reg_A & 0x0F) + (reg_C & 0x0F) + (flag_C ? 0x01 : 0x00)) > 0x0F; flag_C = sum > 0xFF; + reg_A = (byte)sum; flag_Z = reg_A == 0x00; flag_N = false; + } + public void ADC_A_D() + { + var sum = reg_A + reg_D + (flag_C ? 1 : 0); + flag_H = ((reg_A & 0x0F) + (reg_D & 0x0F) + (flag_C ? 0x01 : 0x00)) > 0x0F; flag_C = sum > 0xFF; + reg_A = (byte)sum; flag_Z = reg_A == 0x00; flag_N = false; + } + public void ADC_A_E() + { + var sum = reg_A + reg_E + (flag_C ? 1 : 0); + flag_H = ((reg_A & 0x0F) + (reg_E & 0x0F) + (flag_C ? 0x01 : 0x00)) > 0x0F; flag_C = sum > 0xFF; + reg_A = (byte)sum; flag_Z = reg_A == 0x00; flag_N = false; + } + public void ADC_A_H() + { + var sum = reg_A + reg_H + (flag_C ? 1 : 0); + flag_H = ((reg_A & 0x0F) + (reg_H & 0x0F) + (flag_C ? 0x01 : 0x00)) > 0x0F; flag_C = sum > 0xFF; + reg_A = (byte)sum; flag_Z = reg_A == 0x00; flag_N = false; + } + public void ADC_A_L() + { + var sum = reg_A + reg_L + (flag_C ? 1 : 0); + flag_H = ((reg_A & 0x0F) + (reg_L & 0x0F) + (flag_C ? 0x01 : 0x00)) > 0x0F; flag_C = sum > 0xFF; + reg_A = (byte)sum; flag_Z = reg_A == 0x00; flag_N = false; + } + public void ADC_A_d8() + { + var sum = reg_A + data8 + (flag_C ? 1 : 0); + flag_H = ((reg_A & 0x0F) + (data8 & 0x0F) + (flag_C ? 0x01 : 0x00)) > 0x0F; flag_C = sum > 0xFF; + reg_A = (byte)sum; flag_Z = reg_A == 0x00; flag_N = false; + } + public void ADC_A_aHL() + { + var sum = reg_A + _memory[reg_HL] + (flag_C ? 1 : 0); + flag_H = ((reg_A & 0x0F) + (_memory[reg_HL] & 0x0F) + (flag_C ? 0x01 : 0x00)) > 0x0F; flag_C = sum > 0xFF; + reg_A = (byte)sum; flag_Z = reg_A == 0x00; flag_N = false; + } + + // ADD 16bit + public void ADD_HL_BC() { flag_N = false; flag_H = ((reg_HL & 0x0FFF) + (reg_BC & 0x0FFF)) > 0x0FFF; flag_C = (reg_HL + reg_BC) > 0xFFFF; reg_HL += reg_BC; } + public void ADD_HL_DE() { flag_N = false; flag_H = ((reg_HL & 0x0FFF) + (reg_DE & 0x0FFF)) > 0x0FFF; flag_C = (reg_HL + reg_DE) > 0xFFFF; reg_HL += reg_DE; } + public void ADD_HL_HL() { flag_N = false; flag_H = ((reg_HL & 0x0FFF) + (reg_HL & 0x0FFF)) > 0x0FFF; flag_C = (reg_HL + reg_HL) > 0xFFFF; reg_HL += reg_HL; } + public void ADD_HL_SP() { flag_N = false; flag_H = ((reg_HL & 0x0FFF) + (reg_SP & 0x0FFF)) > 0x0FFF; flag_C = (reg_HL + reg_SP) > 0xFFFF; reg_HL += reg_SP; } + + // SUB 8bit + public void SUB_A() { flag_H = (reg_A & 0x0F) < (reg_A & 0x0F); flag_C = false; reg_A -= reg_A; flag_Z = reg_A == 0x00; flag_N = true; } + public void SUB_B() { flag_H = (reg_A & 0x0F) < (reg_B & 0x0F); flag_C = reg_A < reg_B; reg_A -= reg_B; flag_Z = reg_A == 0x00; flag_N = true; } + public void SUB_C() { flag_H = (reg_A & 0x0F) < (reg_C & 0x0F); flag_C = reg_A < reg_C; reg_A -= reg_C; flag_Z = reg_A == 0x00; flag_N = true; } + public void SUB_D() { flag_H = (reg_A & 0x0F) < (reg_D & 0x0F); flag_C = reg_A < reg_D; reg_A -= reg_D; flag_Z = reg_A == 0x00; flag_N = true; } + public void SUB_E() { flag_H = (reg_A & 0x0F) < (reg_E & 0x0F); flag_C = reg_A < reg_E; reg_A -= reg_E; flag_Z = reg_A == 0x00; flag_N = true; } + public void SUB_H() { flag_H = (reg_A & 0x0F) < (reg_H & 0x0F); flag_C = reg_A < reg_H; reg_A -= reg_H; flag_Z = reg_A == 0x00; flag_N = true; } + public void SUB_L() { flag_H = (reg_A & 0x0F) < (reg_L & 0x0F); flag_C = reg_A < reg_L; reg_A -= reg_L; flag_Z = reg_A == 0x00; flag_N = true; } + public void SUB_d8() { flag_H = (reg_A & 0x0F) < (data8 & 0x0F); flag_C = reg_A < data8; reg_A -= data8; flag_Z = reg_A == 0x00; flag_N = true; } + public void SUB_aHL() + { + flag_H = (reg_A & 0x0F) < (_memory[reg_HL] & 0x0F); + flag_C = reg_A < _memory[reg_HL]; reg_A -= _memory[reg_HL]; flag_Z = reg_A == 0x00; flag_N = true; + } + + // SBC + public void SBC_A_A() { var temp = reg_A + flag_CBit; flag_H = (reg_A & 0x0F) < ((reg_A & 0x0F) + flag_CBit); flag_C = reg_A < temp; reg_A -= (byte)temp; flag_Z = (reg_A == 0x00); flag_N = true; } + public void SBC_A_B() { var temp = reg_B + flag_CBit; flag_H = (reg_A & 0x0F) < ((reg_B & 0x0F) + flag_CBit); flag_C = reg_A < temp; reg_A -= (byte)temp; flag_Z = (reg_A == 0x00); flag_N = true; } + public void SBC_A_C() { var temp = reg_C + flag_CBit; flag_H = (reg_A & 0x0F) < ((reg_C & 0x0F) + flag_CBit); flag_C = reg_A < temp; reg_A -= (byte)temp; flag_Z = (reg_A == 0x00); flag_N = true; } + public void SBC_A_D() { var temp = reg_D + flag_CBit; flag_H = (reg_A & 0x0F) < ((reg_D & 0x0F) + flag_CBit); flag_C = reg_A < temp; reg_A -= (byte)temp; flag_Z = (reg_A == 0x00); flag_N = true; } + public void SBC_A_E() { var temp = reg_E + flag_CBit; flag_H = (reg_A & 0x0F) < ((reg_E & 0x0F) + flag_CBit); flag_C = reg_A < temp; reg_A -= (byte)temp; flag_Z = (reg_A == 0x00); flag_N = true; } + public void SBC_A_H() { var temp = reg_H + flag_CBit; flag_H = (reg_A & 0x0F) < ((reg_H & 0x0F) + flag_CBit); flag_C = reg_A < temp; reg_A -= (byte)temp; flag_Z = (reg_A == 0x00); flag_N = true; } + public void SBC_A_L() { var temp = reg_L + flag_CBit; flag_H = (reg_A & 0x0F) < ((reg_L & 0x0F) + flag_CBit); flag_C = reg_A < temp; reg_A -= (byte)temp; flag_Z = (reg_A == 0x00); flag_N = true; } + public void SBC_A_d8() { var temp = data8 + flag_CBit; flag_H = (reg_A & 0x0F) < ((data8 & 0x0F) + flag_CBit); flag_C = reg_A < temp; reg_A -= (byte)temp; flag_Z = (reg_A == 0x00); flag_N = true; } + public void SBC_A_aHL() + { + var temp = _memory[reg_HL] + flag_CBit; + flag_H = (reg_A & 0x0F) < ((_memory[reg_HL] & 0x0F) + flag_CBit); flag_C = reg_A < temp; reg_A = (byte)(reg_A - temp); flag_Z = (reg_A == 0x00); flag_N = true; + } + + // AND 8bit + public void AND_A() { reg_A &= reg_A; flag_Z = reg_A == 0x00; flag_N = false; flag_H = true; flag_C = false; } + public void AND_B() { reg_A &= reg_B; flag_Z = reg_A == 0x00; flag_N = false; flag_H = true; flag_C = false; } + public void AND_C() { reg_A &= reg_C; flag_Z = reg_A == 0x00; flag_N = false; flag_H = true; flag_C = false; } + public void AND_D() { reg_A &= reg_D; flag_Z = reg_A == 0x00; flag_N = false; flag_H = true; flag_C = false; } + public void AND_E() { reg_A &= reg_E; flag_Z = reg_A == 0x00; flag_N = false; flag_H = true; flag_C = false; } + public void AND_H() { reg_A &= reg_H; flag_Z = reg_A == 0x00; flag_N = false; flag_H = true; flag_C = false; } + public void AND_L() { reg_A &= reg_L; flag_Z = reg_A == 0x00; flag_N = false; flag_H = true; flag_C = false; } + public void AND_d8() { reg_A &= data8; flag_Z = reg_A == 0x00; flag_N = false; flag_H = true; flag_C = false; } + public void AND_aHL() { reg_A &= _memory[reg_HL]; flag_Z = reg_A == 0x00; flag_N = false; flag_H = true; flag_C = false; } + + // OR 8bit + public void OR_A() { reg_A |= reg_A; flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; flag_C = false; } + public void OR_B() { reg_A |= reg_B; flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; flag_C = false; } + public void OR_C() { reg_A |= reg_C; flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; flag_C = false; } + public void OR_D() { reg_A |= reg_D; flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; flag_C = false; } + public void OR_E() { reg_A |= reg_E; flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; flag_C = false; } + public void OR_H() { reg_A |= reg_H; flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; flag_C = false; } + public void OR_L() { reg_A |= reg_L; flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; flag_C = false; } + public void OR_d8() { reg_A |= data8; flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; flag_C = false; } + public void OR_aHL() { reg_A |= _memory[reg_HL]; flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; flag_C = false; } + + // XOR 8bit + public void XOR_A() { reg_A ^= reg_A; flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; flag_C = false; } + public void XOR_B() { reg_A ^= reg_B; flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; flag_C = false; } + public void XOR_C() { reg_A ^= reg_C; flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; flag_C = false; } + public void XOR_D() { reg_A ^= reg_D; flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; flag_C = false; } + public void XOR_E() { reg_A ^= reg_E; flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; flag_C = false; } + public void XOR_H() { reg_A ^= reg_H; flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; flag_C = false; } + public void XOR_L() { reg_A ^= reg_L; flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; flag_C = false; } + public void XOR_d8() { reg_A ^= data8; flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; flag_C = false; } + public void XOR_aHL() { reg_A ^= _memory[reg_HL]; flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; flag_C = false; } + + // CP + public void CP_A() { flag_Z = true; flag_N = true; flag_H = (reg_A & 0x0F) < (reg_A & 0x0F); flag_C = false; } + public void CP_B() { flag_Z = reg_A == reg_B; flag_N = true; flag_H = (reg_A & 0x0F) < (reg_B & 0x0F); flag_C = reg_A < reg_B; } + public void CP_C() { flag_Z = reg_A == reg_C; flag_N = true; flag_H = (reg_A & 0x0F) < (reg_C & 0x0F); flag_C = reg_A < reg_C; } + public void CP_D() { flag_Z = reg_A == reg_D; flag_N = true; flag_H = (reg_A & 0x0F) < (reg_D & 0x0F); flag_C = reg_A < reg_D; } + public void CP_E() { flag_Z = reg_A == reg_E; flag_N = true; flag_H = (reg_A & 0x0F) < (reg_E & 0x0F); flag_C = reg_A < reg_E; } + public void CP_H() { flag_Z = reg_A == reg_H; flag_N = true; flag_H = (reg_A & 0x0F) < (reg_H & 0x0F); flag_C = reg_A < reg_H; } + public void CP_L() { flag_Z = reg_A == reg_L; flag_N = true; flag_H = (reg_A & 0x0F) < (reg_L & 0x0F); flag_C = reg_A < reg_L; } + public void CP_d8() { flag_Z = (reg_A == data8); flag_N = true; flag_H = (reg_A & 0x0F) < (data8 & 0x0F); flag_C = reg_A < data8; } + public void CP_aHL() { flag_Z = reg_A == _memory[reg_HL]; flag_N = true; flag_H = (reg_A & 0x0F) < (_memory[reg_HL] & 0x0F); flag_C = reg_A < _memory[reg_HL]; } + + // DAA + public void DAA() + { + int temp = reg_A; + + // ADD/ADC + if (!flag_N) + { + if (flag_H || ((temp & 0xF) > 9)) + temp += 0x06; + + if (flag_C || (temp > 0x9F)) + temp += 0x60; + } + // SUB/SBC + else + { + if (flag_H) + temp = (temp - 6) & 0xFF; + + if (flag_C) + temp -= 0x60; + } + + flag_H = false; + flag_Z = (temp & 0xFF) == 0x00; + + if ((temp & 0x100) == 0x100) + flag_C = true; + + temp &= 0xFF; + + reg_A = (byte)temp; + } + public void CPL() { reg_A = (byte)(~reg_A); flag_N = true; flag_H = true; } + public void SCF() { flag_N = false; flag_H = false; flag_C = true; } + public void CCF() { flag_N = false; flag_H = false; flag_C = !flag_C; } + + // JP/JR + public void JP_a16() { reg_PC = data16; } + public void JP_aHL() { reg_PC = reg_HL; } + public void JP_NZ_a16() { if (!flag_Z) { JP_a16(); cycleCount += 4; } } + public void JP_Z_a16() { if (flag_Z) { JP_a16(); cycleCount += 4; } } + public void JP_NC_a16() { if (!flag_C) { JP_a16(); cycleCount += 4; } } + public void JP_C_a16() { if (flag_C) { JP_a16(); cycleCount += 4; } } + + public void JR_d8() { reg_PC = (ushort)(reg_PC + (sbyte)data8); } + public void JR_NZ_a8() { if (!flag_Z) { JR_d8(); cycleCount += 4; } } + public void JR_Z_a8() { if (flag_Z) { JR_d8(); cycleCount += 4; } } + public void JR_NC_a8() { if (!flag_C) { JR_d8(); cycleCount += 4; } } + public void JR_C_a8() { if (flag_C) { JR_d8(); cycleCount += 4; } } + + // POP/PUSH + public void POP_AF() { reg_F = (byte)(_memory[reg_SP++] & 0xF0); reg_A = _memory[reg_SP++]; } + public void POP_BC() { reg_C = _memory[reg_SP++]; reg_B = _memory[reg_SP++]; } + public void POP_DE() { reg_E = _memory[reg_SP++]; reg_D = _memory[reg_SP++]; } + public void POP_HL() { reg_L = _memory[reg_SP++]; reg_H = _memory[reg_SP++]; } + + public void PUSH_AF() { _memory[--reg_SP] = reg_A; _memory[--reg_SP] = reg_F; } + public void PUSH_BC() { _memory[--reg_SP] = reg_B; _memory[--reg_SP] = reg_C; } + public void PUSH_DE() { _memory[--reg_SP] = reg_D; _memory[--reg_SP] = reg_E; } + public void PUSH_HL() { _memory[--reg_SP] = reg_H; _memory[--reg_SP] = reg_L; } + + // Returns + public void RET() { reg_PC = (ushort)(_memory[reg_SP++] | (_memory[reg_SP++] << 8)); } + public void RET_NZ() { if (!flag_Z) { RET(); cycleCount += 12; } } + public void RET_Z() { if (flag_Z) { RET(); cycleCount += 12; } } + public void RET_NC() { if (!flag_C) { RET(); cycleCount += 12; } } + public void RET_C() { if (flag_C) { RET(); cycleCount += 12; } } + + public void RETI() { RET(); EI(); } + + // CALL + public void CALL_a16() { _memory[--reg_SP] = (byte)(reg_PC >> 8); _memory[--reg_SP] = (byte)(reg_PC & 0xFF); reg_PC = data16; } + public void CALL_NZ_a16() { if (!flag_Z) { CALL_a16(); cycleCount += 12; } } + public void CALL_Z_a16() { if (flag_Z) { CALL_a16(); cycleCount += 12; } } + public void CALL_NC_a16() { if (!flag_C) { CALL_a16(); cycleCount += 12; } } + public void CALL_C_a16() { if (flag_C) { CALL_a16(); cycleCount += 12; } } + + // RST - Restart + public void RST_00H() { _memory[--reg_SP] = (byte)(reg_PC >> 8); _memory[--reg_SP] = (byte)(reg_PC & 0xFF); reg_PC = (ushort)(0x0000 + _cartridge.LoadAddress); } + public void RST_08H() { _memory[--reg_SP] = (byte)(reg_PC >> 8); _memory[--reg_SP] = (byte)(reg_PC & 0xFF); reg_PC = (ushort)(0x0008 + _cartridge.LoadAddress); } + public void RST_10H() { _memory[--reg_SP] = (byte)(reg_PC >> 8); _memory[--reg_SP] = (byte)(reg_PC & 0xFF); reg_PC = (ushort)(0x0010 + _cartridge.LoadAddress); } + public void RST_18H() { _memory[--reg_SP] = (byte)(reg_PC >> 8); _memory[--reg_SP] = (byte)(reg_PC & 0xFF); reg_PC = (ushort)(0x0018 + _cartridge.LoadAddress); } + public void RST_20H() { _memory[--reg_SP] = (byte)(reg_PC >> 8); _memory[--reg_SP] = (byte)(reg_PC & 0xFF); reg_PC = (ushort)(0x0020 + _cartridge.LoadAddress); } + public void RST_28H() { _memory[--reg_SP] = (byte)(reg_PC >> 8); _memory[--reg_SP] = (byte)(reg_PC & 0xFF); reg_PC = (ushort)(0x0028 + _cartridge.LoadAddress); } + public void RST_30H() { _memory[--reg_SP] = (byte)(reg_PC >> 8); _memory[--reg_SP] = (byte)(reg_PC & 0xFF); reg_PC = (ushort)(0x0030 + _cartridge.LoadAddress); } + public void RST_38H() { _memory[--reg_SP] = (byte)(reg_PC >> 8); _memory[--reg_SP] = (byte)(reg_PC & 0xFF); reg_PC = (ushort)(0x0038 + _cartridge.LoadAddress); } + + // RLCA + public void RLCA() { flag_C = (reg_A & 0x80) == 0x80; reg_A = (byte)((reg_A << 1) | (reg_A >> 7)); flag_Z = false; flag_N = false; flag_H = false; } + public void RRCA() { flag_C = (reg_A & 0x01) == 0x01; reg_A = (byte)((reg_A >> 1) | ((reg_A & 0x01) << 7)); flag_Z = false; flag_N = false; flag_H = false; } + public void RLA() { var temp = reg_A; reg_A = (byte)((reg_A << 1) | (flag_C ? 0x01 : 0x00)); flag_Z = false; flag_N = false; flag_H = false; flag_C = (temp & 0x80) == 0x80; } + public void RRA() { var temp = reg_A; reg_A = (byte)((reg_A >> 1) | (flag_C ? 0x80 : 0x00)); flag_Z = false; flag_N = false; flag_H = false; flag_C = (temp & 0x01) == 0x01; } + + // CB instructions + // RLC + public void RLC_A() { flag_C = (reg_A & 0x80) == 0x80; reg_A = (byte)(reg_A << 1 | (reg_A >> 7)); flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; } + public void RLC_B() { flag_C = (reg_B & 0x80) == 0x80; reg_B = (byte)(reg_B << 1 | (reg_B >> 7)); flag_Z = reg_B == 0x00; flag_N = false; flag_H = false; } + public void RLC_C() { flag_C = (reg_C & 0x80) == 0x80; reg_C = (byte)(reg_C << 1 | (reg_C >> 7)); flag_Z = reg_C == 0x00; flag_N = false; flag_H = false; } + public void RLC_D() { flag_C = (reg_D & 0x80) == 0x80; reg_D = (byte)(reg_D << 1 | (reg_D >> 7)); flag_Z = reg_D == 0x00; flag_N = false; flag_H = false; } + public void RLC_E() { flag_C = (reg_E & 0x80) == 0x80; reg_E = (byte)(reg_E << 1 | (reg_E >> 7)); flag_Z = reg_E == 0x00; flag_N = false; flag_H = false; } + public void RLC_H() { flag_C = (reg_H & 0x80) == 0x80; reg_H = (byte)(reg_H << 1 | (reg_H >> 7)); flag_Z = reg_H == 0x00; flag_N = false; flag_H = false; } + public void RLC_L() { flag_C = (reg_L & 0x80) == 0x80; reg_L = (byte)(reg_L << 1 | (reg_L >> 7)); flag_Z = reg_L == 0x00; flag_N = false; flag_H = false; } + public void RLC_aHL() + { + flag_C = (_memory[reg_HL] & 0x80) == 0x80; + _memory[reg_HL] = (byte)(_memory[reg_HL] << 1 | (_memory[reg_HL] >> 7)); flag_Z = _memory[reg_HL] == 0x00; flag_N = false; flag_H = false; + } + + // RRC + public void RRC_A() { flag_C = (reg_A & 0x01) == 0x01; reg_A = (byte)((reg_A >> 1) | ((reg_A & 0x01) << 7)); flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; } + public void RRC_B() { flag_C = (reg_B & 0x01) == 0x01; reg_B = (byte)((reg_B >> 1) | ((reg_B & 0x01) << 7)); flag_Z = reg_B == 0x00; flag_N = false; flag_H = false; } + public void RRC_C() { flag_C = (reg_C & 0x01) == 0x01; reg_C = (byte)((reg_C >> 1) | ((reg_C & 0x01) << 7)); flag_Z = reg_C == 0x00; flag_N = false; flag_H = false; } + public void RRC_D() { flag_C = (reg_D & 0x01) == 0x01; reg_D = (byte)((reg_D >> 1) | ((reg_D & 0x01) << 7)); flag_Z = reg_D == 0x00; flag_N = false; flag_H = false; } + public void RRC_E() { flag_C = (reg_E & 0x01) == 0x01; reg_E = (byte)((reg_E >> 1) | ((reg_E & 0x01) << 7)); flag_Z = reg_E == 0x00; flag_N = false; flag_H = false; } + public void RRC_H() { flag_C = (reg_H & 0x01) == 0x01; reg_H = (byte)((reg_H >> 1) | ((reg_H & 0x01) << 7)); flag_Z = reg_H == 0x00; flag_N = false; flag_H = false; } + public void RRC_L() { flag_C = (reg_L & 0x01) == 0x01; reg_L = (byte)((reg_L >> 1) | ((reg_L & 0x01) << 7)); flag_Z = reg_L == 0x00; flag_N = false; flag_H = false; } + public void RRC_aHL() + { + flag_C = (_memory[reg_HL] & 0x01) == 0x01; + _memory[reg_HL] = (byte)((_memory[reg_HL] >> 1) | ((_memory[reg_HL] & 0x01) << 7)); + flag_Z = _memory[reg_HL] == 0x00; flag_N = false; flag_H = false; + } + + // RL + public void RL_A() { var temp = reg_A; reg_A = (byte)((reg_A << 1) | (flag_C ? 1 : 0)); flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; flag_C = (temp & 0x80) == 0x80; } + public void RL_B() { var temp = reg_B; reg_B = (byte)((reg_B << 1) | (flag_C ? 1 : 0)); flag_Z = reg_B == 0x00; flag_N = false; flag_H = false; flag_C = (temp & 0x80) == 0x80; } + public void RL_C() { var temp = reg_C; reg_C = (byte)((reg_C << 1) | (flag_C ? 1 : 0)); flag_Z = reg_C == 0x00; flag_N = false; flag_H = false; flag_C = (temp & 0x80) == 0x80; } + public void RL_D() { var temp = reg_D; reg_D = (byte)((reg_D << 1) | (flag_C ? 1 : 0)); flag_Z = reg_D == 0x00; flag_N = false; flag_H = false; flag_C = (temp & 0x80) == 0x80; } + public void RL_E() { var temp = reg_E; reg_E = (byte)((reg_E << 1) | (flag_C ? 1 : 0)); flag_Z = reg_E == 0x00; flag_N = false; flag_H = false; flag_C = (temp & 0x80) == 0x80; } + public void RL_H() { var temp = reg_H; reg_H = (byte)((reg_H << 1) | (flag_C ? 1 : 0)); flag_Z = reg_H == 0x00; flag_N = false; flag_H = false; flag_C = (temp & 0x80) == 0x80; } + public void RL_L() { var temp = reg_L; reg_L = (byte)((reg_L << 1) | (flag_C ? 1 : 0)); flag_Z = reg_L == 0x00; flag_N = false; flag_H = false; flag_C = (temp & 0x80) == 0x80; } + public void RL_aHL() + { + var temp = _memory[reg_HL]; _memory[reg_HL] = (byte)((_memory[reg_HL] << 1) | (flag_C ? 1 : 0)); + flag_Z = _memory[reg_HL] == 0x00; flag_N = false; flag_H = false; flag_C = (temp & 0x80) == 0x80; + } + + // RR + public void RR_A() { var temp = reg_A; reg_A = (byte)((reg_A >> 1) | (flag_C ? 0x80 : 0)); flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; flag_C = (temp & 0x01) == 0x01; } + public void RR_B() { var temp = reg_B; reg_B = (byte)((reg_B >> 1) | (flag_C ? 0x80 : 0)); flag_Z = reg_B == 0x00; flag_N = false; flag_H = false; flag_C = (temp & 0x01) == 0x01; } + public void RR_C() { var temp = reg_C; reg_C = (byte)((reg_C >> 1) | (flag_C ? 0x80 : 0)); flag_Z = reg_C == 0x00; flag_N = false; flag_H = false; flag_C = (temp & 0x01) == 0x01; } + public void RR_D() { var temp = reg_D; reg_D = (byte)((reg_D >> 1) | (flag_C ? 0x80 : 0)); flag_Z = reg_D == 0x00; flag_N = false; flag_H = false; flag_C = (temp & 0x01) == 0x01; } + public void RR_E() { var temp = reg_E; reg_E = (byte)((reg_E >> 1) | (flag_C ? 0x80 : 0)); flag_Z = reg_E == 0x00; flag_N = false; flag_H = false; flag_C = (temp & 0x01) == 0x01; } + public void RR_H() { var temp = reg_H; reg_H = (byte)((reg_H >> 1) | (flag_C ? 0x80 : 0)); flag_Z = reg_H == 0x00; flag_N = false; flag_H = false; flag_C = (temp & 0x01) == 0x01; } + public void RR_L() { var temp = reg_L; reg_L = (byte)((reg_L >> 1) | (flag_C ? 0x80 : 0)); flag_Z = reg_L == 0x00; flag_N = false; flag_H = false; flag_C = (temp & 0x01) == 0x01; } + public void RR_aHL() + { + var temp = _memory[reg_HL]; _memory[reg_HL] = (byte)((_memory[reg_HL] >> 1) | (flag_C ? 0x80 : 0)); + flag_Z = _memory[reg_HL] == 0x00; flag_N = false; flag_H = false; flag_C = (temp & 0x01) == 0x01; + } + + // SLA + public void SLA_A() { flag_C = (reg_A & 0x80) == 0x80; reg_A = (byte)(reg_A << 1); flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; } + public void SLA_B() { flag_C = (reg_B & 0x80) == 0x80; reg_B = (byte)(reg_B << 1); flag_Z = reg_B == 0x00; flag_N = false; flag_H = false; } + public void SLA_C() { flag_C = (reg_C & 0x80) == 0x80; reg_C = (byte)(reg_C << 1); flag_Z = reg_C == 0x00; flag_N = false; flag_H = false; } + public void SLA_D() { flag_C = (reg_D & 0x80) == 0x80; reg_D = (byte)(reg_D << 1); flag_Z = reg_D == 0x00; flag_N = false; flag_H = false; } + public void SLA_E() { flag_C = (reg_E & 0x80) == 0x80; reg_E = (byte)(reg_E << 1); flag_Z = reg_E == 0x00; flag_N = false; flag_H = false; } + public void SLA_H() { flag_C = (reg_H & 0x80) == 0x80; reg_H = (byte)(reg_H << 1); flag_Z = reg_H == 0x00; flag_N = false; flag_H = false; } + public void SLA_L() { flag_C = (reg_L & 0x80) == 0x80; reg_L = (byte)(reg_L << 1); flag_Z = reg_L == 0x00; flag_N = false; flag_H = false; } + public void SLA_aHL() + { + flag_C = (_memory[reg_HL] & 0x80) == 0x80; _memory[reg_HL] = (byte)(_memory[reg_HL] << 1); + flag_Z = _memory[reg_HL] == 0x00; flag_N = false; flag_H = false; + } + + // SRA + public void SRA_A() { flag_C = (reg_A & 0x01) == 0x01; reg_A = (byte)((reg_A >> 1) | (reg_A & 0x80)); flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; } + public void SRA_B() { flag_C = (reg_B & 0x01) == 0x01; reg_B = (byte)((reg_B >> 1) | (reg_B & 0x80)); flag_Z = reg_B == 0x00; flag_N = false; flag_H = false; } + public void SRA_C() { flag_C = (reg_C & 0x01) == 0x01; reg_C = (byte)((reg_C >> 1) | (reg_C & 0x80)); flag_Z = reg_C == 0x00; flag_N = false; flag_H = false; } + public void SRA_D() { flag_C = (reg_D & 0x01) == 0x01; reg_D = (byte)((reg_D >> 1) | (reg_D & 0x80)); flag_Z = reg_D == 0x00; flag_N = false; flag_H = false; } + public void SRA_E() { flag_C = (reg_E & 0x01) == 0x01; reg_E = (byte)((reg_E >> 1) | (reg_E & 0x80)); flag_Z = reg_E == 0x00; flag_N = false; flag_H = false; } + public void SRA_H() { flag_C = (reg_H & 0x01) == 0x01; reg_H = (byte)((reg_H >> 1) | (reg_H & 0x80)); flag_Z = reg_H == 0x00; flag_N = false; flag_H = false; } + public void SRA_L() { flag_C = (reg_L & 0x01) == 0x01; reg_L = (byte)((reg_L >> 1) | (reg_L & 0x80)); flag_Z = reg_L == 0x00; flag_N = false; flag_H = false; } + public void SRA_aHL() + { + flag_C = (_memory[reg_HL] & 0x01) == 0x01; + _memory[reg_HL] = (byte)((_memory[reg_HL] >> 1) | (_memory[reg_HL] & 0x80)); + flag_Z = _memory[reg_HL] == 0x00; flag_N = false; flag_H = false; + } + + // SWAP + public void SWAP_A() { reg_A = (byte)((reg_A >> 4) | (reg_A << 4)); flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; flag_C = false; } + public void SWAP_B() { reg_B = (byte)((reg_B >> 4) | (reg_B << 4)); flag_Z = reg_B == 0x00; flag_N = false; flag_H = false; flag_C = false; } + public void SWAP_C() { reg_C = (byte)((reg_C >> 4) | (reg_C << 4)); flag_Z = reg_C == 0x00; flag_N = false; flag_H = false; flag_C = false; } + public void SWAP_D() { reg_D = (byte)((reg_D >> 4) | (reg_D << 4)); flag_Z = reg_D == 0x00; flag_N = false; flag_H = false; flag_C = false; } + public void SWAP_E() { reg_E = (byte)((reg_E >> 4) | (reg_E << 4)); flag_Z = reg_E == 0x00; flag_N = false; flag_H = false; flag_C = false; } + public void SWAP_H() { reg_H = (byte)((reg_H >> 4) | (reg_H << 4)); flag_Z = reg_H == 0x00; flag_N = false; flag_H = false; flag_C = false; } + public void SWAP_L() { reg_L = (byte)((reg_L >> 4) | (reg_L << 4)); flag_Z = reg_L == 0x00; flag_N = false; flag_H = false; flag_C = false; } + public void SWAP_aHL() + { + _memory[reg_HL] = (byte)((_memory[reg_HL] >> 4) | (_memory[reg_HL] << 4)); + flag_Z = _memory[reg_HL] == 0x00; flag_N = false; flag_H = false; flag_C = false; + } + + // SRL + public void SRL_A() { flag_C = (reg_A & 0x01) == 0x01; reg_A = (byte)(reg_A >> 1); flag_Z = reg_A == 0x00; flag_N = false; flag_H = false; } + public void SRL_B() { flag_C = (reg_B & 0x01) == 0x01; reg_B = (byte)(reg_B >> 1); flag_Z = reg_B == 0x00; flag_N = false; flag_H = false; } + public void SRL_C() { flag_C = (reg_C & 0x01) == 0x01; reg_C = (byte)(reg_C >> 1); flag_Z = reg_C == 0x00; flag_N = false; flag_H = false; } + public void SRL_D() { flag_C = (reg_D & 0x01) == 0x01; reg_D = (byte)(reg_D >> 1); flag_Z = reg_D == 0x00; flag_N = false; flag_H = false; } + public void SRL_E() { flag_C = (reg_E & 0x01) == 0x01; reg_E = (byte)(reg_E >> 1); flag_Z = reg_E == 0x00; flag_N = false; flag_H = false; } + public void SRL_H() { flag_C = (reg_H & 0x01) == 0x01; reg_H = (byte)(reg_H >> 1); flag_Z = reg_H == 0x00; flag_N = false; flag_H = false; } + public void SRL_L() { flag_C = (reg_L & 0x01) == 0x01; reg_L = (byte)(reg_L >> 1); flag_Z = reg_L == 0x00; flag_N = false; flag_H = false; } + public void SRL_aHL() + { + flag_C = (_memory[reg_HL] & 0x01) == 0x01; _memory[reg_HL] = (byte)(_memory[reg_HL] >> 1); + flag_Z = _memory[reg_HL] == 0x00; flag_N = false; flag_H = false; + } + + // RES + public void RES_0_A() { reg_A &= 0xFE; } + public void RES_0_B() { reg_B &= 0xFE; } + public void RES_0_C() { reg_C &= 0xFE; } + public void RES_0_D() { reg_D &= 0xFE; } + public void RES_0_E() { reg_E &= 0xFE; } + public void RES_0_H() { reg_H &= 0xFE; } + public void RES_0_L() { reg_L &= 0xFE; } + public void RES_0_aHL() { _memory[reg_HL] &= 0xFE; } + + public void RES_1_A() { reg_A &= 0xFD; } + public void RES_1_B() { reg_B &= 0xFD; } + public void RES_1_C() { reg_C &= 0xFD; } + public void RES_1_D() { reg_D &= 0xFD; } + public void RES_1_E() { reg_E &= 0xFD; } + public void RES_1_H() { reg_H &= 0xFD; } + public void RES_1_L() { reg_L &= 0xFD; } + public void RES_1_aHL() { _memory[reg_HL] &= 0xFD; } + + public void RES_2_A() { reg_A &= 0xFB; } + public void RES_2_B() { reg_B &= 0xFB; } + public void RES_2_C() { reg_C &= 0xFB; } + public void RES_2_D() { reg_D &= 0xFB; } + public void RES_2_E() { reg_E &= 0xFB; } + public void RES_2_H() { reg_H &= 0xFB; } + public void RES_2_L() { reg_L &= 0xFB; } + public void RES_2_aHL() { _memory[reg_HL] &= 0xFB; } + + public void RES_3_A() { reg_A &= 0xF7; } + public void RES_3_B() { reg_B &= 0xF7; } + public void RES_3_C() { reg_C &= 0xF7; } + public void RES_3_D() { reg_D &= 0xF7; } + public void RES_3_E() { reg_E &= 0xF7; } + public void RES_3_H() { reg_H &= 0xF7; } + public void RES_3_L() { reg_L &= 0xF7; } + public void RES_3_aHL() { _memory[reg_HL] &= 0xF7; } + + public void RES_4_A() { reg_A &= 0xEF; } + public void RES_4_B() { reg_B &= 0xEF; } + public void RES_4_C() { reg_C &= 0xEF; } + public void RES_4_D() { reg_D &= 0xEF; } + public void RES_4_E() { reg_E &= 0xEF; } + public void RES_4_H() { reg_H &= 0xEF; } + public void RES_4_L() { reg_L &= 0xEF; } + public void RES_4_aHL() { _memory[reg_HL] &= 0xEF; } + + public void RES_5_A() { reg_A &= 0xDF; } + public void RES_5_B() { reg_B &= 0xDF; } + public void RES_5_C() { reg_C &= 0xDF; } + public void RES_5_D() { reg_D &= 0xDF; } + public void RES_5_E() { reg_E &= 0xDF; } + public void RES_5_H() { reg_H &= 0xDF; } + public void RES_5_L() { reg_L &= 0xDF; } + public void RES_5_aHL() { _memory[reg_HL] &= 0xDF; } + + public void RES_6_A() { reg_A &= 0xBF; } + public void RES_6_B() { reg_B &= 0xBF; } + public void RES_6_C() { reg_C &= 0xBF; } + public void RES_6_D() { reg_D &= 0xBF; } + public void RES_6_E() { reg_E &= 0xBF; } + public void RES_6_H() { reg_H &= 0xBF; } + public void RES_6_L() { reg_L &= 0xBF; } + public void RES_6_aHL() { _memory[reg_HL] &= 0xBF; } + + public void RES_7_A() { reg_A &= 0x7F; } + public void RES_7_B() { reg_B &= 0x7F; } + public void RES_7_C() { reg_C &= 0x7F; } + public void RES_7_D() { reg_D &= 0x7F; } + public void RES_7_E() { reg_E &= 0x7F; } + public void RES_7_H() { reg_H &= 0x7F; } + public void RES_7_L() { reg_L &= 0x7F; } + public void RES_7_aHL() { _memory[reg_HL] &= 0x7F; } + + // SET + public void SET_0_A() { reg_A |= 0x01; } + public void SET_0_B() { reg_B |= 0x01; } + public void SET_0_C() { reg_C |= 0x01; } + public void SET_0_D() { reg_D |= 0x01; } + public void SET_0_E() { reg_E |= 0x01; } + public void SET_0_H() { reg_H |= 0x01; } + public void SET_0_L() { reg_L |= 0x01; } + public void SET_0_aHL() { _memory[reg_HL] |= 0x01; } + + public void SET_1_A() { reg_A |= 0x02; } + public void SET_1_B() { reg_B |= 0x02; } + public void SET_1_C() { reg_C |= 0x02; } + public void SET_1_D() { reg_D |= 0x02; } + public void SET_1_E() { reg_E |= 0x02; } + public void SET_1_H() { reg_H |= 0x02; } + public void SET_1_L() { reg_L |= 0x02; } + public void SET_1_aHL() { _memory[reg_HL] |= 0x02; } + + public void SET_2_A() { reg_A |= 0x04; } + public void SET_2_B() { reg_B |= 0x04; } + public void SET_2_C() { reg_C |= 0x04; } + public void SET_2_D() { reg_D |= 0x04; } + public void SET_2_E() { reg_E |= 0x04; } + public void SET_2_H() { reg_H |= 0x04; } + public void SET_2_L() { reg_L |= 0x04; } + public void SET_2_aHL() { _memory[reg_HL] |= 0x04; } + + public void SET_3_A() { reg_A |= 0x08; } + public void SET_3_B() { reg_B |= 0x08; } + public void SET_3_C() { reg_C |= 0x08; } + public void SET_3_D() { reg_D |= 0x08; } + public void SET_3_E() { reg_E |= 0x08; } + public void SET_3_H() { reg_H |= 0x08; } + public void SET_3_L() { reg_L |= 0x08; } + public void SET_3_aHL() { _memory[reg_HL] |= 0x08; } + + public void SET_4_A() { reg_A |= 0x10; } + public void SET_4_B() { reg_B |= 0x10; } + public void SET_4_C() { reg_C |= 0x10; } + public void SET_4_D() { reg_D |= 0x10; } + public void SET_4_E() { reg_E |= 0x10; } + public void SET_4_H() { reg_H |= 0x10; } + public void SET_4_L() { reg_L |= 0x10; } + public void SET_4_aHL() { _memory[reg_HL] |= 0x10; } + + public void SET_5_A() { reg_A |= 0x20; } + public void SET_5_B() { reg_B |= 0x20; } + public void SET_5_C() { reg_C |= 0x20; } + public void SET_5_D() { reg_D |= 0x20; } + public void SET_5_E() { reg_E |= 0x20; } + public void SET_5_H() { reg_H |= 0x20; } + public void SET_5_L() { reg_L |= 0x20; } + public void SET_5_aHL() { _memory[reg_HL] |= 0x20; } + + public void SET_6_A() { reg_A |= 0x40; } + public void SET_6_B() { reg_B |= 0x40; } + public void SET_6_C() { reg_C |= 0x40; } + public void SET_6_D() { reg_D |= 0x40; } + public void SET_6_E() { reg_E |= 0x40; } + public void SET_6_H() { reg_H |= 0x40; } + public void SET_6_L() { reg_L |= 0x40; } + public void SET_6_aHL() { _memory[reg_HL] |= 0x40; } + + public void SET_7_A() { reg_A |= 0x80; } + public void SET_7_B() { reg_B |= 0x80; } + public void SET_7_C() { reg_C |= 0x80; } + public void SET_7_D() { reg_D |= 0x80; } + public void SET_7_E() { reg_E |= 0x80; } + public void SET_7_H() { reg_H |= 0x80; } + public void SET_7_L() { reg_L |= 0x80; } + public void SET_7_aHL() { _memory[reg_HL] |= 0x80; } + + // BIT + public void BIT_0_A() { flag_Z = (reg_A & 0x01) == 0x00; flag_N = false; flag_H = true; } + public void BIT_0_B() { flag_Z = (reg_B & 0x01) == 0x00; flag_N = false; flag_H = true; } + public void BIT_0_C() { flag_Z = (reg_C & 0x01) == 0x00; flag_N = false; flag_H = true; } + public void BIT_0_D() { flag_Z = (reg_D & 0x01) == 0x00; flag_N = false; flag_H = true; } + public void BIT_0_E() { flag_Z = (reg_E & 0x01) == 0x00; flag_N = false; flag_H = true; } + public void BIT_0_H() { flag_Z = (reg_H & 0x01) == 0x00; flag_N = false; flag_H = true; } + public void BIT_0_L() { flag_Z = (reg_L & 0x01) == 0x00; flag_N = false; flag_H = true; } + public void BIT_0_aHL() { flag_Z = (_memory[reg_HL] & 0x01) == 0x00; flag_N = false; flag_H = true; } + + public void BIT_1_A() { flag_Z = (reg_A & 0x02) == 0x00; flag_N = false; flag_H = true; } + public void BIT_1_B() { flag_Z = (reg_B & 0x02) == 0x00; flag_N = false; flag_H = true; } + public void BIT_1_C() { flag_Z = (reg_C & 0x02) == 0x00; flag_N = false; flag_H = true; } + public void BIT_1_D() { flag_Z = (reg_D & 0x02) == 0x00; flag_N = false; flag_H = true; } + public void BIT_1_E() { flag_Z = (reg_E & 0x02) == 0x00; flag_N = false; flag_H = true; } + public void BIT_1_H() { flag_Z = (reg_H & 0x02) == 0x00; flag_N = false; flag_H = true; } + public void BIT_1_L() { flag_Z = (reg_L & 0x02) == 0x00; flag_N = false; flag_H = true; } + public void BIT_1_aHL() { flag_Z = (_memory[reg_HL] & 0x02) == 0x00; flag_N = false; flag_H = true; } + + public void BIT_2_A() { flag_Z = (reg_A & 0x04) == 0x00; flag_N = false; flag_H = true; } + public void BIT_2_B() { flag_Z = (reg_B & 0x04) == 0x00; flag_N = false; flag_H = true; } + public void BIT_2_C() { flag_Z = (reg_C & 0x04) == 0x00; flag_N = false; flag_H = true; } + public void BIT_2_D() { flag_Z = (reg_D & 0x04) == 0x00; flag_N = false; flag_H = true; } + public void BIT_2_E() { flag_Z = (reg_E & 0x04) == 0x00; flag_N = false; flag_H = true; } + public void BIT_2_H() { flag_Z = (reg_H & 0x04) == 0x00; flag_N = false; flag_H = true; } + public void BIT_2_L() { flag_Z = (reg_L & 0x04) == 0x00; flag_N = false; flag_H = true; } + public void BIT_2_aHL() { flag_Z = (_memory[reg_HL] & 0x04) == 0x00; flag_N = false; flag_H = true; } + + public void BIT_3_A() { flag_Z = (reg_A & 0x08) == 0x00; flag_N = false; flag_H = true; } + public void BIT_3_B() { flag_Z = (reg_B & 0x08) == 0x00; flag_N = false; flag_H = true; } + public void BIT_3_C() { flag_Z = (reg_C & 0x08) == 0x00; flag_N = false; flag_H = true; } + public void BIT_3_D() { flag_Z = (reg_D & 0x08) == 0x00; flag_N = false; flag_H = true; } + public void BIT_3_E() { flag_Z = (reg_E & 0x08) == 0x00; flag_N = false; flag_H = true; } + public void BIT_3_H() { flag_Z = (reg_H & 0x08) == 0x00; flag_N = false; flag_H = true; } + public void BIT_3_L() { flag_Z = (reg_L & 0x08) == 0x00; flag_N = false; flag_H = true; } + public void BIT_3_aHL() { flag_Z = (_memory[reg_HL] & 0x08) == 0x00; flag_N = false; flag_H = true; } + + public void BIT_4_A() { flag_Z = (reg_A & 0x10) == 0x00; flag_N = false; flag_H = true; } + public void BIT_4_B() { flag_Z = (reg_B & 0x10) == 0x00; flag_N = false; flag_H = true; } + public void BIT_4_C() { flag_Z = (reg_C & 0x10) == 0x00; flag_N = false; flag_H = true; } + public void BIT_4_D() { flag_Z = (reg_D & 0x10) == 0x00; flag_N = false; flag_H = true; } + public void BIT_4_E() { flag_Z = (reg_E & 0x10) == 0x00; flag_N = false; flag_H = true; } + public void BIT_4_H() { flag_Z = (reg_H & 0x10) == 0x00; flag_N = false; flag_H = true; } + public void BIT_4_L() { flag_Z = (reg_L & 0x10) == 0x00; flag_N = false; flag_H = true; } + public void BIT_4_aHL() { flag_Z = (_memory[reg_HL] & 0x10) == 0x00; flag_N = false; flag_H = true; } + + public void BIT_5_A() { flag_Z = (reg_A & 0x20) == 0x00; flag_N = false; flag_H = true; } + public void BIT_5_B() { flag_Z = (reg_B & 0x20) == 0x00; flag_N = false; flag_H = true; } + public void BIT_5_C() { flag_Z = (reg_C & 0x20) == 0x00; flag_N = false; flag_H = true; } + public void BIT_5_D() { flag_Z = (reg_D & 0x20) == 0x00; flag_N = false; flag_H = true; } + public void BIT_5_E() { flag_Z = (reg_E & 0x20) == 0x00; flag_N = false; flag_H = true; } + public void BIT_5_H() { flag_Z = (reg_H & 0x20) == 0x00; flag_N = false; flag_H = true; } + public void BIT_5_L() { flag_Z = (reg_L & 0x20) == 0x00; flag_N = false; flag_H = true; } + public void BIT_5_aHL() { flag_Z = (_memory[reg_HL] & 0x20) == 0x00; flag_N = false; flag_H = true; } + + public void BIT_6_A() { flag_Z = (reg_A & 0x40) == 0x00; flag_N = false; flag_H = true; } + public void BIT_6_B() { flag_Z = (reg_B & 0x40) == 0x00; flag_N = false; flag_H = true; } + public void BIT_6_C() { flag_Z = (reg_C & 0x40) == 0x00; flag_N = false; flag_H = true; } + public void BIT_6_D() { flag_Z = (reg_D & 0x40) == 0x00; flag_N = false; flag_H = true; } + public void BIT_6_E() { flag_Z = (reg_E & 0x40) == 0x00; flag_N = false; flag_H = true; } + public void BIT_6_H() { flag_Z = (reg_H & 0x40) == 0x00; flag_N = false; flag_H = true; } + public void BIT_6_L() { flag_Z = (reg_L & 0x40) == 0x00; flag_N = false; flag_H = true; } + public void BIT_6_aHL() { flag_Z = (_memory[reg_HL] & 0x40) == 0x00; flag_N = false; flag_H = true; } + + public void BIT_7_A() { flag_Z = (reg_A & 0x80) == 0x00; flag_N = false; flag_H = true; } + public void BIT_7_B() { flag_Z = (reg_B & 0x80) == 0x00; flag_N = false; flag_H = true; } + public void BIT_7_C() { flag_Z = (reg_C & 0x80) == 0x00; flag_N = false; flag_H = true; } + public void BIT_7_D() { flag_Z = (reg_D & 0x80) == 0x00; flag_N = false; flag_H = true; } + public void BIT_7_E() { flag_Z = (reg_E & 0x80) == 0x00; flag_N = false; flag_H = true; } + public void BIT_7_H() { flag_Z = (reg_H & 0x80) == 0x00; flag_N = false; flag_H = true; } + public void BIT_7_L() { flag_Z = (reg_L & 0x80) == 0x00; flag_N = false; flag_H = true; } + public void BIT_7_aHL() { flag_Z = (_memory[reg_HL] & 0x80) == 0x00; flag_N = false; flag_H = true; } + } +} diff --git a/GbsPlayer/GbsPlayer.cs b/GbsPlayer/GbsPlayer.cs new file mode 100644 index 0000000..ef5f275 --- /dev/null +++ b/GbsPlayer/GbsPlayer.cs @@ -0,0 +1,171 @@ +using System; +using System.IO; +using System.Threading; + +namespace GbsPlayer +{ + public class GbsPlayer + { + public GameBoyCPU Cpu; + public Cartridge Cartridge; + public GeneralMemory Memory; + public Sound SoundGenerator; + + public byte CurrentTrack; + + public bool GbsLoaded; + + private float _volume = 1; + private float _volumeMultiplier = 1.0f; + + private readonly object _updateLock = new object(); + private bool _exitThread; + + private Thread _updateThread; + + public GbsPlayer() + { + SoundGenerator = new Sound(); + Cartridge = new Cartridge(); + Memory = new GeneralMemory(Cartridge, SoundGenerator); + Cpu = new GameBoyCPU(Memory, Cartridge, SoundGenerator); + } + + public void OnExit() + { + _exitThread = true; + } + + public void LoadFile(string path) + { + Cartridge.ROM = File.ReadAllBytes(path); + + Cartridge.Init(); + Cpu.Init(); + + GbsLoaded = true; + + Console.WriteLine("finished loading file: {0}", path); + } + + public void ChangeTrack(int offset) + { + var newTrack = CurrentTrack + offset; + + while (newTrack < 0) + newTrack += Cartridge.TrackCount; + newTrack %= Cartridge.TrackCount; + + StartTrack((byte)newTrack); + } + + public void StartTrack(byte trackNr) + { + // directly init the new song if update is not called at this time + lock (_updateLock) + { + CurrentTrack = trackNr; + + // clear buffer; stop playback + SoundGenerator.Stop(); + + // init play + GbsInit(trackNr); + + SoundGenerator.SetStopTime(0); + } + } + + private void GbsInit(byte trackNumber) + { + Cartridge.Init(); + Cpu.SkipBootROM(); + Cpu.Init(); + Cpu.SetPlaybackSpeed(1); + + // tack number + Cpu.reg_A = trackNumber; + + Cpu.reg_PC = Cartridge.InitAddress; + Cpu.reg_SP = Cartridge.StackPointer; + + // push the idleAddress on the stack + Memory[--Cpu.reg_SP] = (byte)(Cpu.IdleAddress >> 0x8); + Memory[--Cpu.reg_SP] = (byte)(Cpu.IdleAddress & 0xFF); + + Console.WriteLine("finished gbs init"); + } + + public void Play() + { + Cpu.IsRunning = true; + } + + public void Pause() + { + SoundGenerator.Pause(); + Cpu.IsRunning = false; + } + + public void Resume() + { + SoundGenerator.Resume(); + Cpu.IsRunning = true; + } + + public void Stop() + { + // stop music playback + SoundGenerator.Stop(); + Cpu.IsRunning = false; + } + + public float GetVolume() + { + return _volume; + } + + public void SetVolume(float volume) + { + _volume = volume; + SoundGenerator.SetVolume(_volume * _volumeMultiplier); + } + + public float GetVolumeMultiplier() + { + return _volumeMultiplier; + } + + public void SetVolumeMultiplier(float multiplier) + { + _volumeMultiplier = multiplier; + SoundGenerator.SetVolume(_volume * _volumeMultiplier); + } + + public void Update(float deltaTime) + { + Cpu.Update(); + } + + public void StartThread() + { + // thread is used to run the cpu and playback + _updateThread = new Thread(UpdateThread); + _updateThread.Start(); + } + + public void UpdateThread() + { + while (true) + { + if (_exitThread) + return; + + lock (_updateLock) + Cpu.Update(); + + Thread.Sleep(5); + } + } + } +} diff --git a/GbsPlayer/GeneralMemory.cs b/GbsPlayer/GeneralMemory.cs new file mode 100644 index 0000000..9ff21b3 --- /dev/null +++ b/GbsPlayer/GeneralMemory.cs @@ -0,0 +1,140 @@ +using System; + +namespace GbsPlayer +{ + public class GeneralMemory + { + private readonly Cartridge _cartridge; + private readonly Sound _gbSound; + + public byte[] Memory; + + public GeneralMemory(Cartridge cartridge, Sound gbSound) + { + _cartridge = cartridge; + _gbSound = gbSound; + } + + public void Init() + { + Memory = new byte[65536]; // 0x0000-0xFFFF + } + + public byte this[int index] + { + get + { + // Cartridge + if (index < 0x8000) + return _cartridge[index]; + if (0xA000 <= index && index < 0xE000) + { + // GBS: + // Player authors: you should disregard writes to $4000-$5fff and $ff70, and just implement main RAM from $a000 to $dfff. + return Memory[index]; + } + // shadow ram + if (0xE000 <= index && index < 0xFE00) + return Memory[index - 0x2000]; + // Sound registries + if (0xFF10 <= index && index <= 0xFF3F) + return _gbSound[index]; + // High RAM (HRAM) + if (0xFF80 <= index && index <= 0xFFFF) + return Memory[index]; + + Console.WriteLine("Read at 0x{0:X} not supported", index); + return 0; + } + set + { + // ROM + if (index < 0x8000) + { + _cartridge[index] = value; + } + // 8KB Video RAM (VRAM) + else if (index < 0xA000) + { + Console.WriteLine("VRAM not supported 0x{0:X}", index); + } + // Unit Working RAM + else if (index < 0xE000) + { + // GBS: + // Player authors: you should disregard writes to $4000-$5fff and $ff70, and just implement main RAM from $a000 to $dfff. + Memory[index] = value; + } + // shadow memory + else if (index < 0xFE00) + { + Memory[index - 0x2000] = value; + } + else if (index < 0xFF05) + { + Console.WriteLine("Write to 0x{0:X} not supported", index); + } + else if (index == 0xFF05) + { + // TIMA Timer Counter + Console.WriteLine("TIMA currently not supported"); + } + else if (index == 0xFF06) + { + // TMA Timer Modulo + Console.WriteLine("TMA currently not supported"); + } + // TAC + else if (index == 0xFF07) + { + // Bit 1 & 0, counter rate + // 00: 4096 Hz + // 01: 262144 Hz + // 10: 65536 Hz + // 11: 16384 Hz + + // Bit 2, interrupt type + // 0: Use v-blank + // 1: Use timer + + // Bit 6 - 3, reserved for expansion + // Set them to 0 + + // Bit 7, CPU clock rate + // 0: Use normal rate + // 1: Use 2x(fast) rate + + Console.WriteLine("TAC currently not supported"); + } + else if (index < 0xFF10) + { + Console.WriteLine("Write to 0x{0:X} not supported", index); + } + // Sound stuff + else if (0xFF10 <= index && index <= 0xFF3F) + { + _gbSound[index] = value; + } + else if (index < 0xFF80) + { + Console.WriteLine("Write to 0x{0:X} not supported", index); + } + // High RAM (HRAM) + else if (index < 0xFFFF) + { + Memory[index] = value; + } + // Interrupt Enable Register + else if (index == 0xFFFF) + { + Memory[index] = value; + } + // ERROR + else + { + Console.WriteLine("Error writing to high address"); + } + } + } + } +} diff --git a/GbsPlayer/OPCycle.cs b/GbsPlayer/OPCycle.cs new file mode 100644 index 0000000..30eddf5 --- /dev/null +++ b/GbsPlayer/OPCycle.cs @@ -0,0 +1,41 @@ +namespace GbsPlayer +{ + class OpCycle + { + public static byte[] CycleArray = { + 04,12,08,08,04,04,08,04,20,08,08,08,04,04,08,04, + 04,12,08,08,04,04,08,04,12,08,08,08,04,04,08,04, + 08,12,08,08,04,04,08,04,08,08,08,08,04,04,08,04, + 08,12,08,08,12,12,12,04,08,08,08,08,04,04,08,04, + 04,04,04,04,04,04,08,04,04,04,04,04,04,04,08,04, + 04,04,04,04,04,04,08,04,04,04,04,04,04,04,08,04, + 04,04,04,04,04,04,08,04,04,04,04,04,04,04,08,04, + 08,08,08,08,08,08,04,08,04,04,04,04,04,04,08,04, + 04,04,04,04,04,04,08,04,04,04,04,04,04,04,08,04, + 04,04,04,04,04,04,08,04,04,04,04,04,04,04,08,04, + 04,04,04,04,04,04,08,04,04,04,04,04,04,04,08,04, + 04,04,04,04,04,04,08,04,04,04,04,04,04,04,08,04, + 08,12,12,16,12,16,08,16,08,16,12,00,12,24,08,16, + 08,12,12,00,12,16,08,16,08,16,12,00,12,00,08,16, + 12,12,08,00,00,16,08,16,16,04,16,00,00,00,08,16, + 12,12,08,04,00,16,08,16,12,08,16,04,00,00,08,16 }; + + public static byte[] CycleCbArray = { + 08,08,08,08,08,08,16,08,08,08,08,08,08,08,16,08, + 08,08,08,08,08,08,16,08,08,08,08,08,08,08,16,08, + 08,08,08,08,08,08,16,08,08,08,08,08,08,08,16,08, + 08,08,08,08,08,08,16,08,08,08,08,08,08,08,16,08, + 08,08,08,08,08,08,12,08,08,08,08,08,08,08,12,08, + 08,08,08,08,08,08,12,08,08,08,08,08,08,08,12,08, + 08,08,08,08,08,08,12,08,08,08,08,08,08,08,12,08, + 08,08,08,08,08,08,12,08,08,08,08,08,08,08,12,08, + 08,08,08,08,08,08,16,08,08,08,08,08,08,08,16,08, + 08,08,08,08,08,08,16,08,08,08,08,08,08,08,16,08, + 08,08,08,08,08,08,16,08,08,08,08,08,08,08,16,08, + 08,08,08,08,08,08,16,08,08,08,08,08,08,08,16,08, + 08,08,08,08,08,08,16,08,08,08,08,08,08,08,16,08, + 08,08,08,08,08,08,16,08,08,08,08,08,08,08,16,08, + 08,08,08,08,08,08,16,08,08,08,08,08,08,08,16,08, + 08,08,08,08,08,08,16,08,08,08,08,08,08,08,16,08 }; + } +} diff --git a/GbsPlayer/OpLength.cs b/GbsPlayer/OpLength.cs new file mode 100644 index 0000000..464fdc4 --- /dev/null +++ b/GbsPlayer/OpLength.cs @@ -0,0 +1,23 @@ +namespace GbsPlayer +{ + class OpLength + { + public static byte[] LengthTable = { + 01,03,01,01,01,01,02,01,03,01,01,01,01,01,02,01, + 01,03,01,01,01,01,02,01,02,01,01,01,01,01,02,01, + 02,03,01,01,01,01,02,01,02,01,01,01,01,01,02,01, + 02,03,01,01,01,01,02,01,02,01,01,01,01,01,02,01, + 01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01, + 01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01, + 01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01, + 01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01, + 01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01, + 01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01, + 01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01, + 01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01, + 01,01,03,03,03,01,02,01,01,01,03,01,03,03,02,01, + 01,01,03,00,03,01,02,01,01,01,03,00,03,00,02,01, + 02,01,01,00,00,01,02,01,02,01,03,00,00,00,02,01, + 02,01,01,01,00,01,02,01,02,01,03,01,00,00,02,01 }; + } +} diff --git a/GbsPlayer/Sound.cs b/GbsPlayer/Sound.cs new file mode 100644 index 0000000..54d3e3a --- /dev/null +++ b/GbsPlayer/Sound.cs @@ -0,0 +1,775 @@ +using System; +using Microsoft.Xna.Framework.Audio; + +namespace GbsPlayer +{ + public class Sound + { + public CDynamicEffectInstance _soundOutput; + + public bool WasStopped; + private int _endBufferCount; + private int _bufferCount; + + private const int OutputRate = 44100; + //private const int OutputRate = 48000; + + private byte[] _soundBuffer = new byte[(OutputRate / 100) * 2]; // 100 buffers per second + private int _bufferIndex; + + // FF10-FF3F + private byte[] _soundRegister = new byte[0x30]; + + // frame sequencer + private int _frameSequencerTimer; + private byte _frameSequencerCounter; + + // Square 1 + private byte _modeOneNumberOfSweepShifts; + private bool _modeOneSweepSubtraction; + private byte _modeOneSweepTime; + private byte _modeOneSweepCounter; + + private float _modeOneWavePatternDutyPercentage; + + private int _square1LengthLoad; + private byte _square1LengthCounter; + + // envelope + private byte _square1StartVolume; + private bool _square1EnvelopeAddMode; + private byte _square1EnvelopePeriod; + private int _square1EnvelopeCounter; + private int _square1Volume; + + private short _square1Frequency; + private double _modeOneFreqCounter; + private double _modeOneFreqTime; + private bool _modeOneFreqDuty; + private byte _square1WaveCounter; + + private bool _modeOneCounterEnable; + + private bool _square1Running; + private int _waveOne = 1; + + + // Square 2 + private float _modeTwoWavePatternDutyPercentage; + + private byte _square2StartVolume; + private bool _square2EnvelopeAddMode; + private byte _square2EnvelopePeriod; + private int _square2EnvelopeCounter; + private int _square2Volume; + + private byte _square2LengthCounter; + private int _modeTwoSoundLength; + + private short _square2Frequency; + private double _modeTwoFreqTime; + private double _modeTwoFreqCounter; + private byte _square2WaveCounter; + + private bool _modeTwoCounterEnable; + + private bool _square2Running; + private int _waveTwo = 1; + + + // Wave + private bool _waveDACpower; + + private byte _waveLengthCounter; + private int _modeThreeSoundLength; + + private byte _waveVolumeCode; + + private short _modeThreeFrequency; + + private double _modeThreeFreqCounter; + private double _modeThreeFreqTime; + + private bool _waveTrigger; + private bool _waveLengthEnable; + + private byte[] _waveNibbles = new byte[32]; + private int _waveIndex; + + private short _waveThree; + + // Noise + private byte _noiseLengthLoad; + private byte _noiseVolume; + private byte _noiseInitVolume; + private bool _noiseEnvelopeAddMode; + private byte _noiseEnvelopePeriod; + + private byte _noiseClockShift; + private bool _noiseWidthMode; + private byte _noiseDivisorCode; + + private bool _noiseTrigger; + private bool _noiseLengthEnable; + + private short _noiseLfsr; + + private double _noiseTimeSteps; + + private int _noiseEnvelopeCounter; + + private byte _noiseLengthCounter; + + // FF24 + private byte _soundOutputLevel; + // FF25 + private byte _channelLeftRightControl; + // FF26 + private byte _soundOnOff; + + private double _highPassFilterCapacitor; + + public int DebugCounter; + + public Sound() + { + _soundOutput = new CDynamicEffectInstance(OutputRate); + } + + public void Init() + { + _frameSequencerTimer = 0; + _frameSequencerCounter = 0; + + _square1LengthCounter = 0; + _square2LengthCounter = 0; + _waveLengthCounter = 0; + _noiseLengthCounter = 0; + + _modeOneFreqCounter = 0; + _modeTwoFreqCounter = 0; + _modeThreeFreqCounter = 0; + + _square1EnvelopeCounter = 0; + _square2EnvelopeCounter = 0; + _noiseEnvelopeCounter = 0; + + _highPassFilterCapacitor = 0; + + _bufferIndex = 0; + WasStopped = false; + } + + public bool IsPlaying() + { + return _soundOutput.State == SoundState.Playing; + } + + public bool FinishedPlaying() + { + return _soundOutput.GetPendingBufferCount() == 0; + } + + public void SetStopTime(float length) + { + _endBufferCount = (int)(length * OutputRate); + } + + public void Play() + { + _soundOutput.Play(); + } + + public void Pause() + { + _soundOutput.Pause(); + } + + public void Resume() + { + _soundOutput.Resume(); + } + + public void Stop() + { + _bufferCount = 0; + _bufferIndex = 0; + _soundOutput.Stop(); + } + + public void SetVolume(float volume) + { + _soundOutput.SetVolume(volume); + } + + public void AddCurrentBuffer() + { + _soundOutput.SubmitBuffer(_soundBuffer, 0, _bufferIndex); + _bufferIndex = 0; + } + + public byte this[int index] + { + get + { + Console.WriteLine("Get Index 0x{0:X}", index); + + // Square 1 + if (index == 0xFF10) + return _soundRegister[index - 0xFF10]; + if (index == 0xFF11) + return (byte)(_soundRegister[index - 0xFF10] & 0xC0); + if (index == 0xFF12) + return _soundRegister[index - 0xFF10]; + if (index == 0xFF13) + return 0; + if (index == 0xFF14) + return _soundRegister[index - 0xFF10]; + + // Square 2 + if (index == 0xFF15) // not used + return 0; + if (index == 0xFF16) + return (byte)(_soundRegister[index - 0xFF10] & 0xC0); + if (index == 0xFF17) + return _soundRegister[index - 0xFF10]; + if (index == 0xFF18) + return 0; + if (index == 0xFF19) + return _soundRegister[index - 0xFF10]; + + // Wave + if (index == 0xFF1A) + return (byte)(_waveDACpower ? 0x80 : 0x00); + if (index == 0xFF1B) + return 0; + if (index == 0xFF1C) + return (byte)(_waveVolumeCode << 5); + if (index == 0xFF1D) + return 0; + if (index == 0xFF1E) + return (byte)(_waveLengthEnable ? 0x40 : 0x00); + + // Noise + if (0xFF1F <= index && index <= 0xFF23) + { + + } + + // Stuff + if (index == 0xFF24) + return _soundOutputLevel; + if (index == 0xFF25) + return _channelLeftRightControl; + if (index == 0xFF26) + return _soundOnOff; + + return _soundRegister[index - 0xFF10]; + } + set + { + // Square 1 + if (index == 0xFF10) + { + _soundRegister[index - 0xFF10] = (byte)(value & 0x7F); + + _modeOneNumberOfSweepShifts = (byte)(value & 0x07); + _modeOneSweepSubtraction = (value & 0x08) == 0x08; + _modeOneSweepTime = (byte)((value & 0x70) >> 4); + + _modeOneSweepCounter = 0; + } + else if (index == 0xFF11) + { + _soundRegister[index - 0xFF10] = (byte)(value & 0xC7); + + // Sound Length = (64-t1) * (1/256) sec + _square1LengthLoad = 64 - (byte)(value & 0x3F); // was 0x07 before? + + // 12.5, 25, 50, 75 + var waveDuty = (byte)(value >> 6); + _modeOneWavePatternDutyPercentage = waveDuty == 0 ? 1 : (waveDuty * 2); + } + else if (index == 0xFF12) + { + _soundRegister[index - 0xFF10] = value; + + _square1StartVolume = (byte)(value >> 4); + _square1EnvelopeAddMode = (value & 0x08) == 0x08; + _square1EnvelopePeriod = (byte)(value & 0x07); + } + else if (index == 0xFF13) + { + _soundRegister[index - 0xFF10] = value; + + _square1Frequency = (short)((_square1Frequency & 0x700) + value); // this was 0xF00 before + UpdateSquare1FrequencyTime(); + } + else if (index == 0xFF14) + { + _soundRegister[index - 0xFF10] = (byte)(value & 0x40); + + _square1Frequency = (short)(((value & 0x07) << 8) | (_square1Frequency & 0xFF)); + UpdateSquare1FrequencyTime(); + + _modeOneCounterEnable = (value & 0x40) == 0x40; + + if ((value & 0x80) == 0x80) + { + _square1Running = true; + + _soundOnOff |= 0x01; + + _square1LengthCounter = 0; + + // set to initial value + _square1Volume = _square1StartVolume; + // set the envelope counter to the period + _square1EnvelopeCounter = _square1EnvelopePeriod; + } + } + + // Square 2 + else if (index == 0xFF15) { } // not used + else if (index == 0xFF16) + { + _soundRegister[index - 0xFF10] = (byte)(value & 0xC7); + + // Sound Length = (64-t1) * (1/256) sec + _modeTwoSoundLength = 64 - (byte)(value & 0x3F); + + // 12.5, 25, 50, 75 + var waveDuty = (byte)(value >> 6); + _modeTwoWavePatternDutyPercentage = waveDuty == 0 ? 1 : (waveDuty * 2); + } + else if (index == 0xFF17) + { + _soundRegister[index - 0xFF10] = value; + + _square2StartVolume = (byte)(value >> 4); + _square2EnvelopeAddMode = (value & 0x08) == 0x08; + _square2EnvelopePeriod = (byte)(value & 0x07); + } + else if (index == 0xFF18) + { + _soundRegister[index - 0xFF10] = value; + + _square2Frequency = (short)((_square2Frequency & 0x700) + value); // this was 0xF00 before + UpdateSquare2FrequencyTime(); + } + else if (index == 0xFF19) + { + _soundRegister[index - 0xFF10] = (byte)(value & 0x40); + + _square2Frequency = (short)(((value & 0x07) << 8) + (_square2Frequency & 0xFF)); + UpdateSquare2FrequencyTime(); + + _modeTwoCounterEnable = (value & 0x40) == 0x40; + + if ((value & 0x80) == 0x80) + { + _square2Running = true; + + _soundOnOff |= 0x02; + + _square2LengthCounter = 0; + + // set to initial value + _square2Volume = _square2StartVolume; + // set the envelope counter to the period + _square2EnvelopeCounter = _square2EnvelopePeriod; + } + } + + // Wave + else if (index == 0xFF1A) + { + _waveDACpower = (value & 0x80) == 0x80; + // When the sound OFF flag(bit 7 of NR30) is reset to "0", cancellation of the OFF mode must be performed by setting the sound OFF flag to a "1".This is performed by Sound 3. + } + else if (index == 0xFF1B) + { + // (256-t1) * (1/256) sec + _modeThreeSoundLength = 256 - value; + } + else if (index == 0xFF1C) + { + _waveVolumeCode = (byte)((value >> 5) & 0x03); + + if (_waveVolumeCode == 0x00) + { + _modeThreeFreqCounter = 0; + } + } + else if (index == 0xFF1D) + { + _modeThreeFrequency = (short)((_modeThreeFrequency & 0x700) + value); + UpdateWaveFrequencyTime(); + + _modeThreeFreqCounter = 0; + } + else if (index == 0xFF1E) + { + _modeThreeFrequency = (short)((_modeThreeFrequency & 0xFF) + ((value & 0x07) << 8)); + UpdateWaveFrequencyTime(); + + _waveTrigger = (value & 0x80) == 0x80; + _waveLengthEnable = (value & 0x40) == 0x40; + + // start sound 3 again + if (_waveDACpower && _waveTrigger) + { + _soundOnOff |= 0x04; + + _waveLengthCounter = 0; + _modeThreeFreqCounter = 0; + } + } + + // Noise + else if (index == 0xFF1F) { } // not used + else if (index == 0xFF20) + { + _noiseLengthLoad = (byte)(64 - (value & 0x3F)); + } + else if (index == 0xFF21) + { + _noiseInitVolume = (byte)(value >> 4); + _noiseEnvelopeAddMode = (value & 0x08) == 0x08; + _noiseEnvelopePeriod = (byte)(value & 0x07); + } + else if (index == 0xFF22) + { + _noiseClockShift = (byte)(value >> 4); + _noiseWidthMode = (value & 0x08) == 0x08; + _noiseDivisorCode = (byte)(value & 0x07); + } + else if (index == 0xFF23) + { + _noiseTrigger = (value & 0x80) == 0x80; + _noiseLengthEnable = (value & 0x40) == 0x40; + + // turn channel on/off + if (_noiseTrigger) + { + _soundOnOff |= 0x08; + + _noiseLengthCounter = 0; + + _noiseVolume = _noiseInitVolume; + + _noiseEnvelopeCounter = _noiseEnvelopePeriod; + + if (_noiseWidthMode) + _noiseLfsr = 0x7F; + else + _noiseLfsr = 0x7FFF; + } + else + { + _soundOnOff &= 0xF7; + } + } + + else if (index == 0xFF24) + { + _soundOutputLevel = value; + if (value != 0xFF) + Console.WriteLine("Volume not supported {0:X}", value); + } + else if (index == 0xFF25) + _channelLeftRightControl = value; + // NR52 + else if (index == 0xFF26) + _soundOnOff = value; + + // wave data + else if (0xFF30 <= index && index <= 0xFF3F) + { + _soundRegister[index - 0xFF10] = value; + + _waveNibbles[(index - 0xFF30) * 2] = (byte)(value >> 4); + _waveNibbles[(index - 0xFF30) * 2 + 1] = (byte)(value & 0x0F); + } + } + } + + private void UpdateSquare1FrequencyTime() + { + _modeOneFreqTime = OutputRate / (4194304.0 / (4 * (2048 - _square1Frequency))); + } + + private void UpdateSquare2FrequencyTime() + { + _modeTwoFreqTime = OutputRate / (4194304.0 / (4 * (2048 - _square2Frequency))); + } + + private void UpdateWaveFrequencyTime() + { + _modeThreeFreqTime = OutputRate / (4194304.0 / (2 * (2048 - _modeThreeFrequency))); + } + + // gets called 44100 (outputRate) times a second + public void UpdateBuffer() + { + DebugCounter++; + _frameSequencerTimer++; + + // 44100/512 = 86 + if (_frameSequencerTimer >= 86) + { + _frameSequencerTimer = 0; + + // 256Hz Length Ctr Clock + if (_frameSequencerCounter % 2 == 0) + { + _square1LengthCounter++; + _square2LengthCounter++; + _waveLengthCounter++; + _noiseLengthCounter++; + + // deactivate channel 1 + if (_square1LengthCounter >= _square1LengthLoad && _modeOneCounterEnable) + _soundOnOff &= 0xFE; + + // deactivate channel 2 + if (_square2LengthCounter >= _modeTwoSoundLength && _modeTwoCounterEnable) + _soundOnOff &= 0xFD; + + // deactivate channel 3 + if (_waveLengthCounter >= _modeThreeSoundLength && _waveLengthEnable) + { + _waveTrigger = false; + _soundOnOff &= 0xFB; + } + + if (_noiseLengthCounter >= _noiseLengthLoad && _noiseLengthEnable) + { + _soundOnOff &= 0xF7; + } + } + + // 64Hz Volume Envelope Clock + if ((_frameSequencerCounter + 1) % 8 == 0) + { + // step channel 1 up/down + _square1EnvelopeCounter--; + if (_square1EnvelopePeriod != 0 && _square1EnvelopeCounter <= 0 && + (!_square1EnvelopeAddMode && _square1Volume > 0 || _square1EnvelopeAddMode && _square1Volume < 15)) + { + _square1EnvelopeCounter = _square1EnvelopePeriod; + _square1Volume += _square1EnvelopeAddMode ? 1 : -1; + } + + // step channel 2 up/down + _square2EnvelopeCounter--; + if (_square2EnvelopePeriod != 0 && _square2EnvelopeCounter <= 0 && + (!_square2EnvelopeAddMode && _square2Volume > 0 || _square2EnvelopeAddMode && _square2Volume < 15)) + { + _square2EnvelopeCounter = _square2EnvelopePeriod; + _square2Volume += _square2EnvelopeAddMode ? 1 : -1; + } + + // step channel 4 + _noiseEnvelopeCounter--; + if (_noiseEnvelopePeriod != 0 && _noiseEnvelopeCounter <= 0 && + (!_noiseEnvelopeAddMode && _noiseVolume > 0 || _noiseEnvelopeAddMode && _noiseVolume < 15)) + { + _noiseEnvelopeCounter = _noiseEnvelopePeriod; + _noiseVolume += (byte)(_noiseEnvelopeAddMode ? 1 : -1); + } + } + + // 128Hz Sweep Clock + if ((_frameSequencerCounter + 2) % 4 == 0) + { + _modeOneSweepCounter++; + + // sweep + if (_modeOneSweepTime != 0 && _modeOneNumberOfSweepShifts != 0 && _modeOneSweepCounter >= _modeOneSweepTime) + { + _modeOneSweepCounter = 0; + var newFreq = (short)(_square1Frequency + (_modeOneSweepSubtraction ? -1 : 1) * (_square1Frequency >> _modeOneNumberOfSweepShifts)); + + // newFreq > 11bits + if ((newFreq & 0x7FF) != newFreq) + { + // deactivate channel + _soundOnOff &= 0xFE; + } + else if (newFreq <= 0) + { + + } + else + { + _square1Frequency = newFreq; + } + + _soundRegister[0xFF13 - 0xFF10] = (byte)(_square1Frequency & 0xFF); + _soundRegister[0xFF14 - 0xFF10] = (byte)(_soundRegister[0xFF14 - 0xFF10] & 0xF8 + (_square1Frequency >> 8)); + + UpdateSquare1FrequencyTime(); + } + } + + _frameSequencerCounter++; + if (_frameSequencerCounter >= 8) + _frameSequencerCounter = 0; + } + + // Square 1 + short channel0 = 0; + { + if (_square1Running) + { + _modeOneFreqCounter++; + + if (_modeOneFreqCounter >= _modeOneFreqTime) + { + _modeOneFreqCounter -= _modeOneFreqTime; + + // update wave + _waveOne = _square1WaveCounter < _modeOneWavePatternDutyPercentage ? 1 : 0; + _square1WaveCounter = (byte)((_square1WaveCounter + 1) % 8); + } + } + + // value between 0-15 + channel0 = (short)(_waveOne * _square1Volume); + + // Sound 1 ON Flag + if ((_soundOnOff & 0x01) == 0x00) + channel0 = 0; + } + + // Square 2 + short channel1 = 0; + { + if (_square2Running) + { + _modeTwoFreqCounter++; + + if (_modeTwoFreqCounter >= _modeTwoFreqTime) + { + _modeTwoFreqCounter -= _modeTwoFreqTime; + + // update wave + _waveTwo = _square2WaveCounter < _modeTwoWavePatternDutyPercentage ? 1 : 0; + _square2WaveCounter = (byte)((_square2WaveCounter + 1) % 8); + } + } + + channel1 = (short)(_waveTwo * _square2Volume); + + // Sound 2 ON Flag + if ((_soundOnOff & 0x02) == 0x00) + channel1 = 0; + } + + // Wave + double channel2 = 0; + { + _modeThreeFreqCounter++; + if (_modeThreeFreqCounter >= _modeThreeFreqTime) + { + _modeThreeFreqCounter -= _modeThreeFreqTime; + _waveIndex = (_waveIndex + 1) % 32; + + // 32 x 4 bit samples + _waveThree = (byte)(_waveNibbles[_waveIndex] >> (_waveVolumeCode - 1)); + } + + channel2 = _waveThree; + + // Sound 3 ON Flag + if ((_soundOnOff & 0x04) == 0x00 || _waveVolumeCode == 0x00 || !_waveDACpower) + channel2 = 0; + } + + // Noise Channel + double channel3 = 0; + { + channel3 = 0; + if ((_soundOnOff & 0x08) != 0x00) + { + channel3 = (double)((~_noiseLfsr & 0x01) * _noiseVolume); + + var s = _noiseClockShift; + var r = _noiseDivisorCode == 0 ? 0.5 : _noiseDivisorCode; + var divisor = (262144 / r / Math.Pow(2, s)); + var freq = 4194304 / divisor; + + var stepSize = 4194304 / OutputRate; + _noiseTimeSteps += stepSize; + + var stepCount = (int)(_noiseTimeSteps / freq); + if (stepCount > 1) + channel3 /= (double)stepCount; + + while (_noiseTimeSteps >= freq) + { + _noiseTimeSteps -= freq; + + var lsb = (short)((_noiseLfsr & 0x01) ^ ((_noiseLfsr >> 1) & 0x01)); + + _noiseLfsr >>= 1; + + _noiseLfsr |= (short)(lsb << 14); + + if (_noiseWidthMode) + _noiseLfsr |= (short)(lsb << 6); + + if (_noiseTimeSteps > freq) + channel3 += (double)((~_noiseLfsr & 0x01) * _noiseVolume) / (double)stepCount; + } + } + } + + //channel0 = 0; + //channel1 = 0; + //channel2 = 0; + //channel3 = 0; + + double mixerOutput = ((channel0 / 15.0) + + (channel1 / 15.0) + + (channel2 / 15.0) + + (channel3 / 15.0)) / 4; + + if ((_soundOnOff & 0x80) != 0x80) + mixerOutput = 0; + + var output = HighPass(mixerOutput, (_soundOnOff & 0x0F) != 0x00); + var byteOutput = (short)(output * short.MaxValue); + + _soundBuffer[_bufferIndex++] = (byte)(byteOutput & 0xFF); + _soundBuffer[_bufferIndex++] = (byte)(byteOutput >> 8); + + // this can happen when _bufferIndex get reset while in the process of setting the _soundBuffer + if (_bufferIndex % 2 != 0) + _bufferIndex = 0; + + _bufferCount++; + if (_endBufferCount > 0 && _bufferCount > _endBufferCount) + WasStopped = true; + + if (_bufferIndex >= _soundBuffer.Length || (WasStopped && _bufferIndex > 0)) + AddCurrentBuffer(); + } + + private double HighPass(double input, bool dacsEnabled) + { + if (!dacsEnabled) + return 0.0; + + var output = input - _highPassFilterCapacitor; + + // 0,999958 ^ (4194304/rate) + // 0,999958 ^ (4194304/44100hz) = 0,996013308910 + // 0,999958 ^ (4194304/48000hz) = 0,996336633487 + _highPassFilterCapacitor = input - output * 0.996013308910; // for 44100hz + + return output; + } + } +} diff --git a/InGame/Controls/ButtonMapper.cs b/InGame/Controls/ButtonMapper.cs new file mode 100644 index 0000000..18871f5 --- /dev/null +++ b/InGame/Controls/ButtonMapper.cs @@ -0,0 +1,16 @@ +using Microsoft.Xna.Framework.Input; + +namespace ProjectZ.InGame.Controls +{ + public class ButtonMapper + { + public Keys[] Keys; + public Buttons[] Buttons; + + public ButtonMapper(Keys[] keys, Buttons[] buttons) + { + Keys = keys; + Buttons = buttons; + } + } +} \ No newline at end of file diff --git a/InGame/Controls/CButtons.cs b/InGame/Controls/CButtons.cs new file mode 100644 index 0000000..523f9dc --- /dev/null +++ b/InGame/Controls/CButtons.cs @@ -0,0 +1,22 @@ +using System; + +namespace ProjectZ.InGame.Controls +{ + [Flags] + public enum CButtons + { + None = 0, + Left = 1, + Right = 2, + Up = 4, + Down = 8, + A = 16, + B = 32, + X = 64, + Y = 128, + Select = 256, + Start = 512, + //L = 1024, + //R = 2048 + } +} \ No newline at end of file diff --git a/InGame/Controls/ControlHandler.cs b/InGame/Controls/ControlHandler.cs new file mode 100644 index 0000000..8ba21a9 --- /dev/null +++ b/InGame/Controls/ControlHandler.cs @@ -0,0 +1,252 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; +using ProjectZ.Base; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Controls +{ + public class ControlHandler + { + public static Dictionary ButtonDictionary = new Dictionary(); + + public static CButtons DebugButtons; + + public static bool LastKeyboardDown; + + private const int ScrollStartTime = 350; + private const int ScrollTime = 100; + + private static float _scrollCounter; + + private static bool _initDirection; + + public static void Initialize() + { + ResetControlls(); + } + + public static void ResetControlls() + { + ButtonDictionary.Clear(); + ButtonDictionary.Add(CButtons.Left, new ButtonMapper(new[] { Keys.Left }, new[] { Buttons.DPadLeft })); + ButtonDictionary.Add(CButtons.Right, new ButtonMapper(new[] { Keys.Right }, new[] { Buttons.DPadRight })); + ButtonDictionary.Add(CButtons.Up, new ButtonMapper(new[] { Keys.Up }, new[] { Buttons.DPadUp })); + ButtonDictionary.Add(CButtons.Down, new ButtonMapper(new[] { Keys.Down }, new[] { Buttons.DPadDown })); + ButtonDictionary.Add(CButtons.A, new ButtonMapper(new[] { Keys.S }, new[] { Buttons.A })); + ButtonDictionary.Add(CButtons.B, new ButtonMapper(new[] { Keys.D }, new[] { Buttons.B })); + ButtonDictionary.Add(CButtons.X, new ButtonMapper(new[] { Keys.A }, new[] { Buttons.X })); + ButtonDictionary.Add(CButtons.Y, new ButtonMapper(new[] { Keys.W }, new[] { Buttons.Y })); + ButtonDictionary.Add(CButtons.Select, new ButtonMapper(new[] { Keys.Space }, new[] { Buttons.Back })); + ButtonDictionary.Add(CButtons.Start, new ButtonMapper(new[] { Keys.Enter }, new[] { Buttons.Start })); + //buttonDictionary.Add(CButtons.L, new ButtonMapper(new[] { Keys.NumPad4 }, new[] { Buttons.LeftShoulder })); + //buttonDictionary.Add(CButtons.R, new ButtonMapper(new[] { Keys.NumPad6 }, new[] { Buttons.RightShoulder })); + } + + public static void SaveButtonMaps(SaveManager saveManager) + { + // load the input settings + foreach (var buttonMap in ButtonDictionary) + { + // save the keyboard buttons + for (var i = 0; i < buttonMap.Value.Keys.Length; i++) + saveManager.SetInt("control" + buttonMap.Key + "key" + i, (int)buttonMap.Value.Keys[i]); + // save the gamepad buttons + for (var i = 0; i < buttonMap.Value.Buttons.Length; i++) + saveManager.SetInt("control" + buttonMap.Key + "button" + i, (int)buttonMap.Value.Buttons[i]); + } + } + + public static void LoadButtonMap(SaveManager saveManager) + { + // load the input settings + foreach (var buttonMap in ButtonDictionary) + { + // load the keyboard button + var index = 0; + int key; + var keys = new List(); + while ((key = saveManager.GetInt("control" + buttonMap.Key + "key" + index, -1)) >= 0) + { + keys.Add((Keys)key); + index++; + } + + // set the loaded keys + if (keys.Count > 0) + buttonMap.Value.Keys = keys.ToArray(); + + // load the gamepad button + index = 0; + int button; + var gamepadButtons = new List(); + while ((button = saveManager.GetInt("control" + buttonMap.Key + "button" + index, -1)) >= 0) + { + gamepadButtons.Add((Buttons)button); + index++; + } + + // set the loaded buttons + if (gamepadButtons.Count > 0) + buttonMap.Value.Buttons = gamepadButtons.ToArray(); + } + } + + public static Vector2 GetGamepadDirection() + { + var gamepadState = GamePad.GetState(PlayerIndex.One); + return new Vector2(gamepadState.ThumbSticks.Left.X, -gamepadState.ThumbSticks.Left.Y); + } + + public static Vector2 GetMoveVector2() + { + var gamepadState = GamePad.GetState(PlayerIndex.One); + var vec = new Vector2(gamepadState.ThumbSticks.Left.X, -gamepadState.ThumbSticks.Left.Y); + + // controller deadzone + if (vec.Length() < Values.ControllerDeadzone) + vec = Vector2.Zero; + + if (vec == Vector2.Zero) + { + if (ButtonDown(CButtons.Left)) + vec += new Vector2(-1, 0); + if (ButtonDown(CButtons.Right)) + vec += new Vector2(1, 0); + if (ButtonDown(CButtons.Up)) + vec += new Vector2(0, -1); + if (ButtonDown(CButtons.Down)) + vec += new Vector2(0, 1); + } + + return vec; + } + + public static void Update() + { + if (_scrollCounter < 0) + _scrollCounter += ScrollTime; + + _initDirection = _scrollCounter == ScrollStartTime; + + var direction = GetMoveVector2(); + if (direction.Length() >= Values.ControllerDeadzone) + _scrollCounter -= Game1.DeltaTime; + else + _scrollCounter = ScrollStartTime; + + foreach (var button in ButtonDictionary) + for (var i = 0; i < button.Value.Keys.Length; i++) + if (InputHandler.LastKeyDown(button.Value.Keys[i])) + LastKeyboardDown = true; + + foreach (var button in ButtonDictionary) + for (var i = 0; i < button.Value.Buttons.Length; i++) + if (InputHandler.LastGamePadDown(button.Value.Buttons[i])) + LastKeyboardDown = false; + + DebugButtons = CButtons.None; + } + + public static bool MenuButtonPressed(CButtons button) + { + var direction = GetGamepadDirection(); + if (direction.Length() >= Values.ControllerDeadzone) + { + var dir = AnimationHelper.GetDirection(direction); + if (((dir == 0 && button == CButtons.Left) || (dir == 1 && button == CButtons.Up) || + (dir == 2 && button == CButtons.Right) || (dir == 3 && button == CButtons.Down)) && (_scrollCounter < 0 || _initDirection)) + return true; + } + + return ButtonPressed(button) || (ButtonDown(button) && _scrollCounter < 0); + } + + public static bool LastButtonDown(CButtons button) + { + // check the keyboard buttons + for (var i = 0; i < ButtonDictionary[button].Keys.Length; i++) + if (InputHandler.LastKeyDown(ButtonDictionary[button].Keys[i])) + return true; + + // check the gamepad buttons + for (var i = 0; i < ButtonDictionary[button].Buttons.Length; i++) + if (InputHandler.LastGamePadDown(ButtonDictionary[button].Buttons[i])) + return true; + + return false; + } + + public static bool ButtonDown(CButtons button) + { + var direction = GetGamepadDirection(); + if (direction.Length() >= Values.ControllerDeadzone) + { + var dir = AnimationHelper.GetDirection(direction); + if ((dir == 0 && button == CButtons.Left) || (dir == 1 && button == CButtons.Up) || + (dir == 2 && button == CButtons.Right) || (dir == 3 && button == CButtons.Down)) + return true; + } + + // check the keyboard buttons + for (var i = 0; i < ButtonDictionary[button].Keys.Length; i++) + if (InputHandler.KeyDown(ButtonDictionary[button].Keys[i])) + return true; + + // check the gamepad buttons + for (var i = 0; i < ButtonDictionary[button].Buttons.Length; i++) + if (InputHandler.GamePadDown(ButtonDictionary[button].Buttons[i])) + return true; + + return false; + } + + public static bool ButtonPressed(CButtons button) + { + var direction = GetGamepadDirection(); + if (_initDirection && direction.Length() >= Values.ControllerDeadzone) + { + var dir = AnimationHelper.GetDirection(direction); + if ((dir == 0 && button == CButtons.Left) || (dir == 1 && button == CButtons.Up) || + (dir == 2 && button == CButtons.Right) || (dir == 3 && button == CButtons.Down)) + return true; + } + + // check the keyboard buttons + for (var i = 0; i < ButtonDictionary[button].Keys.Length; i++) + if (InputHandler.KeyPressed(ButtonDictionary[button].Keys[i])) + return true; + + // check the gamepad buttons + for (var i = 0; i < ButtonDictionary[button].Buttons.Length; i++) + if (InputHandler.GamePadPressed(ButtonDictionary[button].Buttons[i])) + return true; + + // button presses used by tests + if ((DebugButtons & button) != 0) + return true; + + return false; + } + + public static CButtons GetPressedButtons() + { + CButtons pressedButtons = 0; + + foreach (var bEntry in ButtonDictionary) + { + for (var i = 0; i < bEntry.Value.Keys.Length; i++) + if (InputHandler.KeyPressed(bEntry.Value.Keys[i])) + pressedButtons |= bEntry.Key; + + // check the gamepad buttons + for (var i = 0; i < bEntry.Value.Buttons.Length; i++) + if (InputHandler.GamePadPressed(bEntry.Value.Buttons[i])) + pressedButtons |= bEntry.Key; + } + + return pressedButtons; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Base/Animation/Animation.cs b/InGame/GameObjects/Base/Animation/Animation.cs new file mode 100644 index 0000000..74ceabb --- /dev/null +++ b/InGame/GameObjects/Base/Animation/Animation.cs @@ -0,0 +1,51 @@ +using System; +using Microsoft.Xna.Framework; + +namespace ProjectZ.InGame.GameObjects.Base +{ + public class Animation + { + public Frame[] Frames = new Frame[0]; + public Point Offset; + + public string Id; + public string NextAnimation; + + public int AnimationLeft = 0; + public int AnimationRight = 0; + + public int AnimationTop = 0; + public int AnimationBottom = 0; + + public int AnimationWidth = 0; + public int AnimationHeight = 0; + + public int LoopCount; + + public Animation(string id) + { + Id = id.ToLower(); + } + } + + public class Frame + { + public Rectangle SourceRectangle; + public Rectangle CollisionRectangle; + + public Point Offset; + + public bool MirroredV; + public bool MirroredH; + + public int FrameTime + { + get => (int)Math.Round(FrameTimeFps * 1000 / 60f); + set => FrameTimeFps = (int)Math.Round(value * 60 / 1000f); + } + + // 1 => shown for 1 frame (if the game runs with 60fps) + // 2 => shown for 2 frames + public int FrameTimeFps { get; set; } + } +} diff --git a/InGame/GameObjects/Base/Animation/Animator.cs b/InGame/GameObjects/Base/Animation/Animator.cs new file mode 100644 index 0000000..3ab80c3 --- /dev/null +++ b/InGame/GameObjects/Base/Animation/Animator.cs @@ -0,0 +1,342 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Base +{ + public class Animator + { + public List Animations = new List(); + + public delegate void AnimationEvent(); + public AnimationEvent OnAnimationFinished; + public AnimationEvent OnFrameChange; + + public Animation CurrentAnimation => Animations[_currentAnimation]; + public Frame CurrentFrame => Animations[_currentAnimation].Frames[CurrentFrameIndex]; + + public Rectangle CollisionRectangle; + public Texture2D SprTexture; + + public string SpritePath; + public float SpeedMultiplier = 1; + + public int CurrentFrameIndex + { + get => _currentFrameIndex; + private set + { + _currentFrameIndex = value; + OnFrameChange?.Invoke(); + } + } + public bool IsPlaying; + + public double FrameCounter => _frameCounter; + + public int FrameWidth => Animations[_currentAnimation].Frames[CurrentFrameIndex].SourceRectangle.Width; + public int FrameHeight => Animations[_currentAnimation].Frames[CurrentFrameIndex].SourceRectangle.Height; + + private double _frameCounter; + + private int _currentLoop; + private int _currentAnimation; + private int _currentFrameIndex; + private int _finishFrameIndex; + + public void Update() + { + var stoppedPlaying = false; + + if (IsPlaying) + { + _frameCounter += Game1.DeltaTime * SpeedMultiplier; + + while (_frameCounter > Animations[_currentAnimation].Frames[CurrentFrameIndex].FrameTime) + { + _frameCounter -= Animations[_currentAnimation].Frames[CurrentFrameIndex].FrameTime; + + if (CurrentFrameIndex + 1 >= Animations[_currentAnimation].Frames.Length) + { + // stop playing + if (Animations[_currentAnimation].LoopCount >= 0 && + Animations[_currentAnimation].LoopCount <= _currentLoop) + { + IsPlaying = false; + stoppedPlaying = true; + OnAnimationFinished?.Invoke(); + } + else + { + // loop animation + CurrentFrameIndex = 0; + _currentLoop++; + } + } + else + { + CurrentFrameIndex++; + } + + // stop the animation? + if (CurrentFrameIndex == _finishFrameIndex) + Stop(); + } + } + + // start the following animation + if (stoppedPlaying && !string.IsNullOrEmpty(Animations[_currentAnimation].NextAnimation)) + Play(Animations[_currentAnimation].NextAnimation); + + CollisionRectangle = GetCollisionBox(CurrentFrame); + } + + public void Draw(SpriteBatch spriteBatch, Vector2 position, Color color) + { + // needed so that the objects don't wiggle around while the camera is moving + var normX = (int)Math.Round(position.X * MapManager.Camera.Scale) / MapManager.Camera.Scale; + var normY = (int)Math.Round(position.Y * MapManager.Camera.Scale) / MapManager.Camera.Scale; + + spriteBatch.Draw(SprTexture, new Vector2( + normX + (CurrentAnimation.Offset.X + CurrentFrame.Offset.X), + normY + (CurrentAnimation.Offset.Y + CurrentFrame.Offset.Y)), CurrentFrame.SourceRectangle, + color, 0, Vector2.Zero, Vector2.One, + (CurrentFrame.MirroredV ? SpriteEffects.FlipVertically : SpriteEffects.None) | + (CurrentFrame.MirroredH ? SpriteEffects.FlipHorizontally : SpriteEffects.None), 0); + + // draw the collision rectangle + if (Game1.DebugMode) + { + spriteBatch.Draw(Resources.SprWhite, new Vector2( + position.X + (CurrentAnimation.Offset.X + CurrentFrame.Offset.X + CurrentFrame.CollisionRectangle.X), + position.Y + (CurrentAnimation.Offset.Y + CurrentFrame.Offset.Y + CurrentFrame.CollisionRectangle.Y)), + new Rectangle(0, 0, CurrentFrame.CollisionRectangle.Width, CurrentFrame.CollisionRectangle.Height), Color.Green * 0.5f); + } + } + + public void DrawBasic(SpriteBatch spriteBatch, Vector2 position, Color color, float scale = 1) + { + spriteBatch.Draw(SprTexture, new Vector2( + position.X + (CurrentAnimation.Offset.X + CurrentFrame.Offset.X) * scale, + position.Y + (CurrentAnimation.Offset.Y + CurrentFrame.Offset.Y) * scale), CurrentFrame.SourceRectangle, + color, 0, Vector2.Zero, new Vector2(scale), + (CurrentFrame.MirroredV ? SpriteEffects.FlipVertically : SpriteEffects.None) | + (CurrentFrame.MirroredH ? SpriteEffects.FlipHorizontally : SpriteEffects.None), 0); + } + + //public void DrawShadow(SpriteBatch spriteBatch) + //{ + // if (!IsVisible || !ShadowVisible) + // return; + + // var normX = (int)Math.Round(PosX * (int)MapManager.Camera.Scale, 0, MidpointRounding.AwayFromZero) / MapManager.Camera.Scale; + // var normY = (int)Math.Round(PosY * (int)MapManager.Camera.Scale, 0, MidpointRounding.AwayFromZero) / MapManager.Camera.Scale; + + // DrawHelper.DrawShadow(SprTexture, new Vector2( + // normX + (CurrentAnimation.Offset.X + CurrentFrame.Offset.X), + // normY + (CurrentAnimation.Offset.Y + CurrentFrame.Offset.Y)), CurrentFrame.SourceRectangle, + // CurrentFrame.MirroredH, Color.White); + + // //spriteBatch.Draw(SprAnimator, new Vector2( + // // drawPosX + (CurrentAnimation.Offset.X + CurrentFrame.Offset.X), + // // drawPosY + (CurrentAnimation.Offset.Y + CurrentFrame.Offset.Y)), + // // new Rectangle(-SprAnimator.Width, 0, SprAnimator.Width * 3, SprAnimator.Height * 2), Color.Black * 0.4f); + //} + + public void ResetFrameCounter() + { + _frameCounter = 0; + } + + public void SetFrame(int frame) + { + if (frame < Animations[_currentAnimation].Frames.Length) + CurrentFrameIndex = frame; + } + + public int GetAnimationTime(int from, int to) + { + var time = 0; + for (var i = from; i < to; i++) + time += Animations[_currentAnimation].Frames[i].FrameTime; + + return time; + } + + public int GetAnimationTime() + { + return GetAnimationTime(0, CurrentAnimation.Frames.Length); + } + + public void SetTime(double time) + { + _frameCounter = time; + } + + public bool HasAnimation(string animationId) + { + return GetAnimationIndex(animationId) != -1; + } + + public int GetAnimationIndex(string animationId) + { + var index = -1; + + for (var i = 0; i < Animations.Count; i++) + if (Animations[i].Id == animationId) + { + index = i; + break; + } + + return index; + } + + public void Play(int animationId) + { + if ((_currentAnimation == animationId && IsPlaying) || animationId < 0) + return; + + IsPlaying = true; + _finishFrameIndex = -1; + _currentAnimation = animationId; + CurrentFrameIndex = 0; + _currentLoop = 0; + _frameCounter = 0; + + CollisionRectangle = GetCollisionBox(CurrentFrame); + } + + public void Play(string animationId) + { + Play(GetAnimationIndex(animationId)); + } + + public void Play(string animationId, int frame, double time) + { + Play(GetAnimationIndex(animationId)); + SetFrame(frame); + SetTime(time); + } + + public void FinishAnimation(int finishFrameIndex) + { + if (_currentFrameIndex == finishFrameIndex) + Stop(); + else + _finishFrameIndex = finishFrameIndex; + } + + public void Stop() + { + IsPlaying = false; + CurrentFrameIndex = 0; + _currentLoop = 0; + } + + public void Pause() + { + IsPlaying = false; + } + + public void Continue() + { + IsPlaying = true; + } + + public void AddAnimation(Animation addAnimation) + { + Animations.Add(addAnimation); + } + + public void AddFrame(int animationIndex, int frameIndex, Frame newFrame) + { + var newFrames = Animations[animationIndex].Frames.ToList(); + newFrames.Insert(frameIndex, newFrame); + + Animations[animationIndex].Frames = newFrames.ToArray(); + + UpdateAnimationSize(animationIndex, newFrame); + } + + public void SetFrameAt(string animationId, int frameIndex, Frame newFrame) + { + SetFrameAt(GetAnimationIndex(animationId), frameIndex, newFrame); + } + + public void SetFrameAt(int animationIndex, int frameIndex, Frame newFrame) + { + Animations[animationIndex].Frames[frameIndex] = newFrame; + UpdateAnimationSize(animationIndex, newFrame); + } + + public void UpdateAnimationSize(int animationIndex, Frame newFrame) + { + if (Animations[animationIndex].AnimationLeft > newFrame.Offset.X) + Animations[animationIndex].AnimationLeft = newFrame.Offset.X; + if (Animations[animationIndex].AnimationTop > newFrame.Offset.Y) + Animations[animationIndex].AnimationTop = newFrame.Offset.Y; + + if (Animations[animationIndex].AnimationRight < newFrame.Offset.X + newFrame.SourceRectangle.Width) + Animations[animationIndex].AnimationRight = newFrame.Offset.X + newFrame.SourceRectangle.Width; + if (Animations[animationIndex].AnimationBottom < newFrame.Offset.Y + newFrame.SourceRectangle.Height) + Animations[animationIndex].AnimationBottom = newFrame.Offset.Y + newFrame.SourceRectangle.Height; + + Animations[animationIndex].AnimationWidth = Animations[animationIndex].AnimationRight - Animations[animationIndex].AnimationLeft; + Animations[animationIndex].AnimationHeight = Animations[animationIndex].AnimationBottom - Animations[animationIndex].AnimationTop; + } + + public void RecalculateAnimationSize(int animationIndex) + { + // update the size of the animation + Animations[animationIndex].AnimationLeft = 0; + Animations[animationIndex].AnimationRight = 0; + Animations[animationIndex].AnimationTop = 0; + Animations[animationIndex].AnimationBottom = 0; + + foreach (var frame in Animations[animationIndex].Frames) + UpdateAnimationSize(animationIndex, frame); + } + + public void SetAnimationFps(int animationId, int fps) + { + for (var j = 0; j < Animations[animationId].Frames.Length; j++) + Animations[animationId].Frames[j].FrameTimeFps = fps; + } + + public void SetFrameFps(int animationId, int frame, int fps) + { + if (0 <= frame && frame < Animations[animationId].Frames.Length) + Animations[animationId].Frames[frame].FrameTimeFps = fps; + } + + public Rectangle GetCollisionBox(Frame frame) + { + if (frame.CollisionRectangle.Width > 0 && frame.CollisionRectangle.Height > 0) + { + var collisionRectangle = new Rectangle( + CurrentAnimation.Offset.X + frame.Offset.X, + CurrentAnimation.Offset.Y + frame.Offset.Y, + frame.CollisionRectangle.Width, frame.CollisionRectangle.Height); + + if (!frame.MirroredH) + collisionRectangle.X += frame.CollisionRectangle.X; + else + collisionRectangle.X += frame.SourceRectangle.Width - frame.CollisionRectangle.Width - frame.CollisionRectangle.X; + + if (!frame.MirroredV) + collisionRectangle.Y += frame.CollisionRectangle.Y; + else + collisionRectangle.Y += frame.SourceRectangle.Height - frame.CollisionRectangle.Height - frame.CollisionRectangle.Y; + + return collisionRectangle; + } + + return Rectangle.Empty; + } + } +} diff --git a/InGame/GameObjects/Base/Animation/SheetAnimation.cs b/InGame/GameObjects/Base/Animation/SheetAnimation.cs new file mode 100644 index 0000000..57365af --- /dev/null +++ b/InGame/GameObjects/Base/Animation/SheetAnimation.cs @@ -0,0 +1,57 @@ +using System; +using Microsoft.Xna.Framework; + +namespace ProjectZ.InGame.GameObjects.Base +{ + public class SheetAnimation + { + public AFrame[] Frames = new AFrame[0]; + + public string Id; + public string NextAnimation; + public int LoopCount; + + public SheetAnimation(string id, int loopCount, params AFrame[] frames) + { + Id = id; + LoopCount = loopCount; + Frames = frames; + } + } + + public class AFrame + { + public ASprite[] Sprites; + + public int FrameTime + { + get => (int)Math.Round(FrameTimeFps * 1000 / 60f); + set => FrameTimeFps = (int)Math.Round(value * 60 / 1000f); + } + + // 1 => shown for 1 frame (if the game runs with 60fps) + // 2 => shown for 2 frames + public int FrameTimeFps { get; set; } + + public AFrame(int frameTimeFps, params ASprite[] sprites) + { + FrameTimeFps = frameTimeFps; + Sprites = sprites; + } + } + + public class ASprite + { + public Point Offset; + + public bool MirroredV; + public bool MirroredH; + + public ASprite(int offsetX, int offsetY, bool mirroredV = false, bool mirroredH = false) + { + Offset = new Point(offsetX, offsetY); + MirroredV = mirroredV; + MirroredH = mirroredH; + } + } +} diff --git a/InGame/GameObjects/Base/Animation/SheetAnimator.cs b/InGame/GameObjects/Base/Animation/SheetAnimator.cs new file mode 100644 index 0000000..672aa71 --- /dev/null +++ b/InGame/GameObjects/Base/Animation/SheetAnimator.cs @@ -0,0 +1,145 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Base +{ + public class SheetAnimator + { + public List Animations = new List(); + + public delegate void AnimationEvent(); + public AnimationEvent OnAnimationFinished; + public AnimationEvent OnFrameChange; + + public SheetAnimation CurrentAnimation => Animations[_currentAnimation]; + public AFrame CurrentFrame => Animations[_currentAnimation].Frames[CurrentFrameIndex]; + + public float SpeedMultiplier = 1; + + public int CurrentFrameIndex + { + get => _currentFrameIndex; + private set + { + _currentFrameIndex = value; + OnFrameChange?.Invoke(); + } + } + public bool IsPlaying; + + public double FrameCounter => _frameCounter; + + private double _frameCounter; + + private int _currentLoop; + private int _currentAnimation; + private int _currentFrameIndex; + + public void Update() + { + if (IsPlaying) + { + _frameCounter += Game1.DeltaTime * SpeedMultiplier; + + while (_frameCounter > Animations[_currentAnimation].Frames[CurrentFrameIndex].FrameTime) + { + _frameCounter -= Animations[_currentAnimation].Frames[CurrentFrameIndex].FrameTime; + + if (CurrentFrameIndex + 1 >= Animations[_currentAnimation].Frames.Length) + { + // stop playing + if (Animations[_currentAnimation].LoopCount >= 0 && + Animations[_currentAnimation].LoopCount <= _currentLoop) + { + IsPlaying = false; + OnAnimationFinished?.Invoke(); + } + else + { + // loop animation + CurrentFrameIndex = 0; + _currentLoop++; + } + } + else + { + CurrentFrameIndex++; + } + } + } + + // start the following animation + if (!IsPlaying && Animations[_currentAnimation].NextAnimation != null) + Play(Animations[_currentAnimation].NextAnimation); + } + + public void ResetFrameCounter() + { + _frameCounter = 0; + } + + public void SetFrame(int frame) + { + if (frame < Animations[_currentAnimation].Frames.Length) + CurrentFrameIndex = frame; + } + + public void SetTime(double time) + { + _frameCounter = time; + } + + public int GetAnimationIndex(string animationId) + { + var index = -1; + + for (var i = 0; i < Animations.Count; i++) + if (Animations[i].Id == animationId) + { + index = i; + break; + } + + return index; + } + + public void Play(int animationId) + { + if ((_currentAnimation == animationId && IsPlaying) || animationId < 0) + return; + + IsPlaying = true; + _currentAnimation = animationId; + CurrentFrameIndex = 0; + _currentLoop = 0; + _frameCounter = 0; + } + + public void Play(string animationId) + { + Play(GetAnimationIndex(animationId)); + } + + public void Stop() + { + IsPlaying = false; + CurrentFrameIndex = 0; + _currentLoop = 0; + } + + public void Pause() + { + IsPlaying = false; + } + + public void Continue() + { + IsPlaying = true; + } + } +} diff --git a/InGame/GameObjects/Base/CObjects/CBox.cs b/InGame/GameObjects/Base/CObjects/CBox.cs new file mode 100644 index 0000000..c7f705f --- /dev/null +++ b/InGame/GameObjects/Base/CObjects/CBox.cs @@ -0,0 +1,70 @@ +using ProjectZ.Base; + +namespace ProjectZ.InGame.GameObjects.Base.CObjects +{ + public class CBox + { + public Box Box; + + public float OffsetX; + public float OffsetY; + public float OffsetZ; + + private readonly bool _followZ; + + public CBox(float posX, float posY, float posZ, float width, float height, float depth) + { + Box = new Box(posX, posY, posZ, width, height, depth); + } + + public CBox(CPosition position, float offsetX, float offsetY, float offsetZ, float width, float height, float depth, bool followZ = false) + { + OffsetX = offsetX; + OffsetY = offsetY; + OffsetZ = offsetZ; + + Box.Width = width; + Box.Height = height; + Box.Depth = depth; + + _followZ = followZ; + Set(position); + } + + public CBox(CPosition position, float offsetX, float offsetY, float width, float height, float depth) : + this(position, offsetX, offsetY, 0, width, height, depth) + { } + + public void Set(CPosition position) + { + if (_followZ) + { + position.AddPositionListener(typeof(CBox), UpdateBoxZ); + UpdateBoxZ(position); + } + else + { + position.AddPositionListener(typeof(CBox), UpdateBox); + UpdateBox(position); + } + } + + private void UpdateBoxZ(CPosition position) + { + Box = new Box( + position.X + OffsetX, + position.Y + OffsetY - position.Z, + OffsetZ, + Box.Width, Box.Height, Box.Depth); + } + + private void UpdateBox(CPosition position) + { + Box = new Box( + position.X + OffsetX, + position.Y + OffsetY, + position.Z + OffsetZ, + Box.Width, Box.Height, Box.Depth); + } + } +} diff --git a/InGame/GameObjects/Base/CObjects/CPosition.cs b/InGame/GameObjects/Base/CObjects/CPosition.cs new file mode 100644 index 0000000..d43d358 --- /dev/null +++ b/InGame/GameObjects/Base/CObjects/CPosition.cs @@ -0,0 +1,148 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; + +namespace ProjectZ.InGame.GameObjects.Base.CObjects +{ + public class CPosition + { + public delegate void PositionChanged(CPosition newPosition); + public Dictionary PositionChangedDict = new Dictionary(); + + private Vector2 _parentOffset; + + private Vector2 _position; + public Vector2 Position => _position; + + public Vector2 LastPosition { get; set; } + public float _lastZ; + + public float X + { + get => _position.X; + set => _position.X = value; + } + public float Y + { + get => _position.Y; + set => _position.Y = value; + } + public float Z; + + public CPosition(float x, float y, float z) + { + _position = new Vector2(x, y); + Z = z; + } + + public CPosition(Vector3 position) + { + _position = new Vector2(position.X, position.Y); + Z = position.Z; + } + + public void AddPositionListener(Type type, PositionChanged positionChanged) + { + if (PositionChangedDict.ContainsKey(type)) + PositionChangedDict[type] += positionChanged; + else + PositionChangedDict.Add(type, positionChanged); + } + + public void RemovePositionListener(Type type) + { + if (PositionChangedDict.ContainsKey(type)) + PositionChangedDict.Remove(type); + } + + public void Set(Vector2 position) + { + _position = position; + NotifyListeners(); + } + + public void Set(Vector3 position) + { + _position.X = position.X; + _position.Y = position.Y; + Z = position.Z; + NotifyListeners(); + } + + public void SetZ(float posZ) + { + Z = posZ; + NotifyListeners(); + } + + public void Set(CPosition position) + { + _position.X = position.X; + _position.Y = position.Y; + Z = position.Z; + NotifyListeners(); + } + + public Vector3 ToVector3() + { + return new Vector3(X, Y, Z); + } + + public void Move(Vector2 velocity) + { + _position += velocity * Game1.TimeMultiplier; + NotifyListeners(); + } + + public void Offset(Vector2 offset) + { + _position += offset; + NotifyListeners(); + } + + public void NotifyListeners() + { + foreach (var listener in PositionChangedDict) + listener.Value(this); + + LastPosition = Position; + _lastZ = Z; + } + + public void UpdateParent(CPosition position) + { + _position.X = position.X + _parentOffset.X; + _position.Y = position.Y + _parentOffset.Y; + Z = position.Z; + NotifyListeners(); + } + + public void UpdateParentOffsetZ(CPosition position) + { + _position.X = position.X + _parentOffset.X; + _position.Y = position.Y + _parentOffset.Y - position.Z; + NotifyListeners(); + } + + public void SetParent(CPosition position, Vector2 offset, bool offsetZ = false) + { + _parentOffset = offset; + + if (!offsetZ) + { + UpdateParent(position); + position.AddPositionListener(typeof(CPosition), UpdateParent); + } + else + { + UpdateParentOffsetZ(position); + position.AddPositionListener(typeof(CPosition), UpdateParentOffsetZ); + } + } + + public bool HasChanged() + { + return _position != LastPosition || Z != _lastZ; + } + } +} diff --git a/InGame/GameObjects/Base/CObjects/CRectangle.cs b/InGame/GameObjects/Base/CObjects/CRectangle.cs new file mode 100644 index 0000000..895de8c --- /dev/null +++ b/InGame/GameObjects/Base/CObjects/CRectangle.cs @@ -0,0 +1,39 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; + +namespace ProjectZ.InGame.GameObjects.Base.CObjects +{ + public class CRectangle + { + public RectangleF Rectangle; + public Rectangle OffsetSize; + + private bool MoveZ; + + public CRectangle(Rectangle rectangle) + { + Rectangle = rectangle; + } + + public CRectangle(RectangleF rectangle) + { + Rectangle = rectangle; + } + + public CRectangle(CPosition position, Rectangle offsetSize, bool moveZ = false) + { + OffsetSize = offsetSize; + position.AddPositionListener(typeof(CRectangle), UpdateRectangle); + UpdateRectangle(position); + MoveZ = moveZ; + } + + public void UpdateRectangle(CPosition position) + { + Rectangle = new RectangleF( + position.X + OffsetSize.X, + position.Y + OffsetSize.Y + (MoveZ ? -position.Z : 0), + OffsetSize.Width, OffsetSize.Height); + } + } +} diff --git a/InGame/GameObjects/Base/CObjects/CSprite.cs b/InGame/GameObjects/Base/CObjects/CSprite.cs new file mode 100644 index 0000000..01f11ca --- /dev/null +++ b/InGame/GameObjects/Base/CObjects/CSprite.cs @@ -0,0 +1,116 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Base.CObjects +{ + public class CSprite + { + public Texture2D SprTexture; + public CPosition Position; + public SpriteShader SpriteShader; + + public SpriteEffects SpriteEffect; + public Rectangle SourceRectangle; + public Vector2 DrawOffset; + public Vector2 Center; + public Color Color = Color.White; + + public float Scale = 1; + public float Rotation; + public bool IsVisible = true; + + public CSprite(CPosition position) + { + Position = position; + } + + public CSprite(Texture2D sprTexture, Rectangle sourceRectangle) + { + SprTexture = sprTexture; + SourceRectangle = sourceRectangle; + } + + public CSprite(Texture2D sprTexture, CPosition position, Rectangle sourceRectangle, Vector2 drawOffset) + { + SprTexture = sprTexture; + Position = position; + SourceRectangle = sourceRectangle; + DrawOffset = drawOffset; + } + + public CSprite(DictAtlasEntry sprite, CPosition position) + { + SetSprite(sprite); + Position = position; + } + + public CSprite(string spriteId, CPosition position) : this(Resources.GetSprite(spriteId), position) + { } + + // @REMOVE: drawOffset should probably be the center in most cases? + public CSprite(DictAtlasEntry sprite, CPosition position, Vector2 drawOffset) + { + SetSprite(sprite); + Position = position; + DrawOffset = drawOffset; + } + + // @REMOVE: drawOffset should probably be the center in most cases? + public CSprite(string spriteId, CPosition position, Vector2 drawOffset) : + this(Resources.GetSprite(spriteId), position, drawOffset) + { } + + public void SetSprite(DictAtlasEntry sprite) + { + SprTexture = sprite.Texture; + SourceRectangle = sprite.ScaledRectangle; + Scale = sprite.Scale; + Center = sprite.ScaledOrigin; + } + + public void Draw(SpriteBatch spriteBatch) + { + if (!IsVisible) + return; + + // this is used to align the sprite to avoid holes + var normX = (float)Math.Round((Position.X + DrawOffset.X) * MapManager.Camera.Scale) / MapManager.Camera.Scale; + var normY = (float)Math.Round((Position.Y + DrawOffset.Y - Position.Z) * MapManager.Camera.Scale) / MapManager.Camera.Scale; + + // change the draw effect + if (SpriteShader != null) + { + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, SpriteShader); + } + + spriteBatch.Draw(SprTexture, new Vector2(normX, normY), SourceRectangle, Color, Rotation, Center * Scale, new Vector2(Scale), SpriteEffect, 0); + + // change the draw effect + // this would not be very efficient if a lot of sprite used effects + if (SpriteShader != null) + { + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, null); + } + } + + public void DrawShadow(SpriteBatch spriteBatch, Color color, int offsetY, float height, float rotation) + { + if (!IsVisible) + return; + + var normX = (float)Math.Round((Position.X + DrawOffset.X - Center.X) * MapManager.Camera.Scale) / MapManager.Camera.Scale; + var normY = (float)Math.Round((Position.Y + DrawOffset.Y - Center.Y - Position.Z * 0.5f + offsetY) * MapManager.Camera.Scale) / MapManager.Camera.Scale; + + // TODO_OPT: this does currently not support FlipVertically + DrawHelper.DrawShadow(SprTexture, new Vector2(normX, normY), + SourceRectangle, SourceRectangle.Width, SourceRectangle.Height, + SpriteEffect == SpriteEffects.FlipHorizontally, height, rotation, color); + } + } +} diff --git a/InGame/GameObjects/Base/Components/AI/AiDamageState.cs b/InGame/GameObjects/Base/Components/AI/AiDamageState.cs new file mode 100644 index 0000000..9975bfc --- /dev/null +++ b/InGame/GameObjects/Base/Components/AI/AiDamageState.cs @@ -0,0 +1,520 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.GameObjects.Base.Components.AI +{ + class AiDamageState + { + public delegate void OnDeleteTemplate(bool pieceOfPower); + public OnDeleteTemplate OnDeath; + + public delegate void OnLiveZero(); + public OnLiveZero OnLiveZeroed; + + public delegate void OnBurnDelegate(); + public OnBurnDelegate OnBurn; + + public int ExplosionOffsetY; + public Point FlameOffset; + + public string SpawnItem; + + public float HitMultiplierX = 5; + public float HitMultiplierY = 5; + + public bool IgnoreZeroDamage; + public bool IsActive = true; + public bool MoveBody = true; + public bool UpdateLastStateFire; + public bool DeathAnimation = true; + public bool SpawnItems = true; + + private readonly GameObject _gameObject; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly CSprite _sprite; + + public SpriteShader DamageSpriteShader; + private SpriteShader _normalShader; + + public AiTriggerCountdown DamageTrigger; + private AiTriggerCountdown _deathCountdown; + + private bool _pieceOfPower; + private float _bodyDrag; + private float _bodyDragAir; + + private double _pieceOfPowerCounter; + private int _pieceOfPowerDeathCount; + + public int CurrentLives; + + private bool _damageBlink; + private bool _returnState; + private readonly bool _hasBurnState; + + public const int BlinkTime = 66; + public const int CooldownTime = BlinkTime * 6; + private readonly int _cooldownTime; + + public int ExplostionWidth = 32; + public int ExplostionHeight = 32; + + public bool HasDamageState; + public bool BossHitSound; + + private float _deathCount = -1000; + + public AiDamageState(GameObject gameObject, BodyComponent body, AiComponent aiComponent, CSprite sprite, int lives, bool hasDamageState = true, bool hasBurnState = true, int cooldownTime = CooldownTime) + { + _gameObject = gameObject; + _body = body; + _aiComponent = aiComponent; + _sprite = sprite; + _normalShader = sprite.SpriteShader; + + CurrentLives = lives; + + HasDamageState = hasDamageState; + _hasBurnState = hasBurnState; + + _cooldownTime = cooldownTime; + + // basic on death reaction + OnDeath = BaseOnDeath; + + DamageSpriteShader = Resources.DamageSpriteShader0; + + _aiComponent.Trigger.Add(DamageTrigger = new AiTriggerCountdown(cooldownTime, DamageTick, FinishDamage)); + if (hasDamageState) + _aiComponent.States.Add("damage", new AiState()); + + var stateKnockBack = new AiState(); + stateKnockBack.Trigger.Add(new AiTriggerCountdown(cooldownTime, null, FinishKnockback)); + + var statePieceOfPower = new AiState(UpdatePieceOfPower) { Init = InitPieceOfPower }; + var stateBurning = new AiState(UpdateBurning) { Init = InitBurning }; + var stateDamageDeath = new AiState { Init = () => OnDeath(false) }; + + _aiComponent.Trigger.Add(_deathCountdown = new AiTriggerCountdown(cooldownTime, DeathTick, () => DeathTick(0))); + + _aiComponent.States.Add("knockBack", stateKnockBack); + _aiComponent.States.Add("pieceOfPower", statePieceOfPower); + if (hasBurnState) + _aiComponent.States.Add("burning", stateBurning); + _aiComponent.States.Add("damageDeath", stateDamageDeath); + } + + public void AddBossDamageState(AiTriggerCountdown.TriggerEndFunction deathAnimationEnd) + { + OnDeath = OnDeathBoss; + + var stateDeath = new AiState(UpdateDeath); + stateDeath.Trigger.Add(new AiTriggerCountdown(3000 / BlinkTime * BlinkTime, UpdateBlink, deathAnimationEnd)); + + _aiComponent.States.Add("deathBoss", stateDeath); + } + + public bool IsInDamageState() + { + return DamageTrigger.CurrentTime > 0 || + _aiComponent.CurrentStateId == "knockBack" || + _aiComponent.CurrentStateId == "burning" || + _aiComponent.CurrentStateId == "pieceOfPower"; + } + + public Values.HitCollision HitKnockBack(GameObject gameObject, Vector2 direction, HitType damageType, bool pieceOfPower, bool blink = true) + { + if (!IsActive || IsInDamageState()) + return Values.HitCollision.None; + + _aiComponent.ChangeState(pieceOfPower ? "pieceOfPower" : "knockBack"); + + _damageBlink = blink; + DamageTrigger.OnInit(); + + if (pieceOfPower) + { + _body.Velocity.X = direction.X * 3; + _body.Velocity.Y = direction.Y * 3; + } + else + { + _body.Velocity.X = direction.X * HitMultiplierX; + _body.Velocity.Y = direction.Y * HitMultiplierY; + } + + _returnState = true; + + return Values.HitCollision.Enemy; + } + + public Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (!IsActive || IsInDamageState() || damageType == HitType.PegasusBootsPush) + return Values.HitCollision.None; + + // directly delete the gameObject if the attack comes from a bowwow + if (damageType == HitType.BowWow) + { + DeathAnimation = false; + OnDeath(false); + return Values.HitCollision.Enemy; + } + + if (damage <= 0 && IgnoreZeroDamage || DamageTrigger.CurrentTime > 0) + return Values.HitCollision.Enemy; + + CurrentLives -= damage; + + // burn on powder impact + if ((damageType == HitType.MagicPowder || damageType == HitType.MagicRod) && _hasBurnState) + { + if (_aiComponent.CurrentStateId != "burning") + { + _aiComponent.ChangeState("burning"); + var speedMultiply = (damageType == HitType.MagicPowder ? 0.125f : 0.5f); + + if (MoveBody) + { + _body.Velocity.X = direction.X * HitMultiplierX * speedMultiply; + _body.Velocity.Y = direction.Y * HitMultiplierY * speedMultiply; + } + + Game1.GameManager.PlaySoundEffect("D378-18-12"); + + return Values.HitCollision.Enemy; + } + } + + if (_aiComponent.CurrentStateId == "burning") + return Values.HitCollision.None; + + // play sound effect + if (!BossHitSound) + { + if (pieceOfPower) + Game1.GameManager.PlaySoundEffect("D370-17-11"); + + Game1.GameManager.PlaySoundEffect("D360-03-03"); + } + else + { + if (CurrentLives <= 0) + Game1.GameManager.PlaySoundEffect("D378-19-13"); + else + Game1.GameManager.PlaySoundEffect("D370-07-07"); + } + + if (pieceOfPower) + _aiComponent.ChangeState("pieceOfPower"); + else + { + if (HasDamageState) + { + _returnState = true; + _aiComponent.ChangeState("damage"); + } + } + + DamageTrigger.OnInit(); + + _damageBlink = damage > 0; + + if (MoveBody) + { + if (pieceOfPower) + { + _body.Velocity.X = direction.X * 3; + _body.Velocity.Y = direction.Y * 3; + } + else + { + _body.Velocity.X = direction.X * HitMultiplierX; + _body.Velocity.Y = direction.Y * HitMultiplierY; + } + } + + // trigger death event? + if (CurrentLives <= 0) + { + OnLiveZeroed?.Invoke(); + _deathCountdown.OnInit(); + } + + return Values.HitCollision.Enemy; + } + + public void SetDamageState(bool blink = true) + { + _damageBlink = blink; + DamageTrigger.OnInit(); + } + + private void InitPieceOfPower() + { + _pieceOfPower = true; + + _bodyDrag = _body.Drag; + _bodyDragAir = _body.DragAir; + + _body.Drag = 1.0f; + _body.DragAir = 1.0f; + + _pieceOfPowerDeathCount = 0; + } + + private void UpdatePieceOfPower() + { + if (!HasDamageState) + _aiComponent.States[_aiComponent.LastStateId].Update?.Invoke(); + + // draw a trail + if (_pieceOfPowerCounter <= 0) + { + _pieceOfPowerCounter = 80; + var animation = new ObjAnimator(_gameObject.Map, 0, 0, 0, 0, Values.LayerPlayer, "Particles/pieceOfPowerTrail", "run", true); + animation.EntityPosition.Set(_body.Position.Position + + new Vector2(_body.OffsetX + _body.Width / 2f, _body.OffsetY + _body.Height / 2f)); + animation.EntityPosition.Z = _body.Position.Z; + Game1.GameManager.MapManager.CurrentMap.Objects.SpawnObject(animation); + _pieceOfPowerDeathCount++; + } + _pieceOfPowerCounter -= Game1.DeltaTime; + + var collision = false; + + if ((_body.LastVelocityCollision & Values.BodyCollision.Horizontal) != 0) + _body.Velocity.X = 0; + if ((_body.LastVelocityCollision & Values.BodyCollision.Vertical) != 0) + _body.Velocity.Y = 0; + + // glide on the wall depending on the angle the body moved towards the wall + if (((_body.LastVelocityCollision & Values.BodyCollision.Horizontal) != 0 && MathF.Abs(_body.Velocity.X) > MathF.Abs(_body.Velocity.Y)) || + ((_body.LastVelocityCollision & Values.BodyCollision.Vertical) != 0 && MathF.Abs(_body.Velocity.Y) > MathF.Abs(_body.Velocity.X))) + { + collision = true; + } + + // last collision + if ((collision && _pieceOfPowerDeathCount > 1) || _pieceOfPowerDeathCount > 5) + { + _pieceOfPower = false; + _body.Drag = _bodyDrag; + _body.DragAir = _bodyDragAir; + + if (CurrentLives <= 0) + { + _body.Velocity.X = 0; + _body.Velocity.Y = 0; + OnDeath(true); + } + else + { + _aiComponent.ChangeState(_aiComponent.LastStateId, true); + } + } + } + + private void InitBurning() + { + OnBurn?.Invoke(); + + _body.VelocityTarget = Vector2.Zero; + + // spawn explosion effect + var burnAnimator = new ObjAnimator(_gameObject.Map, 0, 0, 0, 0, Values.LayerTop, "Particles/flame", "idle", false); + burnAnimator.EntityPosition.Set(_gameObject.EntityPosition.Position); + + // move the animation with the game object + burnAnimator.EntityPosition.SetParent(_gameObject.EntityPosition, + new Vector2((int)(_body.OffsetX + _body.Width / 2) + FlameOffset.X, + (int)(_body.OffsetY + _body.Height) - 8 + FlameOffset.Y)); + + // remove the burning sprite if the ai state changes (e.g. by falling down a hole) + burnAnimator.Animator.OnFrameChange = () => + { + // @HACK + burnAnimator.AnimationComponent.UpdateSprite(); + if (_aiComponent.Owner.Map == null || _aiComponent.CurrentStateId != "burning") + burnAnimator.Map.Objects.DeleteObjects.Add(burnAnimator); + }; + burnAnimator.Animator.OnAnimationFinished = () => + { + FinishBurning(); + burnAnimator.Map.Objects.DeleteObjects.Add(burnAnimator); + }; + + Game1.GameManager.MapManager.CurrentMap.Objects.SpawnObject(burnAnimator); + } + + private void UpdateBurning() + { + if (UpdateLastStateFire) + _aiComponent.States[_aiComponent.LastStateId].Update?.Invoke(); + } + + private void FinishBurning() + { + OnDeath(false); + } + + private void DamageTick(double time) + { + if (_damageBlink) + _sprite.SpriteShader = (_cooldownTime - time) % (BlinkTime * 2) < BlinkTime ? DamageSpriteShader : _normalShader; + } + + private void FinishDamage() + { + _sprite.SpriteShader = _normalShader; + + if (CurrentLives > 0 && + _aiComponent.CurrentStateId != "pieceOfPower" && + _aiComponent.LastStateId != "pieceOfPower" && + _aiComponent.LastStateId != "knockBack") + { + // go back to the previous state without calling the init methods + if (HasDamageState && _returnState) + { + _returnState = false; + _aiComponent.ChangeState(_aiComponent.LastStateId, true); + } + } + } + + private void FinishKnockback() + { + _sprite.SpriteShader = _normalShader; + + // go back to the previous state without calling the init methods + _aiComponent.ChangeState(_aiComponent.LastStateId, true); + } + + private void DeathTick(double time) + { + // die when the time is over or the velocity of the body is low enough + if (time <= 0 || (time < _cooldownTime - 175 && _body.Velocity.Length() < 0.5f && HitMultiplierX > 0 && HitMultiplierY > 0)) + { + if (_pieceOfPower) + { + _body.Drag = _bodyDrag; + _body.DragAir = _bodyDragAir; + } + + _deathCountdown.Stop(); + OnDeath(false); + } + } + + private void UpdateBlink(double time) + { + var blinkTime = BlinkTime; + _sprite.SpriteShader = time % (blinkTime * 2) >= blinkTime ? DamageSpriteShader : _normalShader; + } + + private void UpdateDeath() + { + _deathCount += Game1.DeltaTime; + if (_deathCount < 100) + return; + _deathCount -= 100; + + Game1.GameManager.PlaySoundEffect("D378-19-13"); + + var posX = (int)_gameObject.EntityPosition.X - ExplostionWidth / 2 + Game1.RandomNumber.Next(0, ExplostionWidth) - 8; + var posY = (int)_gameObject.EntityPosition.Y - (int)_gameObject.EntityPosition.Z + ExplosionOffsetY - ExplostionHeight + Game1.RandomNumber.Next(0, ExplostionHeight) - 8; + + // spawn explosion effect + _gameObject.Map.Objects.SpawnObject(new ObjAnimator(_gameObject.Map, posX, posY, Values.LayerTop, "Particles/spawn", "run", true)); + } + + public void OnDeathBoss(bool pieceOfPower) + { + Game1.GameManager.PlaySoundEffect("D370-16-10"); + + IsActive = false; + + // start the death animation + _aiComponent.ChangeState("deathBoss"); + } + + public void BaseOnDeath(bool pieceOfPower) + { + if (_gameObject.Map == null) + return; + + _gameObject.Map.Objects.DeleteObjects.Add(_gameObject); + + // play sound effect + if (pieceOfPower) + Game1.GameManager.PlaySoundEffect("D370-18-12"); + + Game1.GameManager.PlaySoundEffect("D378-19-13"); + + // spawn explosion effect + var bodyCenter = _body.BodyBox.Box.Center; + bodyCenter.Y += ExplosionOffsetY; + if (DeathAnimation) + if (!pieceOfPower) + { + Game1.GameManager.MapManager.CurrentMap.Objects.SpawnObject( + new ObjAnimator(_gameObject.Map, (int)bodyCenter.X - 12, (int)(bodyCenter.Y - _body.Position.Z - 12 - 5), + Values.LayerTop, "Particles/explosion0", "run", true)); + } + else + { + var animation = new ObjAnimator(_gameObject.Map, 0, 0, Values.LayerTop, "Particles/pieceOfPowerExplosion", "run", true); + animation.EntityPosition.Set(new Vector2(bodyCenter.X, bodyCenter.Y - _body.Position.Z)); + Game1.GameManager.MapManager.CurrentMap.Objects.SpawnObject(animation); + } + + if (!SpawnItems) + return; + + Game1.GameManager.GuardianAcornCount++; + Game1.GameManager.PieceOfPowerCount++; + + // TODO_End reevaluate + // spawn heart or ruby + string strObject = SpawnItem; + if (strObject == null) + { + var random = Game1.RandomNumber.Next(0, 100); + if (random < 33) + strObject = "ruby"; + else if (random < 40) + strObject = "heart"; + } + + if (Game1.GameManager.GuardianAcornCount >= 12) + { + Game1.GameManager.GuardianAcornCount -= 12; + + var objItem = new ObjItem(_gameObject.Map, 0, 0, "j", null, "guardianAcorn", null, true); + objItem.EntityPosition.Set(new Vector3(bodyCenter.X, bodyCenter.Y, _body.Position.Z)); + _gameObject.Map.Objects.SpawnObject(objItem); + } + // 40 to 45 enemies? + // @TODO: remove + else if (Game1.GameManager.PieceOfPowerCount >= 45) + { + Game1.GameManager.PieceOfPowerCount -= 45; + + var objItem = new ObjItem(_gameObject.Map, 0, 0, "j", null, "pieceOfPower", null, true); + objItem.EntityPosition.Set(new Vector3(bodyCenter.X, bodyCenter.Y, _body.Position.Z)); + _gameObject.Map.Objects.SpawnObject(objItem); + } + else if (strObject != null) + { + // spawn a heart or a ruby + var objItem = new ObjItem(_gameObject.Map, 0, 0, "j", null, strObject, null, true); + objItem.EntityPosition.Set(new Vector3(bodyCenter.X, bodyCenter.Y, _body.Position.Z)); + _gameObject.Map.Objects.SpawnObject(objItem); + } + } + } +} diff --git a/InGame/GameObjects/Base/Components/AI/AiDeepWaterState.cs b/InGame/GameObjects/Base/Components/AI/AiDeepWaterState.cs new file mode 100644 index 0000000..f637029 --- /dev/null +++ b/InGame/GameObjects/Base/Components/AI/AiDeepWaterState.cs @@ -0,0 +1,52 @@ +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Base.Components.AI +{ + class AiDeepWaterState + { + private readonly BodyComponent _body; + private readonly int _fallTime; + + private float _deepWaterCounter; + private double _lastDeepWaterCollision; + + public AiDeepWaterState(BodyComponent body, int fallTime = 250) + { + _body = body; + _body.OnDeepWaterFunction = OnDeepWaterCollision; + + _fallTime = fallTime; + } + + public void OnDeepWaterCollision() + { + if (_lastDeepWaterCollision != Game1.TotalGameTimeLast) + _deepWaterCounter = _fallTime; + + _deepWaterCounter -= Game1.DeltaTime; + + _lastDeepWaterCollision = Game1.TotalGameTime; + + if (_deepWaterCounter < 0) + { + FallDeath(); + } + } + + private void FallDeath() + { + // play sound effect + Game1.GameManager.PlaySoundEffect("D360-24-18"); + + // spawn splash effect + var fallAnimation = new ObjAnimator(_body.Owner.Map, + (int)(_body.Position.X + _body.OffsetX + _body.Width / 2.0f), + (int)(_body.Position.Y + _body.OffsetY + _body.Height / 2.0f), + Values.LayerPlayer, "Particles/fishingSplash", "idle", true); + _body.Owner.Map.Objects.SpawnObject(fallAnimation); + + _body.Owner.Map.Objects.DeleteObjects.Add(_body.Owner); + } + } +} diff --git a/InGame/GameObjects/Base/Components/AI/AiFallState.cs b/InGame/GameObjects/Base/Components/AI/AiFallState.cs new file mode 100644 index 0000000..54dae06 --- /dev/null +++ b/InGame/GameObjects/Base/Components/AI/AiFallState.cs @@ -0,0 +1,60 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Base.Components.AI +{ + class AiFallState + { + public delegate void HoleAbsorbFunction(); + + private readonly AiComponent _aiComponent; + private readonly BodyComponent _body; + private readonly HoleAbsorbFunction _onAbsorb; + private readonly HoleAbsorbFunction _onDeath; + + public AiFallState(AiComponent aiComponent, BodyComponent body, HoleAbsorbFunction onAbsorb = null, HoleAbsorbFunction onDeath = null, int fallTime = 600) + { + _aiComponent = aiComponent; + + _body = body; + _body.HoleAbsorb = OnHoleAbsorb; + + _onAbsorb = onAbsorb; + _onDeath = onDeath; + + var fallingState = new AiState(); + fallingState.Trigger.Add(new AiTriggerCountdown(fallTime, null, FallDeath)); + _aiComponent.States.Add("falling", fallingState); + } + + public void OnHoleAbsorb() + { + if (_aiComponent.CurrentStateId == "falling") + return; + + _aiComponent.ChangeState("falling"); + + _body.Drag = 0.0f; + _body.VelocityTarget = Vector2.Zero; + + _onAbsorb?.Invoke(); + } + + private void FallDeath() + { + _aiComponent.Owner.Map.Objects.DeleteObjects.Add(_aiComponent.Owner); + + // play sound effect + Game1.GameManager.PlaySoundEffect("D360-24-18"); + + var fallAnimation = new ObjAnimator(_aiComponent.Owner.Map, 0, 0, Values.LayerBottom, "Particles/fall", "idle", true); + fallAnimation.EntityPosition.Set(new Vector2( + _body.Position.X + _body.OffsetX + _body.Width / 2.0f - 5, + _body.Position.Y + _body.OffsetY + _body.Height / 2.0f - 5)); + _aiComponent.Owner.Map.Objects.SpawnObject(fallAnimation); + + _onDeath?.Invoke(); + } + } +} diff --git a/InGame/GameObjects/Base/Components/AI/AiState.cs b/InGame/GameObjects/Base/Components/AI/AiState.cs new file mode 100644 index 0000000..6aab3ed --- /dev/null +++ b/InGame/GameObjects/Base/Components/AI/AiState.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; + +namespace ProjectZ.InGame.GameObjects.Base.Components.AI +{ + class AiState + { + public delegate void InitFunction(); + public delegate void UpdateFunction(); + + public InitFunction Init; + public UpdateFunction Update; + + public List Trigger = new List(); + + public AiState() { } + + public AiState(UpdateFunction update) + { + Update = update; + } + } +} diff --git a/InGame/GameObjects/Base/Components/AI/AiStunnedState.cs b/InGame/GameObjects/Base/Components/AI/AiStunnedState.cs new file mode 100644 index 0000000..4598abf --- /dev/null +++ b/InGame/GameObjects/Base/Components/AI/AiStunnedState.cs @@ -0,0 +1,71 @@ +using System; + +namespace ProjectZ.InGame.GameObjects.Base.Components.AI +{ + class AiStunnedState + { + private readonly AiComponent _aiComponent; + private readonly AnimationComponent _animationComponent; + + private readonly int _shakeTime; + + private string _oldState; + private float _spriteOffsetX; + + public string ReturnState; + public float ShakeOffset = 2; + public bool SilentStateChange = true; + + public AiStunnedState(AiComponent aiComponent, AnimationComponent animationComponent, int stunTime, int shakeTime) + { + _aiComponent = aiComponent; + _animationComponent = animationComponent; + _shakeTime = shakeTime; + + var stateStunned = new AiState(); + stateStunned.Trigger.Add(new AiTriggerCountdown(stunTime, null, () => _aiComponent.ChangeState("shake"))); + var stateShake = new AiState { Init = InitShake }; + stateShake.Trigger.Add(new AiTriggerCountdown(_shakeTime, ShakeTick, ShakeEnd)); + + aiComponent.States.Add("stunned", stateStunned); + aiComponent.States.Add("shake", stateShake); + } + + public void StartStun() + { + // make sure to not save the stunned state to not create an endless stunned loop + if (_aiComponent.CurrentStateId != "stunned" && + _aiComponent.CurrentStateId != "shake") + _oldState = _aiComponent.CurrentStateId; + + Game1.GameManager.PlaySoundEffect("D360-03-03"); + + _aiComponent.ChangeState("stunned"); + } + + public bool IsStunned() + { + return _aiComponent.CurrentStateId == "stunned" || _aiComponent.CurrentStateId == "shake"; + } + + private void InitShake() + { + _spriteOffsetX = _animationComponent.SpriteOffset.X; + } + + private void ShakeTick(double counter) + { + // 4 frames to go left/right + _animationComponent.SpriteOffset.X = _spriteOffsetX + ShakeOffset * MathF.Sin(MathF.PI * ((_shakeTime - (float)counter) / 1000 * (60 / 4f))); + _animationComponent.UpdateSprite(); + } + + private void ShakeEnd() + { + _animationComponent.SpriteOffset.X = _spriteOffsetX; + + // change back to the state before the entity got stunned + _aiComponent.ChangeState(ReturnState != null ? ReturnState : _oldState, SilentStateChange); + } + } +} diff --git a/InGame/GameObjects/Base/Components/AI/AiTrigger.cs b/InGame/GameObjects/Base/Components/AI/AiTrigger.cs new file mode 100644 index 0000000..325c6e8 --- /dev/null +++ b/InGame/GameObjects/Base/Components/AI/AiTrigger.cs @@ -0,0 +1,11 @@ +using Microsoft.Xna.Framework; + +namespace ProjectZ.InGame.GameObjects.Base.Components.AI +{ + class AiTrigger + { + public virtual void OnInit() { } + + public virtual void Update() { } + } +} diff --git a/InGame/GameObjects/Base/Components/AI/AiTriggerCountdown.cs b/InGame/GameObjects/Base/Components/AI/AiTriggerCountdown.cs new file mode 100644 index 0000000..3ad7558 --- /dev/null +++ b/InGame/GameObjects/Base/Components/AI/AiTriggerCountdown.cs @@ -0,0 +1,73 @@ +namespace ProjectZ.InGame.GameObjects.Base.Components.AI +{ + class AiTriggerCountdown : AiTrigger + { + public delegate void TriggerFunction(double counter); + public delegate void TriggerEndFunction(); + + public TriggerFunction TickFunction; + public TriggerEndFunction CountdownEnd; + + public double CurrentTime; + public int StartTime; + public bool ResetAfterEnd; + + private bool _initRunningState; + private bool _isRunning; + + public AiTriggerCountdown(int startTime, TriggerFunction tickFunction, TriggerEndFunction countdownEnd, bool initRunningState = true) + { + StartTime = startTime; + + TickFunction = tickFunction; + CountdownEnd = countdownEnd; + + _initRunningState = initRunningState; + } + + public override void OnInit() + { + CurrentTime = StartTime; + _isRunning = _initRunningState; + } + + public override void Update() + { + if (!_isRunning) + return; + + CurrentTime -= Game1.DeltaTime; + + if (CurrentTime <= 0) + { + _isRunning = false; + CountdownEnd?.Invoke(); + if (ResetAfterEnd) + OnInit(); + } + else + TickFunction?.Invoke(CurrentTime); + } + + public bool IsRunning() + { + return _isRunning; + } + + public void Restart() + { + CurrentTime = StartTime; + _isRunning = true; + } + + public void Start() + { + _isRunning = true; + } + + public void Stop() + { + _isRunning = false; + } + } +} diff --git a/InGame/GameObjects/Base/Components/AI/AiTriggerRandomTime.cs b/InGame/GameObjects/Base/Components/AI/AiTriggerRandomTime.cs new file mode 100644 index 0000000..32067c3 --- /dev/null +++ b/InGame/GameObjects/Base/Components/AI/AiTriggerRandomTime.cs @@ -0,0 +1,50 @@ + +namespace ProjectZ.InGame.GameObjects.Base.Components.AI +{ + class AiTriggerRandomTime : AiTrigger + { + public delegate void TriggerFunction(); + + public TriggerFunction Triggered; + + public double CurrentTime; + + public int MinTime; + public int MaxTime; + + public bool IsRunning = true; + public bool ResetAfterEnd = true; + + public AiTriggerRandomTime(TriggerFunction triggered, int minTime, int maxTime) + { + Triggered = triggered; + + MinTime = minTime; + MaxTime = maxTime; + } + + public override void OnInit() + { + IsRunning = true; + CurrentTime = Game1.RandomNumber.Next(MinTime, MaxTime); + } + + public override void Update() + { + if (!IsRunning) + return; + + CurrentTime -= Game1.DeltaTime; + + if (CurrentTime > 0) + return; + + Triggered(); + + if (ResetAfterEnd) + OnInit(); + else + IsRunning = false; + } + } +} diff --git a/InGame/GameObjects/Base/Components/AI/AiTriggerSwitch.cs b/InGame/GameObjects/Base/Components/AI/AiTriggerSwitch.cs new file mode 100644 index 0000000..c1bbb1d --- /dev/null +++ b/InGame/GameObjects/Base/Components/AI/AiTriggerSwitch.cs @@ -0,0 +1,36 @@ + +namespace ProjectZ.InGame.GameObjects.Base.Components.AI +{ + class AiTriggerSwitch : AiTrigger + { + public int StartTime; + public double CurrentTime; + public bool State; + + public AiTriggerSwitch(int startTime) + { + StartTime = startTime; + } + + public override void OnInit() + { + State = true; + CurrentTime = 0; + } + + public override void Update() + { + if (CurrentTime > 0) + CurrentTime -= Game1.DeltaTime; + + if (CurrentTime <= 0) + State = true; + } + + public void Reset() + { + CurrentTime = StartTime; + State = false; + } + } +} diff --git a/InGame/GameObjects/Base/Components/AI/AiTriggerTimer.cs b/InGame/GameObjects/Base/Components/AI/AiTriggerTimer.cs new file mode 100644 index 0000000..0e98792 --- /dev/null +++ b/InGame/GameObjects/Base/Components/AI/AiTriggerTimer.cs @@ -0,0 +1,36 @@ + +namespace ProjectZ.InGame.GameObjects.Base.Components.AI +{ + class AiTriggerTimer : AiTrigger + { + public int StartTime; + public double CurrentTime; + public bool State; + + public AiTriggerTimer(int startTime) + { + StartTime = startTime; + } + + public override void OnInit() + { + State = false; + CurrentTime = StartTime; + } + + public override void Update() + { + if (CurrentTime > 0) + CurrentTime -= Game1.DeltaTime; + + if (CurrentTime <= 0) + State = true; + } + + public void Reset() + { + CurrentTime = StartTime; + State = false; + } + } +} diff --git a/InGame/GameObjects/Base/Components/AI/AiTriggerUpdate.cs b/InGame/GameObjects/Base/Components/AI/AiTriggerUpdate.cs new file mode 100644 index 0000000..0f70d29 --- /dev/null +++ b/InGame/GameObjects/Base/Components/AI/AiTriggerUpdate.cs @@ -0,0 +1,19 @@ + +namespace ProjectZ.InGame.GameObjects.Base.Components.AI +{ + class AiTriggerUpdate : AiTrigger + { + public delegate void UpdateFunction(); + public UpdateFunction UpdateFun; + + public AiTriggerUpdate(UpdateFunction update) + { + UpdateFun = update; + } + + public override void Update() + { + UpdateFun?.Invoke(); + } + } +} diff --git a/InGame/GameObjects/Base/Components/AiComponent.cs b/InGame/GameObjects/Base/Components/AiComponent.cs new file mode 100644 index 0000000..a11a8a9 --- /dev/null +++ b/InGame/GameObjects/Base/Components/AiComponent.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using ProjectZ.InGame.GameObjects.Base.Components.AI; + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + class AiComponent : Component + { + public new static int Index = 0; + public static int Mask = 0x01 << Index; + + public Dictionary States = new Dictionary(); + public List Trigger = new List(); + + public AiState CurrentState; + + public string CurrentStateId; + public string LastStateId; + + public void ChangeState(string newStateId, bool silentMode = false) + { + LastStateId = CurrentStateId; + CurrentStateId = newStateId; + CurrentState = States[newStateId]; + + if (!silentMode) + { + CurrentState.Init?.Invoke(); + + foreach (var trigger in CurrentState.Trigger) + trigger.OnInit(); + } + } + } +} diff --git a/InGame/GameObjects/Base/Components/AnimationComponent.cs b/InGame/GameObjects/Base/Components/AnimationComponent.cs new file mode 100644 index 0000000..d24e9bd --- /dev/null +++ b/InGame/GameObjects/Base/Components/AnimationComponent.cs @@ -0,0 +1,74 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base.CObjects; + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + class AnimationComponent : BaseAnimationComponent + { + public CSprite Sprite; + public Animator Animator; + + public Vector2 SpriteOffset; + + private bool _mirroredV; + public bool MirroredV + { + get => _mirroredV; + set + { + _mirroredV = value; + UpdateSprite(); + } + } + + private bool _mirroredH; + public bool MirroredH + { + get => _mirroredH; + set + { + _mirroredH = value; + UpdateSprite(); + } + } + + public AnimationComponent(Animator animator, CSprite sprite, Vector2 spriteOffset) + { + Animator = animator; + Animator.OnFrameChange = UpdateSprite; + + SpriteOffset = spriteOffset; + Sprite = sprite; + Sprite.SprTexture = animator.SprTexture; + + UpdateSprite(); + } + + public void UpdateSprite() + { + var offsetX = MirroredH ? -1 : 1; + Sprite.DrawOffset.X = SpriteOffset.X + (Animator.CurrentAnimation.Offset.X + + Animator.CurrentFrame.Offset.X) * offsetX; + + var offsetY = MirroredV ? -1 : 1; + Sprite.DrawOffset.Y = SpriteOffset.Y + (Animator.CurrentAnimation.Offset.Y + + Animator.CurrentFrame.Offset.Y) * offsetY; + + if (MirroredH) + Sprite.DrawOffset.X -= Animator.CurrentFrame.SourceRectangle.Width; + if (MirroredV) + Sprite.DrawOffset.Y -= Animator.CurrentFrame.SourceRectangle.Height; + + Sprite.SourceRectangle = Animator.CurrentFrame.SourceRectangle; + Sprite.SpriteEffect = + (Animator.CurrentFrame.MirroredV ^ MirroredV ? SpriteEffects.FlipVertically : SpriteEffects.None) | + (Animator.CurrentFrame.MirroredH ^ MirroredH ? SpriteEffects.FlipHorizontally : SpriteEffects.None); + } + + public override void UpdateAnimation() + { + Animator.Update(); + } + } +} diff --git a/InGame/GameObjects/Base/Components/AnimationSheetComponent.cs b/InGame/GameObjects/Base/Components/AnimationSheetComponent.cs new file mode 100644 index 0000000..18e6ecd --- /dev/null +++ b/InGame/GameObjects/Base/Components/AnimationSheetComponent.cs @@ -0,0 +1,17 @@ +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + class AnimationSheetComponent : BaseAnimationComponent + { + public SheetAnimator Animator; + + public AnimationSheetComponent(SheetAnimator animator) + { + Animator = animator; + } + + public override void UpdateAnimation() + { + Animator.Update(); + } + } +} diff --git a/InGame/GameObjects/Base/Components/BaseAnimationComponent.cs b/InGame/GameObjects/Base/Components/BaseAnimationComponent.cs new file mode 100644 index 0000000..491c608 --- /dev/null +++ b/InGame/GameObjects/Base/Components/BaseAnimationComponent.cs @@ -0,0 +1,13 @@ + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + class BaseAnimationComponent : Component + { + public new static int Index = 1; + public static int Mask = 0x01 << Index; + + public bool UpdateWithOpenDialog; + + public virtual void UpdateAnimation() { } + } +} diff --git a/InGame/GameObjects/Base/Components/BlurDrawComponent.cs b/InGame/GameObjects/Base/Components/BlurDrawComponent.cs new file mode 100644 index 0000000..2faefc2 --- /dev/null +++ b/InGame/GameObjects/Base/Components/BlurDrawComponent.cs @@ -0,0 +1,23 @@ +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + public class BlurDrawComponent : Component + { + public delegate void DrawTemplate(SpriteBatch spriteBatch); + public DrawTemplate Draw; + + public new static int Index = 16; + public static int Mask = 0x01 << Index; + + public int Layer = Values.LightLayer0; + + protected BlurDrawComponent() { } + + public BlurDrawComponent(DrawTemplate draw) + { + Draw = draw; + } + } +} diff --git a/InGame/GameObjects/Base/Components/BodyCollisionComponent.cs b/InGame/GameObjects/Base/Components/BodyCollisionComponent.cs new file mode 100644 index 0000000..feebd30 --- /dev/null +++ b/InGame/GameObjects/Base/Components/BodyCollisionComponent.cs @@ -0,0 +1,28 @@ +using ProjectZ.Base; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + class BodyCollisionComponent : CollisionComponent + { + public BodyComponent Body; + + public bool IsActive = true; + + public BodyCollisionComponent(BodyComponent body, Values.CollisionTypes collisionType) + { + Body = body; + CollisionType = collisionType; + Collision = IsColliding; + } + + public bool IsColliding(Box box, int dir, int level, ref Box collidingBox) + { + if (!IsActive || !box.Intersects(Body.BodyBox.Box)) + return false; + + collidingBox = Body.BodyBox.Box; + return true; + } + } +} diff --git a/InGame/GameObjects/Base/Components/BodyComponent.cs b/InGame/GameObjects/Base/Components/BodyComponent.cs new file mode 100644 index 0000000..8900424 --- /dev/null +++ b/InGame/GameObjects/Base/Components/BodyComponent.cs @@ -0,0 +1,121 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + public class BodyComponent : Component + { + public delegate void MoveCollisionFunction(Values.BodyCollision collision); + public delegate void HoleAbsorbFunction(); + public delegate void HoleOnPullFunction(Vector2 direction, float percentage); + public delegate void DeepWaterFunction(); + + public MoveCollisionFunction MoveCollision; + public HoleAbsorbFunction HoleAbsorb; + public HoleOnPullFunction HoleOnPull; + public DeepWaterFunction OnDeepWaterFunction; + + public CBox BodyBox; + public CPosition Position; + + public Vector3 Velocity; + public Vector2 VelocityTarget; + public Vector2 LastVelocityTarget; + public Vector2 SlideOffset; + public Vector2 HoleAbsorption; + + // used for the rolling bands + // could probably be done in a better way (interface?) + public Vector2 AdditionalMovementVT; + public Vector2 LastAdditionalMovementVT; + + public RectangleF FieldRectangle = RectangleF.Empty; + + public MapStates.FieldStates CurrentFieldState = MapStates.FieldStates.Init; + public Values.CollisionTypes CollisionTypes = Values.CollisionTypes.Normal; + public Values.CollisionTypes CollisionTypesIgnore; + public Values.CollisionTypes AvoidTypes; + + public Values.BodyCollision VelocityCollision; + public Values.BodyCollision LastVelocityCollision; + + public float JumpStartHeight; + public float MaxJumpHeight = 4; + public float Drag = 0.8f; + public float DragAir = 0.9f; + public float DragWater = 0.95f; + public float Gravity = -0.25f; + public float Gravity2D = 0.1f; + public float Gravity2DWater = 0.025f; + public float Bounciness = 0; + public float Bounciness2D = 0; + public float SpeedMultiply = 1; + public float AbsorbPercentage = 1.0f; + // not sure why this was changed from beeing zero + public float AbsorbStop = 0.15f; + public float MaxSlideDistance = 6.0f; + + public float Width + { + get => BodyBox.Box.Width; + set => BodyBox.Box.Width = value; + } + public float Height + { + get => BodyBox.Box.Height; + set => BodyBox.Box.Height = value; + } + public float Depth + { + get => BodyBox.Box.Depth; + set => BodyBox.Box.Depth = value; + } + public float OffsetX + { + get => BodyBox.OffsetX; + set => BodyBox.OffsetX = value; + } + public float OffsetY + { + get => BodyBox.OffsetY; + set => BodyBox.OffsetY = value; + } + + public int DeepWaterOffset = -3; + + public int Level = 0; + + // used to make the xy movement happen in one step + // if there is a collision do not move any of them independently + public bool SimpleMovement = false; + // if the body is already inside a collider ignore the collider or not + public bool IgnoreInsideCollision = true; + + public bool IsActive = true; + public bool IsGrounded = true; + public bool WasGrounded = true; + public bool IgnoresZ; + public bool IgnoreHoles; + public bool IsPusher; + public bool IgnoreHeight; + public bool IsSlider; + public bool IsAbsorbed; + public bool WasHolePulled; + public bool DisableVelocityTargetMultiplier; // this is used for the vacuum + public bool RestAdditionalMovement = true; + public bool SplashEffect = true; + public bool UpdateFieldState = true; + + public new static int Index = 2; + public static int Mask = 0x01 << Index; + + public BodyComponent(CPosition position, int offsetX, int offsetY, int width, int height, int depth) + { + Position = position; + BodyBox = new CBox(position, offsetX, offsetY, width, height, depth); + } + } +} diff --git a/InGame/GameObjects/Base/Components/BodyDrawComponent.cs b/InGame/GameObjects/Base/Components/BodyDrawComponent.cs new file mode 100644 index 0000000..833c07d --- /dev/null +++ b/InGame/GameObjects/Base/Components/BodyDrawComponent.cs @@ -0,0 +1,87 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + class BodyDrawComponent : DrawComponent + { + public int WaterOutlineOffsetY; + + public bool WaterOutline = true; + public bool DeepWaterOutline = false; + public bool Gras = true; + + private readonly BodyComponent _body; + + public delegate void DrawFunc(SpriteBatch spriteBatch); + private DrawFunc _draw; + + private static Rectangle _sourceGrass; + private static Rectangle _sourceWater; + + public BodyDrawComponent(BodyComponent body, DrawFunc draw, int layer) + : base(layer, body.Position) + { + _body = body; + _draw = draw; + + Draw = DrawFunction; + + if (_sourceGrass == Rectangle.Empty) + _sourceGrass = Resources.SourceRectangle("grass"); + if (_sourceWater == Rectangle.Empty) + _sourceWater = Resources.SourceRectangle("water"); + } + + public BodyDrawComponent(BodyComponent body, CSprite sprite, int layer) + : this(body, sprite.Draw, layer) { } + + public void DrawFunction(SpriteBatch spriteBatch) + { + if (!IsActive) + return; + + var isOnWater = _body.CurrentFieldState.HasFlag(MapStates.FieldStates.Water) && WaterOutline || + _body.CurrentFieldState.HasFlag(MapStates.FieldStates.DeepWater) && DeepWaterOutline; + + // draw the water stuff + if (_body.IsActive && isOnWater && _body.IsGrounded && _body.Position.Z <= 0) + { + spriteBatch.Draw(Resources.SprObjects, new Vector2( + _body.Position.X + _body.OffsetX + _body.Width / 2f - 6, + _body.Position.Y - _body.Position.Z + _body.OffsetY + _body.Height - 6 + WaterOutlineOffsetY), + new Rectangle(_sourceWater.X, _sourceWater.Y + (Game1.TotalGameTime % 133 > 66 ? 9 : 0), _sourceWater.Width, _sourceWater.Height / 2), Color.White); + } + + _draw(spriteBatch); + + // draw water effect + if (_body.IsActive && isOnWater && _body.IsGrounded && _body.Position.Z <= 0) + { + spriteBatch.Draw(Resources.SprObjects, new Vector2( + _body.Position.X + _body.OffsetX + _body.Width / 2f - 6, + _body.Position.Y - _body.Position.Z + _body.OffsetY + _body.Height - 2 + WaterOutlineOffsetY), + new Rectangle(_sourceWater.X, _sourceWater.Y + _sourceWater.Height / 2 + (Game1.TotalGameTime % 133 > 66 ? 9 : 0), _sourceWater.Width, _sourceWater.Height / 2), Color.White); + } + + // draw grass if the body is standing on grass + if (_body.IsActive && Gras && _body.CurrentFieldState.HasFlag(MapStates.FieldStates.Grass) && _body.Position.Z < 4) + { + var flip = (_body.Position.X + _body.Position.Y) % 8 > 4; + + spriteBatch.Draw(Resources.SprObjects, new Vector2( + _body.Position.X + _body.OffsetX + _body.Width / 2f - 8, + _body.Position.Y + _body.OffsetY + _body.Height - 8), _sourceGrass, Color.White, + 0, Vector2.Zero, Vector2.One, !flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, 0); + + spriteBatch.Draw(Resources.SprObjects, new Vector2( + _body.Position.X + _body.OffsetX + _body.Width / 2f, + _body.Position.Y + _body.OffsetY + _body.Height - 8), _sourceGrass, Color.White, + 0, Vector2.Zero, Vector2.One, flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, 0); + } + } + } +} diff --git a/InGame/GameObjects/Base/Components/BodyDrawShadowComponent.cs b/InGame/GameObjects/Base/Components/BodyDrawShadowComponent.cs new file mode 100644 index 0000000..38d7d96 --- /dev/null +++ b/InGame/GameObjects/Base/Components/BodyDrawShadowComponent.cs @@ -0,0 +1,52 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + class BodyDrawShadowComponent : DrawShadowComponent + { + public float? Height; + public float? Rotation; + + public int ShadowWidth = 8; + public int ShadowHeight = 4; + + public int OffsetY = 0; + + public float Transparency = 1; + + private readonly BodyComponent _body; + private readonly CSprite _sprite; + + public BodyDrawShadowComponent(BodyComponent body, CSprite sprite) + { + _body = body; + _sprite = sprite; + + Draw = SpriteDrawFunction; + } + + public void SpriteDrawFunction(SpriteBatch spriteBatch) + { + if (!IsActive || !_sprite.IsVisible) + return; + + // draw the sprite shadow + var multSprite = 1 - _body.Position.Z / 10f; + if (multSprite > 0) + _sprite.DrawShadow(spriteBatch, Color.White * Transparency * multSprite, -1, Height ?? Owner.Map.ShadowHeight, Rotation ?? Owner.Map.ShadowRotation); + + // draw the shadow circle shadow below the body + if (_body.Position.Z > 0) + { + var mult = MathHelper.Clamp(_body.Position.Z / 1f, 0, 1); + DrawHelper.DrawShadow(Resources.SprItem, new Vector2( + _body.BodyBox.Box.X + _body.BodyBox.Box.Width / 2f - ShadowWidth / 2f, + _body.BodyBox.Box.Y + _body.BodyBox.Box.Height - ShadowHeight + OffsetY), + new Rectangle(1, 218, 8, 4), ShadowWidth, ShadowHeight, false, 1.0f, 0.0f, Color.White * Transparency * mult); + } + } + } +} diff --git a/InGame/GameObjects/Base/Components/BoxCollisionComponent.cs b/InGame/GameObjects/Base/Components/BoxCollisionComponent.cs new file mode 100644 index 0000000..dbf0a21 --- /dev/null +++ b/InGame/GameObjects/Base/Components/BoxCollisionComponent.cs @@ -0,0 +1,29 @@ +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + class BoxCollisionComponent : CollisionComponent + { + public CBox CollisionBox; + public int DirectionFlag = 15; + public bool IsActive = true; + + public BoxCollisionComponent(CBox collisionBox, Values.CollisionTypes collisionType) + { + CollisionBox = collisionBox; + CollisionType = collisionType; + Collision = IsColliding; + } + + public bool IsColliding(Box box, int dir, int level, ref Box collidingBox) + { + if (!IsActive || ((0x01 << dir) & DirectionFlag) == 0 || !box.Intersects(CollisionBox.Box)) + return false; + + collidingBox = CollisionBox.Box; + return true; + } + } +} diff --git a/InGame/GameObjects/Base/Components/CarriableComponent.cs b/InGame/GameObjects/Base/Components/CarriableComponent.cs new file mode 100644 index 0000000..d42394c --- /dev/null +++ b/InGame/GameObjects/Base/Components/CarriableComponent.cs @@ -0,0 +1,42 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base.CObjects; + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + public class CarriableComponent : Component + { + public delegate void StartFunction(); + public StartFunction StartGrabbing; + + public delegate Vector3 InitFunction(); + public InitFunction Init; + + public delegate bool UpdatePositionFunction(Vector3 position); + public UpdatePositionFunction UpdatePosition; + + public delegate void ThrowFunction(Vector2 direction); + public ThrowFunction Throw; + + public delegate bool PullFunction(Vector2 direction); + public PullFunction Pull; + + public CRectangle Rectangle; + + public int CarryHeight = 13; + + public bool IsHeavy; + public bool IsPickedUp; + public bool IsActive = true; + + public new static int Index = 3; + public static int Mask = 0x01 << Index; + + public CarriableComponent(CRectangle rectangle, InitFunction init, UpdatePositionFunction updatePosition, ThrowFunction @throw) + { + Rectangle = rectangle; + Init = init; + UpdatePosition = updatePosition; + Throw = @throw; + } + } +} diff --git a/InGame/GameObjects/Base/Components/CollisionComponent.cs b/InGame/GameObjects/Base/Components/CollisionComponent.cs new file mode 100644 index 0000000..e82e830 --- /dev/null +++ b/InGame/GameObjects/Base/Components/CollisionComponent.cs @@ -0,0 +1,23 @@ +using ProjectZ.Base; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + public class CollisionComponent : Component + { + public new static int Index = 4; + public static int Mask = 0x01 << Index; + + public delegate bool CollisionTemplate(Box box, int direction, int level, ref Box collidingBox); + public CollisionTemplate Collision; + + public Values.CollisionTypes CollisionType = Values.CollisionTypes.Normal; + + protected CollisionComponent() { } + + public CollisionComponent(CollisionTemplate collision) + { + Collision = collision; + } + } +} diff --git a/InGame/GameObjects/Base/Components/Component.cs b/InGame/GameObjects/Base/Components/Component.cs new file mode 100644 index 0000000..e2152ea --- /dev/null +++ b/InGame/GameObjects/Base/Components/Component.cs @@ -0,0 +1,8 @@ +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + public class Component + { + public GameObject Owner; + public static int Index; + } +} diff --git a/InGame/GameObjects/Base/Components/DamageFieldComponent.cs b/InGame/GameObjects/Base/Components/DamageFieldComponent.cs new file mode 100644 index 0000000..f267452 --- /dev/null +++ b/InGame/GameObjects/Base/Components/DamageFieldComponent.cs @@ -0,0 +1,43 @@ +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + class DamageFieldComponent : Component + { + public new static int Index = 10; + public static int Mask = 0x01 << Index; + + public delegate bool OnDamageTemplate(); + public OnDamageTemplate OnDamage; + + public delegate void OnDamagedPlayerTemplate(); + public OnDamagedPlayerTemplate OnDamagedPlayer; + + public CBox CollisionBox; + public HitType DamageType; + + public float PushMultiplier = 1.75f; + public int Strength; + public bool IsActive = true; + + public DamageFieldComponent(CBox collisionBox, HitType damageType, int damageStrength) + { + CollisionBox = collisionBox; + DamageType = damageType; + Strength = damageStrength; + + OnDamage = DamagePlayer; + } + + public bool DamagePlayer() + { + var damagedPlayer = MapManager.ObjLink.HitPlayer(CollisionBox.Box, DamageType, Strength, PushMultiplier); + if (damagedPlayer && OnDamagedPlayer != null) + OnDamagedPlayer(); + + return damagedPlayer; + } + } +} diff --git a/InGame/GameObjects/Base/Components/DrawCSpriteComponent.cs b/InGame/GameObjects/Base/Components/DrawCSpriteComponent.cs new file mode 100644 index 0000000..087cdca --- /dev/null +++ b/InGame/GameObjects/Base/Components/DrawCSpriteComponent.cs @@ -0,0 +1,25 @@ +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base.CObjects; + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + public class DrawCSpriteComponent : DrawComponent + { + public CSprite Sprite; + + public DrawCSpriteComponent(CSprite sprite, int layer) + : base(layer, sprite.Position) + { + Sprite = sprite; + Draw = DrawFunction; + } + + public void DrawFunction(SpriteBatch spriteBatch) + { + if (!IsActive) + return; + + Sprite.Draw(spriteBatch); + } + } +} diff --git a/InGame/GameObjects/Base/Components/DrawComponent.cs b/InGame/GameObjects/Base/Components/DrawComponent.cs new file mode 100644 index 0000000..4078995 --- /dev/null +++ b/InGame/GameObjects/Base/Components/DrawComponent.cs @@ -0,0 +1,47 @@ +using System; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base.CObjects; + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + public class DrawComponent : Component, IComparable + { + public delegate void DrawTemplate(SpriteBatch spriteBatch); + public DrawTemplate Draw; + + // The position is only used for sorting. Should it be removed? + public CPosition Position; + + public int Layer; + + public bool IsActive = true; + + public new static int Index = 5; + public static int Mask = 0x01 << Index; + + protected DrawComponent() { } + + public DrawComponent(int layer, CPosition position) + { + Layer = layer; + Position = position; + } + + public DrawComponent(DrawTemplate draw, int layer, CPosition position) + { + Draw = draw; + Layer = layer; + Position = position; + } + + public int CompareTo(DrawComponent other) + { + var compare = Layer.CompareTo(other.Layer); + + if (compare != 0) + return compare; + + return Position.Y.CompareTo(other.Position.Y); + } + } +} diff --git a/InGame/GameObjects/Base/Components/DrawShadowCSpriteComponent.cs b/InGame/GameObjects/Base/Components/DrawShadowCSpriteComponent.cs new file mode 100644 index 0000000..cbb611c --- /dev/null +++ b/InGame/GameObjects/Base/Components/DrawShadowCSpriteComponent.cs @@ -0,0 +1,29 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base.CObjects; + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + class DrawShadowCSpriteComponent : DrawShadowComponent + { + public CSprite Sprite; + public Color Color = Color.White; + + public float? Height; + public float? Rotation; + + public DrawShadowCSpriteComponent(CSprite sprite) + { + Sprite = sprite; + Draw = SpriteDrawFunction; + } + + public void SpriteDrawFunction(SpriteBatch spriteBatch) + { + if (!IsActive) + return; + + Sprite.DrawShadow(spriteBatch, Color, -1, Height ?? Owner.Map.ShadowHeight, Rotation ?? Owner.Map.ShadowRotation); + } + } +} diff --git a/InGame/GameObjects/Base/Components/DrawShadowComponent.cs b/InGame/GameObjects/Base/Components/DrawShadowComponent.cs new file mode 100644 index 0000000..b15eb52 --- /dev/null +++ b/InGame/GameObjects/Base/Components/DrawShadowComponent.cs @@ -0,0 +1,22 @@ +using Microsoft.Xna.Framework.Graphics; + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + class DrawShadowComponent : Component + { + public new static int Index = 6; + public static int Mask = 0x01 << Index; + + public delegate void DrawTemplate(SpriteBatch spriteBatch); + public DrawTemplate Draw; + + public bool IsActive = true; + + protected DrawShadowComponent() { } + + public DrawShadowComponent(DrawTemplate draw) + { + Draw = draw; + } + } +} diff --git a/InGame/GameObjects/Base/Components/DrawShadowSpriteComponent.cs b/InGame/GameObjects/Base/Components/DrawShadowSpriteComponent.cs new file mode 100644 index 0000000..e77e0dd --- /dev/null +++ b/InGame/GameObjects/Base/Components/DrawShadowSpriteComponent.cs @@ -0,0 +1,83 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + class DrawShadowSpriteComponent : DrawShadowComponent + { + public Texture2D Texture; + public Vector2 DrawOffset; + + public CPosition Position; + public Rectangle SourceRectangle; + + public Color Color = Color.White; + + public float Width; + public float Height; + + private float? ShadowHeight; + private float? ShadowRotation; + + public DrawShadowSpriteComponent(string spriteId, CPosition position, float? shadowHeight = null, float? shadowRotation = null) + { + var sprite = Resources.GetSprite(spriteId); + Texture = sprite.Texture; + Position = position; + SourceRectangle = sprite.SourceRectangle; + + Width = sprite.SourceRectangle.Width; + Height = sprite.SourceRectangle.Height; + DrawOffset = -sprite.Origin; + + ShadowHeight = shadowHeight; + ShadowRotation = shadowRotation; + + Draw = DrawShadow; + } + + public DrawShadowSpriteComponent(Texture2D texture, CPosition position, Rectangle sourceRectangle, Vector2 drawOffset, float? shadowHeight = null, float? shadowRotation = null) + { + Texture = texture; + Position = position; + SourceRectangle = sourceRectangle; + + Width = sourceRectangle.Width; + Height = sourceRectangle.Height; + DrawOffset = drawOffset; + + ShadowHeight = shadowHeight; + ShadowRotation = shadowRotation; + + Draw = DrawShadow; + } + + public DrawShadowSpriteComponent(Texture2D texture, CPosition position, Rectangle sourceRectangle, Vector2 drawOffset, int width, int height) + { + Texture = texture; + Position = position; + SourceRectangle = sourceRectangle; + + DrawOffset = drawOffset; + Width = width; + Height = height; + + ShadowHeight = 1.0f; + ShadowRotation = 0.0f; + + Draw = DrawShadow; + } + + private void DrawShadow(SpriteBatch spriteBatch) + { + if (!IsActive) + return; + + var position = new Vector2(Position.X + DrawOffset.X, Position.Y + DrawOffset.Y); + DrawHelper.DrawShadow(Texture, position, SourceRectangle, Width, Height, false, + ShadowHeight ?? Owner.Map.ShadowHeight, ShadowRotation ?? Owner.Map.ShadowRotation, Color); + } + } +} diff --git a/InGame/GameObjects/Base/Components/DrawSpriteComponent.cs b/InGame/GameObjects/Base/Components/DrawSpriteComponent.cs new file mode 100644 index 0000000..c3f371f --- /dev/null +++ b/InGame/GameObjects/Base/Components/DrawSpriteComponent.cs @@ -0,0 +1,42 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + public class DrawSpriteComponent : DrawComponent + { + public CSprite Sprite; + + public DrawSpriteComponent(string spriteId, CPosition position, int layer) + : base(layer, position) + { + var sprite = Resources.GetSprite(spriteId); + Sprite = new CSprite(sprite, position); + Draw = DrawFunction; + } + + public DrawSpriteComponent(string spriteId, CPosition position, Vector2 offset, int layer) + : base(layer, position) + { + Sprite = new CSprite(spriteId, position, offset); + Draw = DrawFunction; + } + + public DrawSpriteComponent(Texture2D sprite, CPosition position, Rectangle sourceRectangle, Vector2 offset, int layer) + : base(layer, position) + { + Sprite = new CSprite(sprite, position, sourceRectangle, offset); + Draw = DrawFunction; + } + + private void DrawFunction(SpriteBatch spriteBatch) + { + if (!IsActive) + return; + + Sprite.Draw(spriteBatch); + } + } +} diff --git a/InGame/GameObjects/Base/Components/HittableComponent.cs b/InGame/GameObjects/Base/Components/HittableComponent.cs new file mode 100644 index 0000000..1e37f9e --- /dev/null +++ b/InGame/GameObjects/Base/Components/HittableComponent.cs @@ -0,0 +1,25 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + class HittableComponent : Component + { + public new static int Index = 7; + public static int Mask = 0x01 << Index; + + public delegate Values.HitCollision HitTemplate(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower); + public HitTemplate Hit; + + public CBox HittableBox; + + public bool IsActive = true; + + public HittableComponent(CBox hittableBox, HitTemplate hit) + { + HittableBox = hittableBox; + Hit = hit; + } + } +} diff --git a/InGame/GameObjects/Base/Components/InteractComponent.cs b/InGame/GameObjects/Base/Components/InteractComponent.cs new file mode 100644 index 0000000..05e001f --- /dev/null +++ b/InGame/GameObjects/Base/Components/InteractComponent.cs @@ -0,0 +1,23 @@ +using ProjectZ.InGame.GameObjects.Base.CObjects; + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + class InteractComponent : Component + { + public new static int Index = 8; + public static int Mask = 0x01 << Index; + + public bool IsActive = true; + + public delegate bool InteractTemplate(); + public InteractTemplate InteractFunction; + + public CBox BoxInteractabel; + + public InteractComponent(CBox box, InteractTemplate interactFunction) + { + BoxInteractabel = box; + InteractFunction = interactFunction; + } + } +} diff --git a/InGame/GameObjects/Base/Components/KeyChangeListenerComponent.cs b/InGame/GameObjects/Base/Components/KeyChangeListenerComponent.cs new file mode 100644 index 0000000..5324507 --- /dev/null +++ b/InGame/GameObjects/Base/Components/KeyChangeListenerComponent.cs @@ -0,0 +1,19 @@ + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + public class KeyChangeListenerComponent : Component + { + public new static int Index = 14; + public static int Mask = 0x01 << Index; + + public delegate void KeyChangeTemplate(); + public KeyChangeTemplate KeyChangeFunction; + + protected KeyChangeListenerComponent() { } + + public KeyChangeListenerComponent(KeyChangeTemplate keyChangeFunction) + { + KeyChangeFunction = keyChangeFunction; + } + } +} diff --git a/InGame/GameObjects/Base/Components/LightDrawComponent.cs b/InGame/GameObjects/Base/Components/LightDrawComponent.cs new file mode 100644 index 0000000..c66ae9e --- /dev/null +++ b/InGame/GameObjects/Base/Components/LightDrawComponent.cs @@ -0,0 +1,23 @@ +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + public class LightDrawComponent : Component + { + public delegate void DrawTemplate(SpriteBatch spriteBatch); + public DrawTemplate Draw; + + public new static int Index = 9; + public static int Mask = 0x01 << Index; + + public int Layer = Values.LightLayer0; + + protected LightDrawComponent() { } + + public LightDrawComponent(DrawTemplate draw) + { + Draw = draw; + } + } +} diff --git a/InGame/GameObjects/Base/Components/ObjectCollisionComponent.cs b/InGame/GameObjects/Base/Components/ObjectCollisionComponent.cs new file mode 100644 index 0000000..0a012bd --- /dev/null +++ b/InGame/GameObjects/Base/Components/ObjectCollisionComponent.cs @@ -0,0 +1,31 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base.CObjects; + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + class ObjectCollisionComponent : Component + { + public delegate void ObjectCollisionTemplate(GameObject gameObject); + public ObjectCollisionTemplate OnCollision; + + public CRectangle CollisionRectangle; + public bool TriggerOnCollision = true; + + public new static int Index = 11; + public static int Mask = 0x01 << Index; + + protected ObjectCollisionComponent() { } + + public ObjectCollisionComponent(Rectangle collisionRectangle, ObjectCollisionTemplate onCollision) + { + CollisionRectangle = new CRectangle(collisionRectangle); + OnCollision = onCollision; + } + + public ObjectCollisionComponent(CRectangle collisionRectangle, ObjectCollisionTemplate onCollision) + { + CollisionRectangle = collisionRectangle; + OnCollision = onCollision; + } + } +} diff --git a/InGame/GameObjects/Base/Components/OcarinaListenerComponent.cs b/InGame/GameObjects/Base/Components/OcarinaListenerComponent.cs new file mode 100644 index 0000000..3f1a30b --- /dev/null +++ b/InGame/GameObjects/Base/Components/OcarinaListenerComponent.cs @@ -0,0 +1,19 @@ + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + public class OcarinaListenerComponent : Component + { + public new static int Index = 15; + public static int Mask = 0x01 << Index; + + public delegate void OcarinaPlayedTemplate(int ocarinaSong); + public OcarinaPlayedTemplate OcarinaPlayedFunction; + + protected OcarinaListenerComponent() { } + + public OcarinaListenerComponent(OcarinaPlayedTemplate ocarinaPlayedFunction) + { + OcarinaPlayedFunction = ocarinaPlayedFunction; + } + } +} diff --git a/InGame/GameObjects/Base/Components/PushableComponent.cs b/InGame/GameObjects/Base/Components/PushableComponent.cs new file mode 100644 index 0000000..0d1b9fb --- /dev/null +++ b/InGame/GameObjects/Base/Components/PushableComponent.cs @@ -0,0 +1,41 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base.CObjects; + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + public class PushableComponent : Component + { + public new static int Index = 13; + public static int Mask = 0x01 << Index; + + public enum PushType { Impact, Continues } + + public delegate bool PushableTemplate(Vector2 direction, PushType pushType); + public PushableTemplate Push; + + public CBox PushableBox; + + public double LastPushTime; + public double LastWaitTime; + + public float RepelMultiplier = 1f; + public float InertiaCounter; + + public int InertiaTime = 0; + public int CooldownTime = 250; + + public bool IsActive = true; + public bool RunActivate; + + // @HACK: getting repelled by this will have a sound and particle + public bool RepelParticle; + + protected PushableComponent() { } + + public PushableComponent(CBox rectangle, PushableTemplate push) + { + PushableBox = rectangle; + Push = push; + } + } +} diff --git a/InGame/GameObjects/Base/Components/ShadowBodyDrawComponent.cs b/InGame/GameObjects/Base/Components/ShadowBodyDrawComponent.cs new file mode 100644 index 0000000..bfa2c34 --- /dev/null +++ b/InGame/GameObjects/Base/Components/ShadowBodyDrawComponent.cs @@ -0,0 +1,34 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + class ShadowBodyDrawComponent : DrawShadowComponent + { + private readonly CPosition _position; + private readonly Vector2 _offset = new Vector2(0, -1.5f); + + public int ShadowWidth = 8; + public int ShadowHeight = 4; + + public float Transparency = 1; + + public ShadowBodyDrawComponent(CPosition position) + { + _position = position; + Draw = SpriteDrawFunction; + } + + public void SpriteDrawFunction(SpriteBatch spriteBatch) + { + if (!IsActive) + return; + + // draw the shadow + DrawHelper.DrawShadow(Resources.SprItem, new Vector2(_position.X - ShadowWidth / 2 + _offset.X, _position.Y - ShadowHeight / 2 + _offset.Y), + new Rectangle(1, 218, 8, 4), ShadowWidth, ShadowHeight, false, 1, 0, Color.White * ((_position.Z + 10) / 20f) * Transparency); + } + } +} diff --git a/InGame/GameObjects/Base/Components/UpdateComponent.cs b/InGame/GameObjects/Base/Components/UpdateComponent.cs new file mode 100644 index 0000000..1f5d92d --- /dev/null +++ b/InGame/GameObjects/Base/Components/UpdateComponent.cs @@ -0,0 +1,18 @@ +namespace ProjectZ.InGame.GameObjects.Base.Components +{ + class UpdateComponent : Component + { + public delegate void UpdateTemplate(); + public UpdateTemplate UpdateFunction; + + public new static int Index = 12; + public static int Mask = 0x01 << Index; + + protected UpdateComponent() { } + + public UpdateComponent(UpdateTemplate updateFunction) + { + UpdateFunction = updateFunction; + } + } +} diff --git a/InGame/GameObjects/Base/GameObject.cs b/InGame/GameObjects/Base/GameObject.cs new file mode 100644 index 0000000..bedcb69 --- /dev/null +++ b/InGame/GameObjects/Base/GameObject.cs @@ -0,0 +1,158 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; +using System.Diagnostics; + +namespace ProjectZ.InGame.GameObjects.Base +{ + public class GameObject + { + // editor stuff + public Texture2D SprEditorImage; + public Rectangle EditorIconSource; + public Color EditorColor = new Color(255, 255, 255) * 0.65f; + public float EditorIconScale = 1.0f; + + public Map.Map Map; + + public Values.GameObjectTag Tags; + + // entity component system stuff + public CPosition EntityPosition; + public Component[] Components = new Component[32]; // TODO_End: replace with actual component count + // should have probably used an enum... + + public Rectangle EntitySize = new Rectangle(-16, -16, 48, 48); + public Point EntityPoolPosition; + + public int ComponentsMask; + + public virtual bool IsActive { get; set; } = true; + public bool IsDead; + + public GameObject() { } + + // constructor used for the editor objects + public GameObject(string spriteId) + { + var sprite = Resources.GetSprite(spriteId); + + SprEditorImage = sprite.Texture; + EditorIconSource = sprite.ScaledRectangle; + EditorIconScale = sprite.Scale; + } + + public GameObject(Map.Map map, string spriteId) : this(spriteId) + { + Map = map; + } + + public GameObject(Map.Map map) + { + Map = map; + } + + public virtual void Init() { } + + public virtual void DrawEditor(SpriteBatch spriteBatch, Vector2 position) + { + if (SprEditorImage != null) + spriteBatch.Draw(SprEditorImage, position, EditorIconSource, EditorColor, + 0, Vector2.Zero, new Vector2(EditorIconScale), SpriteEffects.None, 0); + } + + public void AddComponent(int index, Component newComponent) + { + ComponentsMask |= (0x01 << index); + Components[index] = newComponent; + newComponent.Owner = this; + +#if DEBUG + if (EntityPosition == null) + return; + + if (newComponent is CarriableComponent) + { + var carriableComponent = (CarriableComponent)newComponent; + var rectangle = carriableComponent.Rectangle.Rectangle; + Debug.Assert(EntityPosition.X + EntitySize.X <= rectangle.X); + Debug.Assert(EntityPosition.Y + EntitySize.Y <= rectangle.Y); + Debug.Assert(rectangle.Right <= EntityPosition.X + EntitySize.X + EntitySize.Width); + Debug.Assert(rectangle.Bottom <= EntityPosition.Y + EntitySize.Y + EntitySize.Height); + } + if (newComponent is ObjectCollisionComponent) + { + var objectCollider = (ObjectCollisionComponent)newComponent; + var rectangle = objectCollider.CollisionRectangle.Rectangle; + Debug.Assert(EntityPosition.X + EntitySize.X <= rectangle.X); + Debug.Assert(EntityPosition.Y + EntitySize.Y <= rectangle.Y); + Debug.Assert(rectangle.Right <= EntityPosition.X + EntitySize.X + EntitySize.Width); + Debug.Assert(rectangle.Bottom <= EntityPosition.Y + EntitySize.Y + EntitySize.Height); + } + if (newComponent is BodyCollisionComponent) + { + var bodyComponent = (BodyCollisionComponent)newComponent; + var bodyBox = bodyComponent.Body.BodyBox.Box; + Debug.Assert(EntityPosition.X + EntitySize.X <= bodyBox.X); + Debug.Assert(EntityPosition.Y + EntitySize.Y <= bodyBox.Y); + Debug.Assert(bodyBox.Right <= EntityPosition.X + EntitySize.X + EntitySize.Width); + Debug.Assert(bodyBox.Front <= EntityPosition.Y + EntitySize.Y + EntitySize.Height); + } + if (newComponent is BoxCollisionComponent) + { + var boxCollisionComponent = (BoxCollisionComponent)newComponent; + var box = boxCollisionComponent.CollisionBox.Box; + Debug.Assert(EntityPosition.X + EntitySize.X <= box.X); + Debug.Assert(EntityPosition.Y + EntitySize.Y <= box.Y); + Debug.Assert(box.Right <= EntityPosition.X + EntitySize.X + EntitySize.Width); + Debug.Assert(box.Front <= EntityPosition.Y + EntitySize.Y + EntitySize.Height); + } + if (newComponent is DamageFieldComponent) + { + var damageComponent = (DamageFieldComponent)newComponent; + var box = damageComponent.CollisionBox.Box; + Debug.Assert(EntityPosition.X + EntitySize.X <= box.X); + Debug.Assert(EntityPosition.Y + EntitySize.Y <= box.Y); + Debug.Assert(box.Right <= EntityPosition.X + EntitySize.X + EntitySize.Width); + Debug.Assert(box.Front <= EntityPosition.Y + EntitySize.Y + EntitySize.Height); + } + //if (newComponent is HittableComponent) + //{ + // var hittableComponent = (HittableComponent)newComponent; + // var box = hittableComponent.HittableBox.Box; + // Debug.Assert(EntityPosition.X + EntitySize.X <= box.X); + // Debug.Assert(EntityPosition.Y + EntitySize.Y <= box.Y); + // Debug.Assert(box.Right <= EntityPosition.X + EntitySize.X + EntitySize.Width); + // Debug.Assert(box.Front <= EntityPosition.Y + EntitySize.Y + EntitySize.Height); + //} + if (newComponent is InteractComponent) + { + var interactionComponent = (InteractComponent)newComponent; + var box = interactionComponent.BoxInteractabel.Box; + Debug.Assert(EntityPosition.X + EntitySize.X <= box.X); + Debug.Assert(EntityPosition.Y + EntitySize.Y <= box.Y); + Debug.Assert(box.Right <= EntityPosition.X + EntitySize.X + EntitySize.Width); + Debug.Assert(box.Front <= EntityPosition.Y + EntitySize.Y + EntitySize.Height); + } + if (newComponent is PushableComponent) + { + var pushableComponent = (PushableComponent)newComponent; + var box = pushableComponent.PushableBox.Box; + Debug.Assert(EntityPosition.X + EntitySize.X <= box.X); + Debug.Assert(EntityPosition.Y + EntitySize.Y <= box.Y); + Debug.Assert(box.Right <= EntityPosition.X + EntitySize.X + EntitySize.Width); + Debug.Assert(box.Front <= EntityPosition.Y + EntitySize.Y + EntitySize.Height); + } +#endif + } + + public void RemoveComponent(int index) + { + ComponentsMask &= (ComponentsMask ^ (0x01 << index)); + Components[index].Owner = null; + Components[index] = null; + } + } +} diff --git a/InGame/GameObjects/Base/GameObjectFollower.cs b/InGame/GameObjects/Base/GameObjectFollower.cs new file mode 100644 index 0000000..fb44f29 --- /dev/null +++ b/InGame/GameObjects/Base/GameObjectFollower.cs @@ -0,0 +1,13 @@ +using Microsoft.Xna.Framework; + +namespace ProjectZ.InGame.GameObjects.Base +{ + public class GameObjectFollower : GameObject + { + public GameObjectFollower(string spriteId) : base(spriteId) { } + + public GameObjectFollower(Map.Map map) : base(map) { } + + public virtual void SetPosition(Vector2 position) { } + } +} diff --git a/InGame/GameObjects/Base/Pools/ComponentDrawPool.cs b/InGame/GameObjects/Base/Pools/ComponentDrawPool.cs new file mode 100644 index 0000000..d6db78a --- /dev/null +++ b/InGame/GameObjects/Base/Pools/ComponentDrawPool.cs @@ -0,0 +1,226 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base.Components; + +namespace ProjectZ.InGame.GameObjects.Base.Pools +{ + class ComponentDrawPool + { + // this sorting stuff is probably unnecessary if most objects are not using transparency between 0-1 + public class DrawTile + { + public List DrawComponents = new List(); + public float DrawPosition; + public int DrawIndex; + } + + public List NoneTiledObjects = new List(); + public DrawTile[,] ComponentTiles; + + public readonly int TileWidth; + public readonly int TileHeight; + + private int _noneTiledIndex; + + public ComponentDrawPool(int width, int height, int tileWidth, int tileHeight) + { + if (width <= 0) + width = 1; + if (height <= 0) + height = 1; + + var tWidth = width * 16; + var tHeight = height * 16; + + TileWidth = tileWidth; + TileHeight = tileHeight; + + ComponentTiles = new DrawTile[ + (int)Math.Ceiling(tWidth / (float)TileWidth), + (int)Math.Ceiling(tHeight / (float)TileHeight)]; + + for (var y = 0; y < ComponentTiles.GetLength(1); y++) + for (var x = 0; x < ComponentTiles.GetLength(0); x++) + ComponentTiles[x, y] = new DrawTile(); + } + + public void AddEntity(GameObject gameObject) + { + if (gameObject.EntityPosition == null) + { + NoneTiledObjects.Add(gameObject.Components[DrawComponent.Index] as DrawComponent); + return; + } + + var left = (int)(gameObject.EntityPosition.X / TileWidth); + var bottom = (int)(gameObject.EntityPosition.Y / TileHeight); + + left = MathHelper.Clamp(left, 0, ComponentTiles.GetLength(0) - 1); + bottom = MathHelper.Clamp(bottom, 0, ComponentTiles.GetLength(1) - 1); + + ComponentTiles[left, bottom].DrawComponents.Add(gameObject.Components[DrawComponent.Index] as DrawComponent); + + gameObject.EntityPosition.LastPosition = gameObject.EntityPosition.Position; + + // update tile placement after position the entity changes its position + gameObject.EntityPosition.AddPositionListener(typeof(ComponentDrawPool), newPosition => { UpdatePartition(gameObject); }); + } + + public virtual void RemoveEntity(GameObject gameObject) + { + if (gameObject.EntityPosition == null) + { + NoneTiledObjects.Remove(gameObject.Components[DrawComponent.Index] as DrawComponent); + return; + } + + gameObject.EntityPosition.PositionChangedDict.Remove(typeof(ComponentDrawPool)); + + var left = (int)(gameObject.EntityPosition.X / TileWidth); + var bottom = (int)(gameObject.EntityPosition.Y / TileHeight); + + left = MathHelper.Clamp(left, 0, ComponentTiles.GetLength(0) - 1); + bottom = MathHelper.Clamp(bottom, 0, ComponentTiles.GetLength(1) - 1); + + ComponentTiles[left, bottom].DrawComponents.Remove(gameObject.Components[DrawComponent.Index] as DrawComponent); + } + + private void UpdatePartition(GameObject gameObject) + { + var leftPre = (int)(gameObject.EntityPosition.LastPosition.X / TileWidth); + var bottomPre = (int)(gameObject.EntityPosition.LastPosition.Y / TileHeight); + + leftPre = MathHelper.Clamp(leftPre, 0, ComponentTiles.GetLength(0) - 1); + bottomPre = MathHelper.Clamp(bottomPre, 0, ComponentTiles.GetLength(1) - 1); + + var leftNow = (int)(gameObject.EntityPosition.Position.X / TileWidth); + var bottomNow = (int)(gameObject.EntityPosition.Position.Y / TileHeight); + + leftNow = MathHelper.Clamp(leftNow, 0, ComponentTiles.GetLength(0) - 1); + bottomNow = MathHelper.Clamp(bottomNow, 0, ComponentTiles.GetLength(1) - 1); + + // moved to another tile? + if (leftNow == leftPre && bottomNow == bottomPre) + return; + + // remove from the old tile + ComponentTiles[leftPre, bottomPre].DrawComponents.Remove(gameObject.Components[DrawComponent.Index] as DrawComponent); + // add to the new tile + ComponentTiles[leftNow, bottomNow].DrawComponents.Add(gameObject.Components[DrawComponent.Index] as DrawComponent); + } + + public void DrawPool(SpriteBatch spriteBatch, int posX, int posY, int width, int height, int startLayer, int endLayer) + { + var left = (posX - TileWidth) / TileWidth; + var right = (posX + width) / TileWidth; + var top = (posY - TileHeight) / TileHeight; + var bottom = (posY + height) / TileHeight; + + left = MathHelper.Clamp(left, 0, ComponentTiles.GetLength(0) - 1); + right = MathHelper.Clamp(right, 0, ComponentTiles.GetLength(0) - 1); + top = MathHelper.Clamp(top, 0, ComponentTiles.GetLength(1) - 1); + bottom = MathHelper.Clamp(bottom + 1, 0, ComponentTiles.GetLength(1) - 1); + + // sort the tiles + if (startLayer == 0) + { + NoneTiledObjects.Sort(); + _noneTiledIndex = 0; + + for (var y = top; y <= bottom; y++) + for (var x = left; x <= right; x++) + { + ComponentTiles[x, y].DrawIndex = 0; + ComponentTiles[x, y].DrawComponents.Sort(); + } + } + + // draw from start to end layer + for (var z = startLayer; z < endLayer; z++) + { + for (var y = top; y <= bottom; y++) + DrawTileRow(spriteBatch, z, y, left, right); + + for (; _noneTiledIndex < NoneTiledObjects.Count; _noneTiledIndex++) + { + var gameObject = NoneTiledObjects[_noneTiledIndex]; + if (!gameObject.IsActive) + continue; + + if (gameObject.Layer > z) + break; + + gameObject.Draw(spriteBatch); + } + } + } + + void DrawTileRow(SpriteBatch spriteBatch, int layer, int y, int left, int right) + { + var currentX = left; + var finishedX = left; + + for (var x = left; x <= right; x++) + { + if (ComponentTiles[x, y].DrawIndex == ComponentTiles[x, y].DrawComponents.Count || + ComponentTiles[x, y].DrawComponents[ComponentTiles[x, y].DrawIndex].Layer > layer) + { + ComponentTiles[x, y].DrawPosition = float.MaxValue; + finishedX++; + } + else + ComponentTiles[x, y].DrawPosition = + ComponentTiles[x, y].DrawComponents[ComponentTiles[x, y].DrawIndex].Position.Y; + } + + while (finishedX <= right) + { + if (ComponentTiles[currentX, y].DrawPosition == float.MaxValue) + { + currentX++; + if (currentX > right) + currentX = left; + + continue; + } + + while (ComponentTiles[currentX, y].DrawPosition < float.MaxValue) + { + // tile on the left needs to be drawn first? + if (currentX - 1 >= left && ComponentTiles[currentX, y].DrawPosition > ComponentTiles[currentX - 1, y].DrawPosition) + { + currentX--; + break; + } + + // does the tile to the right need to draw first? + if (currentX + 1 <= right && ComponentTiles[currentX, y].DrawPosition > ComponentTiles[currentX + 1, y].DrawPosition) + { + currentX++; + break; + } + + // draw the object + if (ComponentTiles[currentX, y].DrawComponents[ComponentTiles[currentX, y].DrawIndex].Owner.IsActive) + ComponentTiles[currentX, y].DrawComponents[ComponentTiles[currentX, y].DrawIndex].Draw(spriteBatch); + ComponentTiles[currentX, y].DrawIndex++; + + // all objects in the tile are drawn? + if (ComponentTiles[currentX, y].DrawIndex == ComponentTiles[currentX, y].DrawComponents.Count || + ComponentTiles[currentX, y].DrawComponents[ComponentTiles[currentX, y].DrawIndex].Layer > layer) + { + finishedX++; + ComponentTiles[currentX, y].DrawPosition = float.MaxValue; + continue; + } + + // update the draw position of the pool + ComponentTiles[currentX, y].DrawPosition = + ComponentTiles[currentX, y].DrawComponents[ComponentTiles[currentX, y].DrawIndex].Position.Y; + } + } + } + } +} diff --git a/InGame/GameObjects/Base/Pools/ComponentDrawPoolNew.cs b/InGame/GameObjects/Base/Pools/ComponentDrawPoolNew.cs new file mode 100644 index 0000000..eabf6d9 --- /dev/null +++ b/InGame/GameObjects/Base/Pools/ComponentDrawPoolNew.cs @@ -0,0 +1,266 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base.Components; + +namespace ProjectZ.InGame.GameObjects.Base.Pools +{ + class ComponentDrawPoolNew + { + // this sorting stuff is probably unnecessary if most objects are not using transparency between 0-1 + public class DrawTile + { + public List DrawComponents = new List(); + public float DrawPosition; + public int DrawIndex; + } + + public List NoneTiledObjects = new List(); + public DrawTile[,] ComponentTiles; + + public readonly int TileWidth; + public readonly int TileHeight; + + private int _noneTiledIndex; + + private List _currentObjects = new List(); + + public ComponentDrawPoolNew(int width, int height, int tileWidth, int tileHeight) + { + if (width <= 0) + width = 1; + if (height <= 0) + height = 1; + + var tWidth = width * 16; + var tHeight = height * 16; + + TileWidth = tileWidth; + TileHeight = tileHeight; + + ComponentTiles = new DrawTile[ + (int)Math.Ceiling(tWidth / (float)TileWidth), + (int)Math.Ceiling(tHeight / (float)TileHeight)]; + + for (var y = 0; y < ComponentTiles.GetLength(1); y++) + for (var x = 0; x < ComponentTiles.GetLength(0); x++) + ComponentTiles[x, y] = new DrawTile(); + } + + public void AddEntity(GameObject gameObject) + { + if (gameObject.EntityPosition == null) + { + NoneTiledObjects.Add(gameObject.Components[DrawComponent.Index] as DrawComponent); + return; + } + + var left = (int)((gameObject.EntityPosition.X + gameObject.EntitySize.X) / TileWidth); + var right = (int)((gameObject.EntityPosition.X + gameObject.EntitySize.X + gameObject.EntitySize.Width) / TileWidth); + + var top = (int)((gameObject.EntityPosition.Y + gameObject.EntitySize.Y) / TileHeight); + var bottom = (int)((gameObject.EntityPosition.Y + gameObject.EntitySize.Y + gameObject.EntitySize.Height) / TileHeight); + + left = MathHelper.Clamp(left, 0, ComponentTiles.GetLength(0) - 1); + right = MathHelper.Clamp(right, 0, ComponentTiles.GetLength(0) - 1); + top = MathHelper.Clamp(top, 0, ComponentTiles.GetLength(1) - 1); + bottom = MathHelper.Clamp(bottom, 0, ComponentTiles.GetLength(1) - 1); + + for (var y = top; y <= bottom; y++) + for (var x = left; x <= right; x++) + ComponentTiles[x, y].DrawComponents.Add(gameObject.Components[DrawComponent.Index] as DrawComponent); + + // update tile placement after the entity changes its position + gameObject.EntityPosition.AddPositionListener(typeof(ComponentPool), position => UpdatePartition(gameObject)); + } + + public void RemoveEntity(GameObject gameObject) + { + if (gameObject.EntityPosition == null) + { + NoneTiledObjects.Remove(gameObject.Components[DrawComponent.Index] as DrawComponent); + return; + } + + gameObject.EntityPosition.PositionChangedDict.Remove(typeof(ComponentPool)); + + var left = (int)((gameObject.EntityPosition.X + gameObject.EntitySize.X) / TileWidth); + var right = (int)((gameObject.EntityPosition.X + gameObject.EntitySize.X + gameObject.EntitySize.Width) / TileWidth); + + var top = (int)((gameObject.EntityPosition.Y + gameObject.EntitySize.Y) / TileHeight); + var bottom = (int)((gameObject.EntityPosition.Y + gameObject.EntitySize.Y + gameObject.EntitySize.Height) / TileHeight); + + left = MathHelper.Clamp(left, 0, ComponentTiles.GetLength(0) - 1); + right = MathHelper.Clamp(right, 0, ComponentTiles.GetLength(0) - 1); + top = MathHelper.Clamp(top, 0, ComponentTiles.GetLength(1) - 1); + bottom = MathHelper.Clamp(bottom, 0, ComponentTiles.GetLength(1) - 1); + + for (var y = top; y <= bottom; y++) + for (var x = left; x <= right; x++) + ComponentTiles[x, y].DrawComponents.Remove(gameObject.Components[DrawComponent.Index] as DrawComponent); + } + + private void UpdatePartition(GameObject gameObject) + { + var left = (int)((gameObject.EntityPosition.LastPosition.X + gameObject.EntitySize.X) / TileWidth); + var right = (int)((gameObject.EntityPosition.LastPosition.X + gameObject.EntitySize.X + gameObject.EntitySize.Width) / TileWidth); + + var top = (int)((gameObject.EntityPosition.LastPosition.Y + gameObject.EntitySize.Y) / TileHeight); + var bottom = (int)((gameObject.EntityPosition.LastPosition.Y + gameObject.EntitySize.Y + gameObject.EntitySize.Height) / TileHeight); + + left = MathHelper.Clamp(left, 0, ComponentTiles.GetLength(0) - 1); + right = MathHelper.Clamp(right, 0, ComponentTiles.GetLength(0) - 1); + top = MathHelper.Clamp(top, 0, ComponentTiles.GetLength(1) - 1); + bottom = MathHelper.Clamp(bottom, 0, ComponentTiles.GetLength(1) - 1); + + var leftNew = (int)((gameObject.EntityPosition.X + gameObject.EntitySize.X) / TileWidth); + var rightNew = (int)((gameObject.EntityPosition.X + gameObject.EntitySize.X + gameObject.EntitySize.Width) / TileWidth); + + var topNew = (int)((gameObject.EntityPosition.Y + gameObject.EntitySize.Y) / TileHeight); + var bottomNew = (int)((gameObject.EntityPosition.Y + gameObject.EntitySize.Y + gameObject.EntitySize.Height) / TileHeight); + + leftNew = MathHelper.Clamp(leftNew, 0, ComponentTiles.GetLength(0) - 1); + rightNew = MathHelper.Clamp(rightNew, 0, ComponentTiles.GetLength(0) - 1); + topNew = MathHelper.Clamp(topNew, 0, ComponentTiles.GetLength(1) - 1); + bottomNew = MathHelper.Clamp(bottomNew, 0, ComponentTiles.GetLength(1) - 1); + + // remove the entity at the old position + for (var y = top; y <= bottom; y++) + for (var x = left; x <= right; x++) + if (!(leftNew <= x && x <= rightNew && + topNew <= y && y <= bottomNew)) + ComponentTiles[x, y].DrawComponents.Remove(gameObject.Components[DrawComponent.Index] as DrawComponent); + + // add the entity at the new position + for (var y = topNew; y <= bottomNew; y++) + for (var x = leftNew; x <= rightNew; x++) + if (!(left <= x && x <= right && + top <= y && y <= bottom)) + ComponentTiles[x, y].DrawComponents.Add(gameObject.Components[DrawComponent.Index] as DrawComponent); + } + + public void DrawPool(SpriteBatch spriteBatch, int posX, int posY, int width, int height, int startLayer, int endLayer) + { + var left = posX / TileWidth; + var right = (posX + width) / TileWidth; + var top = posY / TileHeight; + var bottom = (posY + height) / TileHeight; + + left = MathHelper.Clamp(left, 0, ComponentTiles.GetLength(0) - 1); + right = MathHelper.Clamp(right, 0, ComponentTiles.GetLength(0) - 1); + top = MathHelper.Clamp(top, 0, ComponentTiles.GetLength(1) - 1); + bottom = MathHelper.Clamp(bottom, 0, ComponentTiles.GetLength(1) - 1); + + // sort the tiles + if (startLayer == 0) + { + NoneTiledObjects.Sort(); + _noneTiledIndex = 0; + + for (var y = top; y <= bottom; y++) + for (var x = left; x <= right; x++) + { + ComponentTiles[x, y].DrawIndex = 0; + ComponentTiles[x, y].DrawComponents.Sort(); + } + } + + // draw from start to end layer + for (var z = startLayer; z < endLayer; z++) + { + for (var y = top; y <= bottom; y++) + DrawTileRow(spriteBatch, z, y, left, right, top, bottom); + + for (; _noneTiledIndex < NoneTiledObjects.Count; _noneTiledIndex++) + { + var gameObject = NoneTiledObjects[_noneTiledIndex]; + if (!gameObject.IsActive) + continue; + + if (gameObject.Layer > z) + break; + + gameObject.Draw(spriteBatch); + } + } + } + + private void DrawTileRow(SpriteBatch spriteBatch, int layer, int y, int left, int right, int top, int bottom) + { + var currentX = left; + var finishedX = left; + + for (var x = left; x <= right; x++) + { + // finished drawing the tile? + if (ComponentTiles[x, y].DrawIndex == ComponentTiles[x, y].DrawComponents.Count || + ComponentTiles[x, y].DrawComponents[ComponentTiles[x, y].DrawIndex].Layer > layer) + { + ComponentTiles[x, y].DrawPosition = float.MaxValue; + finishedX++; + } + else + ComponentTiles[x, y].DrawPosition = + ComponentTiles[x, y].DrawComponents[ComponentTiles[x, y].DrawIndex].Position.Y; + } + + while (finishedX <= right) + { + // skip tile if it is already drawn + if (ComponentTiles[currentX, y].DrawPosition == float.MaxValue) + { + currentX++; + if (currentX > right) + currentX = left; + + continue; + } + + while (ComponentTiles[currentX, y].DrawPosition < float.MaxValue) + { + // TODO_Opt: this does only support components that are not split over more than one tile to the left or right of the Position.X tile + // tile on the left needs to be drawn first? + if (left <= currentX - 1 && ComponentTiles[currentX - 1, y].DrawPosition < ComponentTiles[currentX, y].DrawPosition) + { + currentX--; + break; + } + // does the tile on the right need to be drawn first? + if (currentX + 1 <= right && ComponentTiles[currentX, y].DrawPosition > ComponentTiles[currentX + 1, y].DrawPosition) + { + currentX++; + break; + } + + // draw the object + var drawComponent = ComponentTiles[currentX, y].DrawComponents[ComponentTiles[currentX, y].DrawIndex]; + var posX = (int)(drawComponent.Position.X / TileWidth); + var posY = (int)(drawComponent.Position.Y / TileHeight); + // make sure to only draw the component only one time + if (drawComponent.Owner.IsActive && + (posX == currentX || posX < left && currentX == left || right < posX && currentX == right) && + (posY == y || posY < top && y == top || bottom < posY && y == bottom)) + { + drawComponent.Draw(spriteBatch); + } + + ComponentTiles[currentX, y].DrawIndex++; + + // all objects in the tile are drawn? + if (ComponentTiles[currentX, y].DrawIndex == ComponentTiles[currentX, y].DrawComponents.Count || + ComponentTiles[currentX, y].DrawComponents[ComponentTiles[currentX, y].DrawIndex].Layer > layer) + { + finishedX++; + ComponentTiles[currentX, y].DrawPosition = float.MaxValue; + continue; + } + + // update the draw position of the tile + ComponentTiles[currentX, y].DrawPosition = + ComponentTiles[currentX, y].DrawComponents[ComponentTiles[currentX, y].DrawIndex].Position.Y; + } + } + } + } +} diff --git a/InGame/GameObjects/Base/Pools/ComponentPool.cs b/InGame/GameObjects/Base/Pools/ComponentPool.cs new file mode 100644 index 0000000..55c6c2c --- /dev/null +++ b/InGame/GameObjects/Base/Pools/ComponentPool.cs @@ -0,0 +1,235 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; + +namespace ProjectZ.InGame.GameObjects.Base.Pools +{ + public class ComponentPool + { + public class ObjectTile + { + public List GameObjects = new List(); + } + + public Map.Map Map; + + public List NoneTiledObjects = new List(); + public ObjectTile[,] ComponentTiles; + + public readonly int TileWidth; + public readonly int TileHeight; + + public ComponentPool(Map.Map map, int width, int height, int tileWidth, int tileHeight) + { + Map = map; + + if (width <= 0) + width = 1; + if (height <= 0) + height = 1; + + var tWidth = width * 16; + var tHeight = height * 16; + + TileWidth = tileWidth; + TileHeight = tileHeight; + + ComponentTiles = new ObjectTile[ + (int)Math.Ceiling(tWidth / (float)TileWidth), + (int)Math.Ceiling(tHeight / (float)TileHeight)]; + + for (var y = 0; y < ComponentTiles.GetLength(1); y++) + for (var x = 0; x < ComponentTiles.GetLength(0); x++) + ComponentTiles[x, y] = new ObjectTile(); + } + + public void AddEntity(GameObject gameObject) + { + if (gameObject.EntityPosition == null) + { + NoneTiledObjects.Add(gameObject); + return; + } + + var left = (int)((gameObject.EntityPosition.X + gameObject.EntitySize.X) / TileWidth); + var right = (int)((gameObject.EntityPosition.X + gameObject.EntitySize.X + gameObject.EntitySize.Width) / TileWidth); + + var top = (int)((gameObject.EntityPosition.Y + gameObject.EntitySize.Y) / TileHeight); + var bottom = (int)((gameObject.EntityPosition.Y + gameObject.EntitySize.Y + gameObject.EntitySize.Height) / TileHeight); + + left = MathHelper.Clamp(left, 0, ComponentTiles.GetLength(0) - 1); + right = MathHelper.Clamp(right, 0, ComponentTiles.GetLength(0) - 1); + top = MathHelper.Clamp(top, 0, ComponentTiles.GetLength(1) - 1); + bottom = MathHelper.Clamp(bottom, 0, ComponentTiles.GetLength(1) - 1); + + for (var y = top; y <= bottom; y++) + for (var x = left; x <= right; x++) + ComponentTiles[x, y].GameObjects.Add(gameObject); + + // the pool position is needed to not add duplicates to the component list + gameObject.EntityPoolPosition = new Point(left, top); + + gameObject.EntityPosition.LastPosition = gameObject.EntityPosition.Position; + + // update tile placement after the entity changes its position + gameObject.EntityPosition.AddPositionListener(typeof(ComponentPool), position => UpdatePartition(gameObject)); + } + + public void RemoveEntity(GameObject gameObject) + { + if (gameObject.EntityPosition == null) + { + NoneTiledObjects.Remove(gameObject); + return; + } + + gameObject.EntityPosition.PositionChangedDict.Remove(typeof(ComponentPool)); + + var left = (int)((gameObject.EntityPosition.X + gameObject.EntitySize.X) / TileWidth); + var right = (int)((gameObject.EntityPosition.X + gameObject.EntitySize.X + gameObject.EntitySize.Width) / TileWidth); + + var top = (int)((gameObject.EntityPosition.Y + gameObject.EntitySize.Y) / TileHeight); + var bottom = (int)((gameObject.EntityPosition.Y + gameObject.EntitySize.Y + gameObject.EntitySize.Height) / TileHeight); + + left = MathHelper.Clamp(left, 0, ComponentTiles.GetLength(0) - 1); + right = MathHelper.Clamp(right, 0, ComponentTiles.GetLength(0) - 1); + top = MathHelper.Clamp(top, 0, ComponentTiles.GetLength(1) - 1); + bottom = MathHelper.Clamp(bottom, 0, ComponentTiles.GetLength(1) - 1); + + for (var y = top; y <= bottom; y++) + for (var x = left; x <= right; x++) + ComponentTiles[x, y].GameObjects.Remove(gameObject); + } + + private void UpdatePartition(GameObject gameObject) + { + var left = (int)((gameObject.EntityPosition.LastPosition.X + gameObject.EntitySize.X) / TileWidth); + var right = (int)((gameObject.EntityPosition.LastPosition.X + gameObject.EntitySize.X + gameObject.EntitySize.Width) / TileWidth); + + var top = (int)((gameObject.EntityPosition.LastPosition.Y + gameObject.EntitySize.Y) / TileHeight); + var bottom = (int)((gameObject.EntityPosition.LastPosition.Y + gameObject.EntitySize.Y + gameObject.EntitySize.Height) / TileHeight); + + left = MathHelper.Clamp(left, 0, ComponentTiles.GetLength(0) - 1); + right = MathHelper.Clamp(right, 0, ComponentTiles.GetLength(0) - 1); + top = MathHelper.Clamp(top, 0, ComponentTiles.GetLength(1) - 1); + bottom = MathHelper.Clamp(bottom, 0, ComponentTiles.GetLength(1) - 1); + + var leftNew = (int)((gameObject.EntityPosition.X + gameObject.EntitySize.X) / TileWidth); + var rightNew = (int)((gameObject.EntityPosition.X + gameObject.EntitySize.X + gameObject.EntitySize.Width) / TileWidth); + + var topNew = (int)((gameObject.EntityPosition.Y + gameObject.EntitySize.Y) / TileHeight); + var bottomNew = (int)((gameObject.EntityPosition.Y + gameObject.EntitySize.Y + gameObject.EntitySize.Height) / TileHeight); + + leftNew = MathHelper.Clamp(leftNew, 0, ComponentTiles.GetLength(0) - 1); + rightNew = MathHelper.Clamp(rightNew, 0, ComponentTiles.GetLength(0) - 1); + topNew = MathHelper.Clamp(topNew, 0, ComponentTiles.GetLength(1) - 1); + bottomNew = MathHelper.Clamp(bottomNew, 0, ComponentTiles.GetLength(1) - 1); + + // remove the entity at the old position + for (var y = top; y <= bottom; y++) + for (var x = left; x <= right; x++) + if (!(leftNew <= x && x <= rightNew && + topNew <= y && y <= bottomNew)) + ComponentTiles[x, y].GameObjects.Remove(gameObject); + + // add the entity at the new position + for (var y = topNew; y <= bottomNew; y++) + for (var x = leftNew; x <= rightNew; x++) + if (!(left <= x && x <= right && + top <= y && y <= bottom)) + ComponentTiles[x, y].GameObjects.Add(gameObject); + + // the pool position is needed to not add duplicates to the component list + gameObject.EntityPoolPosition = new Point(leftNew, topNew); + } + + public void GetObjectList(List gameObjectList, int recLeft, int recTop, int recWidth, int recHeight) + { + var left = recLeft / TileWidth; + var right = (recLeft + recWidth) / TileWidth; + var top = recTop / TileHeight; + var bottom = (recTop + recHeight) / TileHeight; + + left = MathHelper.Clamp(left, 0, ComponentTiles.GetLength(0) - 1); + right = MathHelper.Clamp(right, 0, ComponentTiles.GetLength(0) - 1); + top = MathHelper.Clamp(top, 0, ComponentTiles.GetLength(1) - 1); + bottom = MathHelper.Clamp(bottom, 0, ComponentTiles.GetLength(1) - 1); + + for (var y = top; y <= bottom; y++) + for (var x = left; x <= right; x++) + foreach (var gameObject in ComponentTiles[x, y].GameObjects) + { + // check to not add objects more than once + if (gameObject.EntityPoolPosition.X == x && gameObject.EntityPoolPosition.Y == y || + x == left && y == top || + gameObject.EntityPoolPosition.X == x && y == top || + x == left && gameObject.EntityPoolPosition.Y == y) + gameObjectList.Add(gameObject); + } + + foreach (var gameObject in NoneTiledObjects) + gameObjectList.Add(gameObject); + } + + public GameObject GetObjectOfType(int recLeft, int recTop, int recWidth, int recHeight, Type type) + { + var left = recLeft / TileWidth; + var right = (recLeft + recWidth) / TileWidth; + var top = recTop / TileHeight; + var bottom = (recTop + recHeight) / TileHeight; + + left = MathHelper.Clamp(left, 0, ComponentTiles.GetLength(0) - 1); + right = MathHelper.Clamp(right, 0, ComponentTiles.GetLength(0) - 1); + top = MathHelper.Clamp(top, 0, ComponentTiles.GetLength(1) - 1); + bottom = MathHelper.Clamp(bottom, 0, ComponentTiles.GetLength(1) - 1); + + for (var y = top; y <= bottom; y++) + for (var x = left; x <= right; x++) + foreach (var gameObject in ComponentTiles[x, y].GameObjects) + { + // check to not add objects more than once + if ((gameObject.EntityPoolPosition.X == x && gameObject.EntityPoolPosition.Y == y || + x == left && y == top || + gameObject.EntityPoolPosition.X == x && y == top || + x == left && gameObject.EntityPoolPosition.Y == y) && + gameObject.GetType() == type) + return gameObject; + } + + foreach (var gameObject in NoneTiledObjects) + if (gameObject.GetType() == type) + return gameObject; + + return null; + } + + public void GetComponentList(List gameObjectList, int recLeft, int recTop, int recWidth, int recHeight, int componentMask) + { + var left = recLeft / TileWidth; + var right = (recLeft + recWidth) / TileWidth; + var top = recTop / TileHeight; + var bottom = (recTop + recHeight) / TileHeight; + + left = MathHelper.Clamp(left, 0, ComponentTiles.GetLength(0) - 1); + right = MathHelper.Clamp(right, 0, ComponentTiles.GetLength(0) - 1); + top = MathHelper.Clamp(top, 0, ComponentTiles.GetLength(1) - 1); + bottom = MathHelper.Clamp(bottom, 0, ComponentTiles.GetLength(1) - 1); + + for (var y = top; y <= bottom; y++) + for (var x = left; x <= right; x++) + foreach (var gameObject in ComponentTiles[x, y].GameObjects) + { + if ((gameObject.ComponentsMask & componentMask) != 0 && + (gameObject.EntityPoolPosition.X == x && gameObject.EntityPoolPosition.Y == y || + x == left && y == top || + gameObject.EntityPoolPosition.X == x && y == top || + x == left && gameObject.EntityPoolPosition.Y == y)) + gameObjectList.Add(gameObject); + } + + foreach (var gameObject in NoneTiledObjects) + if ((gameObject.ComponentsMask & componentMask) != 0) + gameObjectList.Add(gameObject); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Base/Systems/SystemAi.cs b/InGame/GameObjects/Base/Systems/SystemAi.cs new file mode 100644 index 0000000..42ed47d --- /dev/null +++ b/InGame/GameObjects/Base/Systems/SystemAi.cs @@ -0,0 +1,40 @@ +using System.Collections.Generic; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Pools; +using ProjectZ.InGame.Map; + +namespace ProjectZ.InGame.GameObjects.Base.Systems +{ + class SystemAi + { + public ComponentPool Pool; + + private readonly List _objectList = new List(); + + public void Update() + { + _objectList.Clear(); + Pool.GetComponentList(_objectList, + (int)((MapManager.Camera.X - Game1.RenderWidth / 2) / MapManager.Camera.Scale), + (int)((MapManager.Camera.Y - Game1.RenderHeight / 2) / MapManager.Camera.Scale), + (int)(Game1.RenderWidth / MapManager.Camera.Scale), + (int)(Game1.RenderHeight / MapManager.Camera.Scale), AiComponent.Mask); + + foreach (var gameObject in _objectList) + { + if (!gameObject.IsActive) + continue; + + var aiComponent = (gameObject.Components[AiComponent.Index]) as AiComponent; + + aiComponent?.CurrentState.Update?.Invoke(); + + foreach (var trigger in aiComponent.CurrentState.Trigger) + trigger.Update(); + + foreach (var trigger in aiComponent.Trigger) + trigger.Update(); + } + } + } +} diff --git a/InGame/GameObjects/Base/Systems/SystemAnimation.cs b/InGame/GameObjects/Base/Systems/SystemAnimation.cs new file mode 100644 index 0000000..ed3c70c --- /dev/null +++ b/InGame/GameObjects/Base/Systems/SystemAnimation.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Pools; +using ProjectZ.InGame.Map; + +namespace ProjectZ.InGame.GameObjects.Base.Systems +{ + class SystemAnimation + { + public ComponentPool Pool; + + private readonly List _objectList = new List(); + + public void Update(bool dialogOpen) + { + _objectList.Clear(); + Pool.GetComponentList(_objectList, + (int)((MapManager.Camera.X - Game1.RenderWidth / 2) / MapManager.Camera.Scale), + (int)((MapManager.Camera.Y - Game1.RenderHeight / 2) / MapManager.Camera.Scale), + (int)(Game1.RenderWidth / MapManager.Camera.Scale), + (int)(Game1.RenderHeight / MapManager.Camera.Scale), BaseAnimationComponent.Mask); + + foreach (var gameObject in _objectList) + { + if (!gameObject.IsActive) + continue; + + var animationComponent = (gameObject.Components[BaseAnimationComponent.Index]) as BaseAnimationComponent; + + // update the animation + if (!dialogOpen || animationComponent.UpdateWithOpenDialog) + animationComponent.UpdateAnimation(); + } + } + } +} diff --git a/InGame/GameObjects/Base/Systems/SystemBody.cs b/InGame/GameObjects/Base/Systems/SystemBody.cs new file mode 100644 index 0000000..f8c4c33 --- /dev/null +++ b/InGame/GameObjects/Base/Systems/SystemBody.cs @@ -0,0 +1,534 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Pools; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Base.Systems +{ + class SystemBody + { + public ComponentPool Pool; + + private readonly List _objectList = new List(); + private readonly List _holeList = new List(); + + public void Update(int threadIndex, int threadCount) + { + if (Game1.TimeMultiplier <= 0) + return; + + _objectList.Clear(); + Pool.GetComponentList(_objectList, + (int)((MapManager.Camera.X - Game1.RenderWidth / 2) / MapManager.Camera.Scale), + (int)((MapManager.Camera.Y - Game1.RenderHeight / 2) / MapManager.Camera.Scale), + (int)(Game1.RenderWidth / MapManager.Camera.Scale), + (int)(Game1.RenderHeight / MapManager.Camera.Scale), BodyComponent.Mask); + + foreach (var gameObject in _objectList) + { + if (!gameObject.IsActive) + continue; + + var component = gameObject.Components[BodyComponent.Index] as BodyComponent; + if (component.IsActive) + UpdateBody(component); + } + } + + private void UpdateBody(BodyComponent body) + { + var collisionType = Values.BodyCollision.None; + + body.SpeedMultiply = 1; + body.WasGrounded = body.IsGrounded; + + if (!Pool.Map.Is2dMap) + { + // z position update + if (!body.IgnoresZ) + collisionType |= UpdateVelocityZ(body); + + // hole pulling + if (!body.IgnoreHoles) + UpdateHole(body); + else + body.HoleAbsorption = Vector2.Zero; + } + + var velocityTargetMult = 1f; + + // the speed gets limited by the velocity and the hole absorption vector + if (!body.DisableVelocityTargetMultiplier) + { + float velocityLength; + if (Pool.Map.Is2dMap && !body.CurrentFieldState.HasFlag(MapStates.FieldStates.DeepWater)) + velocityLength = Math.Abs(body.Velocity.X) * 2.5f; + else + velocityLength = (new Vector2(body.Velocity.X, body.Velocity.Y).Length() + body.HoleAbsorption.Length()) * 1.5f; + + velocityTargetMult = MathHelper.Clamp(1f - velocityLength, 0, 1); + } + body.DisableVelocityTargetMultiplier = false; + + var velocityTarget = body.VelocityTarget * body.SpeedMultiply * velocityTargetMult; + + // AdditionalMovement should slide because the raft is using it to move + var bodyOffset = velocityTarget + body.HoleAbsorption + body.AdditionalMovementVT; + var slideOffset = body.SlideOffset; + + var velocityOffset = (new Vector2(body.Velocity.X, body.Velocity.Y) * (0.5f + body.SpeedMultiply * 0.5f)) * Game1.TimeMultiplier; + + body.LastVelocityTarget = body.VelocityTarget; + body.LastAdditionalMovementVT = body.AdditionalMovementVT; + + if (body.RestAdditionalMovement) + body.AdditionalMovementVT = Vector2.Zero; + + body.SlideOffset = Vector2.Zero; + + collisionType |= MoveBody(body, slideOffset + bodyOffset * Game1.TimeMultiplier, body.CollisionTypes | body.AvoidTypes, + body.IsPusher, body.IsSlider, false); + + // in 2d mode the velocity is also used to push, currently used for stomping goombas + // if the player gets pushed onto a push trigger it should not get activated + collisionType |= MoveBody(body, velocityOffset, body.CollisionTypes, Pool.Map.Is2dMap && body.IsPusher, false, true); + + // set IsGrounded in 2d mode + if (Pool.Map.Is2dMap) + { + body.IsGrounded = (collisionType & Values.BodyCollision.Vertical) != 0 && body.Velocity.Y > 0; + + if (body.IsGrounded) + { + // bounce of the ground + if (!body.WasGrounded && body.Velocity.Y * body.Bounciness2D > 0.4f) + body.Velocity.Y = -body.Velocity.Y * body.Bounciness2D; + else + body.Velocity.Y = 0; + } + + if (!body.IgnoresZ && (body.CurrentFieldState & MapStates.FieldStates.Init) == 0) + { + if (!body.IgnoresZ && (body.CurrentFieldState & MapStates.FieldStates.DeepWater) == 0) + body.Velocity.Y += body.Gravity2D * Game1.TimeMultiplier; + else if (!body.IgnoresZ && (body.CurrentFieldState & MapStates.FieldStates.DeepWater) != 0) + body.Velocity.Y += body.Gravity2DWater * Game1.TimeMultiplier; + } + } + + var drag = body.IsGrounded ? body.Drag : body.DragAir; + if (body.CurrentFieldState.HasFlag(MapStates.FieldStates.DeepWater)) + drag = body.DragWater; + + // apply drag if the body is grounded + body.Velocity.X *= (float)Math.Pow(drag, Game1.TimeMultiplier); + if (Math.Abs(body.Velocity.X) < 0.01f * Game1.TimeMultiplier) + body.Velocity.X = 0; + + if (!Pool.Map.Is2dMap || body.CurrentFieldState.HasFlag(MapStates.FieldStates.DeepWater)) + { + body.Velocity.Y *= (float)Math.Pow(drag, Game1.TimeMultiplier); + if (Math.Abs(body.Velocity.Y) < 0.01f * Game1.TimeMultiplier) + body.Velocity.Y = 0; + } + + if (body.Position.HasChanged()) + body.Position.NotifyListeners(); + + // get the current field the body is on + var lastFieldState = body.CurrentFieldState; + if (body.UpdateFieldState) + body.CurrentFieldState = GetFieldState(body); + + if (body.Position.Z <= 0 && body.SplashEffect && lastFieldState != MapStates.FieldStates.Init && (body.CurrentFieldState & MapStates.FieldStates.DeepWater) != 0) + { + if (body.Owner.Map.Is2dMap && (lastFieldState & MapStates.FieldStates.DeepWater) == 0) + { + body.Velocity.Y *= 0.25f; + + Game1.GameManager.PlaySoundEffect("D360-14-0E"); + + // spawn splash animation + var splashAnimator = new ObjAnimator(body.Owner.Map, 0, 0, 0, 3, 1, "Particles/splash", "idle", true); + splashAnimator.EntityPosition.Set(new Vector2(body.Position.X, body.Position.Y - 9)); + Game1.GameManager.MapManager.CurrentMap.Objects.SpawnObject(splashAnimator); + } + + body.OnDeepWaterFunction?.Invoke(); + } + + // inform the listener of the collision + body.VelocityCollision = collisionType; + if (collisionType != Values.BodyCollision.None) + body.MoveCollision?.Invoke(collisionType); + + body.LastVelocityCollision = collisionType; + } + + public static MapStates.FieldStates GetFieldState(BodyComponent body) + { + var state = Game1.GameManager.MapManager.CurrentMap.GetFieldState( + new Vector2(body.BodyBox.Box.X + body.BodyBox.Box.Width / 2, body.BodyBox.Box.Front - 0.01f)) & + ~(MapStates.FieldStates.Water | MapStates.FieldStates.DeepWater | MapStates.FieldStates.Lava) | + Game1.GameManager.MapManager.CurrentMap.GetFieldState( + new Vector2(body.BodyBox.Box.X + body.BodyBox.Box.Width / 2, body.BodyBox.Box.Front + body.DeepWaterOffset)) & + (MapStates.FieldStates.Water | MapStates.FieldStates.DeepWater | MapStates.FieldStates.Lava); + + return state; + } + + public static Values.BodyCollision MoveBody(BodyComponent body, Vector2 offset, Values.CollisionTypes collisionTypes, bool isPusher, bool slide, bool ignoreField) + { + var collisionType = Values.BodyCollision.None; + + // move body in one step without aligning it to colliding objects + if (body.SimpleMovement) + { + var collidingBox = Box.Empty; + var direction = AnimationHelper.GetDirection(offset); + + if (!Collision(body, body.Position.X + offset.X, body.Position.Y + offset.Y, direction, collisionTypes, ignoreField, ref collidingBox)) + { + body.Position.X += offset.X; + body.Position.Y += offset.Y; + } + else + { + // the returned collision type is not as precise as with the other method + collisionType |= (direction % 2 == 0 ? Values.BodyCollision.Horizontal : Values.BodyCollision.Vertical); + + if (direction == 0) + collisionType |= Values.BodyCollision.Left; + else if (direction == 1) + collisionType |= Values.BodyCollision.Top; + else if (direction == 2) + collisionType |= Values.BodyCollision.Right; + else if (direction == 3) + collisionType |= Values.BodyCollision.Bottom; + } + + return collisionType; + } + + if (offset.X != 0) + { + var collidingBox = Box.Empty; + + // move horizontally + if (!Collision(body, body.Position.X + offset.X, body.Position.Y, offset.X < 0 ? 0 : 2, collisionTypes, ignoreField, ref collidingBox)) + { + body.Position.X += offset.X; + } + else + { + var nullBox = Box.Empty; + collisionType |= offset.X < 0 ? Values.BodyCollision.Left : Values.BodyCollision.Right; + collisionType |= Values.BodyCollision.Horizontal; + + // try to move around the object if there is space around it + if (slide) + { + var sliderOffset = Math.Abs(offset.X * 0.5f); + + if (offset.Y >= 0 && !Collision(body, body.Position.X + offset.X, + body.Position.Y + body.MaxSlideDistance, offset.X < 0 ? 0 : 2, collisionTypes, ignoreField, ref nullBox)) + { + body.SlideOffset.Y += sliderOffset; + } + else if (offset.Y <= 0 && !Collision(body, body.Position.X + offset.X, + body.Position.Y - body.MaxSlideDistance, offset.X < 0 ? 0 : 2, collisionTypes, ignoreField, ref nullBox)) + { + body.SlideOffset.Y -= sliderOffset; + } + } + + // align with the collided object + if (offset.X < 0 && + Math.Abs(body.Position.X - collidingBox.Right + body.OffsetX) < Math.Abs(offset.X) && + !Collision(body, collidingBox.Right - body.OffsetX, body.Position.Y, 0, collisionTypes, ignoreField, ref nullBox)) + { + body.Position.X = collidingBox.Right - body.OffsetX; + } + else if (offset.X > 0 && + Math.Abs(body.Position.X - (collidingBox.X - (body.Width + body.OffsetX))) < Math.Abs(offset.X) && + !Collision(body, collidingBox.X - (body.Width + body.OffsetX), body.Position.Y, 2, collisionTypes, ignoreField, ref nullBox)) + { + body.Position.X = collidingBox.X - (body.Width + body.OffsetX); + } + + // try to push the colliding object + // if this is done before the alignment it can happen that the body walks into the object it is pushing + if (isPusher && Math.Abs(offset.X) > Math.Abs(offset.Y)) + { + var pushRectangle = new Box( + body.Position.X + offset.X + body.OffsetX, body.Position.Y + body.OffsetY, body.Position.Z, body.Width, body.Height, body.Depth); + Game1.GameManager.MapManager.CurrentMap.Objects.PushObject( + pushRectangle, new Vector2(Math.Sign(offset.X), 0), PushableComponent.PushType.Continues); + } + } + } + + if (offset.Y != 0) + { + var collidingBox = Box.Empty; + + // move vertically + if (!Collision(body, body.Position.X, body.Position.Y + offset.Y, offset.Y < 0 ? 1 : 3, collisionTypes, ignoreField, ref collidingBox)) + { + body.Position.Y += offset.Y; + } + else + { + var nullBox = Box.Empty; + collisionType |= offset.Y < 0 ? Values.BodyCollision.Top : Values.BodyCollision.Bottom; + collisionType |= Values.BodyCollision.Vertical; + + // try to move around the object if there is space around it + if (slide) + { + var sliderOffset = Math.Abs(offset.Y * 0.5f); + + if (offset.X >= 0 && !Collision(body, body.Position.X + body.MaxSlideDistance, + body.Position.Y + offset.Y, offset.Y < 0 ? 1 : 3, collisionTypes, ignoreField, ref nullBox)) + { + body.SlideOffset.X += sliderOffset; + } + else if (offset.X <= 0 && !Collision(body, body.Position.X - body.MaxSlideDistance, + body.Position.Y + offset.Y, offset.Y < 0 ? 1 : 3, collisionTypes, ignoreField, ref nullBox)) + { + body.SlideOffset.X -= sliderOffset; + } + } + + // align with the floor + if (offset.Y < 0 && + Math.Abs(body.Position.Y - (collidingBox.Front - body.OffsetY)) < Math.Abs(offset.Y) && + !Collision(body, body.Position.X, collidingBox.Front - body.OffsetY, 1, collisionTypes, ignoreField, ref nullBox)) + { + body.Position.Y = collidingBox.Front - body.OffsetY; + } + else if (offset.Y > 0 && + Math.Abs(body.Position.Y - (collidingBox.Y - (body.Height + body.OffsetY))) < Math.Abs(offset.Y) && + !Collision(body, body.Position.X, collidingBox.Y - (body.Height + body.OffsetY), 3, collisionTypes, ignoreField, ref nullBox)) + { + body.Position.Y = collidingBox.Y - (body.Height + body.OffsetY); + } + + // try to push the colliding object + if (isPusher && Math.Abs(offset.X) < Math.Abs(offset.Y)) + { + var pushRectangle = new Box( + body.Position.X + body.OffsetX, body.Position.Y + offset.Y + body.OffsetY, body.Position.Z, body.Width, body.Height, body.Depth); + Game1.GameManager.MapManager.CurrentMap.Objects.PushObject( + pushRectangle, new Vector2(0, Math.Sign(offset.Y)), PushableComponent.PushType.Continues); + } + } + } + + return collisionType; + } + + private Values.BodyCollision UpdateVelocityZ(BodyComponent body) + { + var collision = Values.BodyCollision.None; + + if (body.IgnoresZ) + { + body.IsGrounded = false; + return collision; + } + + // let the body fall + var floorHeight = 0f; + if (!body.IgnoreHeight) + { + // get the position of the floor at the position of the body + var depthBox = new Box( + body.Position.X + body.OffsetX, body.Position.Y + body.OffsetY, + body.Position.Z - body.Depth + 1, + body.Width, body.Height, body.Depth); + floorHeight = Game1.GameManager.MapManager.CurrentMap.Objects.GetDepth( + depthBox, body.CollisionTypes, body.JumpStartHeight + body.MaxJumpHeight); + } + + body.Velocity.Z += body.Gravity * Game1.TimeMultiplier; + body.Velocity.Z = Math.Clamp(body.Velocity.Z, -6, 6); + + // move the body up or down as long as it is not hitting the floor + if (body.Position.Z + body.Velocity.Z * Game1.TimeMultiplier > floorHeight && + (!body.IsGrounded || body.Velocity.Z >= 0 || Math.Abs(floorHeight - body.Position.Z) > 2)) + { + // set jump height at beginning of the jump + if (body.IsGrounded) + body.JumpStartHeight = body.Position.Z; + + body.Position.Z += body.Velocity.Z * Game1.TimeMultiplier; + body.IsGrounded = false; + } + else + { + // spawn splash animation + if (body.CurrentFieldState.HasFlag(MapStates.FieldStates.Water) && !body.IgnoreHeight && body.Velocity.Z < -0.5f) + { + var splashAnimator = new ObjAnimator(body.Owner.Map, 0, 0, 0, 3, Values.LayerPlayer, "Particles/splash", "idle", true); + splashAnimator.EntityPosition.Set(new Vector2( + body.Position.X + body.OffsetX + body.Width / 2f, + body.Position.Y + body.OffsetY + body.Height - body.Position.Z - 3)); + Game1.GameManager.MapManager.CurrentMap.Objects.SpawnObject(splashAnimator); + } + + // bounce from the ground but not on the water + if (body.Velocity.Z * body.Bounciness < -0.4f && + !body.CurrentFieldState.HasFlag(MapStates.FieldStates.DeepWater)) + body.Velocity.Z *= -body.Bounciness; + else + body.Velocity.Z = 0; + + if (!body.IsGrounded) + collision |= Values.BodyCollision.Floor; + + // don't move the body on top of the object it is colliding + if (body.Position.Z > floorHeight || + Math.Abs(body.Position.Z - floorHeight) <= 3) + body.Position.Z = floorHeight; + + body.JumpStartHeight = body.Position.Z; + body.IsGrounded = true; + } + + return collision; + } + + private void UpdateHole(BodyComponent body) + { + // check for collisions with holes + if (body.Position.Z > 0) + { + body.WasHolePulled = false; + return; + } + + var bodyBox = body.BodyBox.Box; + var bodyArea = bodyBox.Width * bodyBox.Height; + var bodyBoxCenter = body.BodyBox.Box.Center; + + var holeCollisionCoM = Vector2.Zero; + var holeCollisionArea = 0.0f; + + var noneCollisionCoM = bodyBoxCenter; + var noneCollisionArea = bodyBox.Width * bodyBox.Height; + + _holeList.Clear(); + Game1.GameManager.MapManager.CurrentMap.Objects.GetComponentList( + _holeList, (int)bodyBox.X, (int)bodyBox.Y, (int)bodyBox.Width, (int)bodyBox.Height, CollisionComponent.Mask); + + foreach (var hole in _holeList) + { + if (!hole.IsActive) + continue; + + var collisionObject = hole.Components[CollisionComponent.Index] as CollisionComponent; + var collidingBox = Box.Empty; + if ((collisionObject.CollisionType & Values.CollisionTypes.Hole) == 0 || + !collisionObject.Collision(bodyBox, 0, 0, ref collidingBox)) + continue; + + var collidingRec = bodyBox.Rectangle().GetIntersection(collidingBox.Rectangle()); + var collidingArea = collidingRec.Width * collidingRec.Height; + + // center of mass for the holes + holeCollisionCoM = + holeCollisionCoM * (holeCollisionArea / (holeCollisionArea + collidingArea)) + + collidingRec.Center * (collidingArea / (holeCollisionArea + collidingArea)); + + // this makes sure to not cancle out two holes pulling the body into different directions; otherwise the body would be able to walk between them if he is aligned with the + if (collidingArea == holeCollisionArea && holeCollisionCoM.X == bodyBoxCenter.X && collidingRec.Width * 2 != bodyBox.Width) + holeCollisionCoM.X -= 4; + if (collidingArea == holeCollisionArea && holeCollisionCoM.Y == bodyBoxCenter.Y && collidingRec.Height * 2 != bodyBox.Height) + holeCollisionCoM.Y += 4; + + holeCollisionArea += collidingArea; + } + + // calculate the new centers of mass and collision/none collision areas + noneCollisionCoM += (noneCollisionCoM - holeCollisionCoM) * (holeCollisionArea / noneCollisionArea); + noneCollisionArea -= holeCollisionArea; + + body.SpeedMultiply = 1 - holeCollisionArea / bodyArea; + + // the direction of the force applied to the body goes from the CoM of the body rectangle that is not colliding + // to the CoM of the body rectangle that is colliding + var holeDirection = holeCollisionCoM - noneCollisionCoM; + if (holeDirection != Vector2.Zero) + holeDirection.Normalize(); + + body.IsAbsorbed = false; + + var collisionAreaPercentage = holeCollisionArea / bodyArea; + + // the body is getting absorbed + if (holeCollisionArea >= bodyArea * body.AbsorbPercentage) + { + // absorption gets set to zero if the body jumped into the hole + // fixes a bug where the player can push an object on the other side of a hole while falling into it + if (!body.WasHolePulled) + body.HoleAbsorption = Vector2.Zero; + + body.Velocity = Vector3.Zero;// *= (float)Math.Pow(0.85f, Game1.TimeMultiplier); + body.HoleAbsorption *= (float)Math.Pow(0.85f, Game1.TimeMultiplier); + body.HoleAbsorb?.Invoke(); + body.IsAbsorbed = true; + } + // body is getting pulled towards the hole + else if (collisionAreaPercentage > body.AbsorbStop) + { + var holePull = new Vector2(holeDirection.X, holeDirection.Y) * collisionAreaPercentage * 0.5f; + + // calculate the new direction of the hole pull + var oldPercentage = (float)Math.Pow(0.8f, Game1.TimeMultiplier); + body.HoleAbsorption = body.HoleAbsorption * oldPercentage + + holePull * (1 - oldPercentage); + + body.HoleOnPull?.Invoke(holePull, collisionAreaPercentage); + body.WasHolePulled = true; + } + // stop the absorption + else if (body.HoleAbsorption != Vector2.Zero) + { + body.HoleAbsorption = Vector2.Zero; + body.HoleOnPull?.Invoke(Vector2.Zero, collisionAreaPercentage); + body.WasHolePulled = false; + } + } + + public static bool Collision(BodyComponent body, float posX, float posY, int direction, + Values.CollisionTypes collisionTypes, bool ignoreField, ref Box collidingBox) + { + // the +2 is to allow the body to move onto objects that are up to 2 higher + var box = new Box(posX + body.OffsetX, posY + body.OffsetY, + Math.Min(body.JumpStartHeight + body.MaxJumpHeight, body.Position.Z + 2), body.Width, body.Height, body.Depth); + var oldBox = new Box(body.Position.X + body.OffsetX, body.Position.Y + body.OffsetY, + Math.Min(body.JumpStartHeight + body.MaxJumpHeight, body.Position.Z), body.Width, body.Height, body.Depth); + + // check if the body is inside his allowed field or if he already left it + if (!ignoreField && body.FieldRectangle.Width > 0 && + !body.FieldRectangle.Contains(box.Rectangle()) && body.FieldRectangle.Contains(oldBox.Rectangle())) + return true; + + var cBox = Box.Empty; + if (Game1.GameManager.MapManager.CurrentMap.Objects.Collision( + box, body.IgnoreInsideCollision ? oldBox : Box.Empty, collisionTypes, body.CollisionTypesIgnore, direction, body.Level, ref cBox)) + { + collidingBox = cBox; + return true; + } + + return false; + } + } +} diff --git a/InGame/GameObjects/Bosses/AngerFishBlob.cs b/InGame/GameObjects/Bosses/AngerFishBlob.cs new file mode 100644 index 0000000..158ef99 --- /dev/null +++ b/InGame/GameObjects/Bosses/AngerFishBlob.cs @@ -0,0 +1,50 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + internal class AngerFishBlob : GameObject + { + private readonly BodyComponent _body; + private float _counter; + private bool _init; + + public AngerFishBlob(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(-2, -2, 5, 5); + + _body = new BodyComponent(EntityPosition, -2, 1, 5, 2, 8) + { + CollisionTypes = Values.CollisionTypes.None, + DeepWaterOffset = -6, + IgnoresZ = true, + SplashEffect = false + }; + _body.VelocityTarget.Y = -0.65f; + + var sprite = new CSprite(Resources.SprNightmares, EntityPosition, new Rectangle(37, 101, 5, 5), new Vector2(-2, -2)); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(BodyComponent.Index, _body); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerPlayer)); + } + + private void Update() + { + _counter += Game1.DeltaTime; + _body.VelocityTarget.X = MathF.Sin(_counter / 75f) * 0.15f; + + // despawn the blob + if (_init && !_body.CurrentFieldState.HasFlag(MapStates.FieldStates.DeepWater)) + Map.Objects.DeleteObjects.Add(this); + + _init = true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/AnglerFishStone.cs b/InGame/GameObjects/Bosses/AnglerFishStone.cs new file mode 100644 index 0000000..ad2420c --- /dev/null +++ b/InGame/GameObjects/Bosses/AnglerFishStone.cs @@ -0,0 +1,53 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + internal class AnglerFishStone : GameObject + { + private readonly BodyComponent _body; + private readonly CPosition _position; + + public AnglerFishStone(Map.Map map, int posX, int posY) : base(map) + { + _position = new CPosition(posX, posY, 0); + + var animator = AnimatorSaveLoad.LoadAnimator("nightmares/anger fish stone"); + animator.Play("run"); + + _body = new BodyComponent(_position, -8, -14, 16, 14, 8) + { + CollisionTypes = Values.CollisionTypes.None + }; + + var sprite = new CSprite(_position); + var animationComponent = new AnimationComponent(animator, sprite, new Vector2(-8, -14)); + + var damageBox = new CBox(_position, -6, -12, 12, 12, 8); + var hittableBox = new CBox(_position, -8, -14, 16, 14, 8); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 6)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerBottom)); + } + + private void Update() + { + // despawn the stone + if (_position.Y + 6 > Map.MapHeight * 16) + Map.Objects.DeleteObjects.Add(this); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + return Values.HitCollision.RepellingParticle; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossAnglerFish.cs b/InGame/GameObjects/Bosses/BossAnglerFish.cs new file mode 100644 index 0000000..34febd5 --- /dev/null +++ b/InGame/GameObjects/Bosses/BossAnglerFish.cs @@ -0,0 +1,370 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Enemies; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + class BossAnglerFish : GameObject + { + private readonly AiTriggerCountdown _damageCountdown; + private readonly AiTriggerCountdown _stoneCountdown; + private readonly AiTriggerRandomTime _fishCountdown; + private readonly AiTriggerRandomTime _blobCountdown; + + private readonly CSprite _sprite; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + + private readonly Color _lightColor = new Color(255, 200, 200); + + private readonly Vector2 _startPosition; + + private readonly string _saveKey; + + private const int CooldownTime = 350; + private const int StoneSpawnTime = 1500; + + private float _waitingCounter; + private float _deathCount; + private int _stoneCount; + + private const int Lives = 10; + private int _currentLives = Lives; + private bool _isAlive = true; + + private Vector2 _preAttackVelocity; + + public BossAnglerFish() : base("angler fish") { } + + public BossAnglerFish(Map.Map map, int posX, int posY, string saveKey) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 16, posY, 0); + EntitySize = new Rectangle(-26, -23 + 16, 56, 48); + + _startPosition = EntityPosition.Position; + + _saveKey = saveKey; + + if (!string.IsNullOrWhiteSpace(saveKey) && Game1.GameManager.SaveManager.GetString(saveKey) == "1") + { + // respawn the heart if the player died after he killed the boss without collecting the heart + SpawnHeart(); + + IsDead = true; + return; + } + + _animator = AnimatorSaveLoad.LoadAnimator("Nightmares/anger fish"); + _animator.Play("idle"); + + _sprite = new CSprite(EntityPosition); + + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-28, -24 + 16)); + + _body = new BodyComponent(EntityPosition, -20, -23 + 16, 50, 48, 8) + { + CollisionTypes = Values.CollisionTypes.Normal | Values.CollisionTypes.NPCWall, + Bounciness = 0.25f, + Drag = 0.85f, + IgnoresZ = true, + IsGrounded = false, + MoveCollision = OnCollision, + FieldRectangle = Map.GetField(posX, posY) + }; + + var hittableRectangle = new CBox(EntityPosition, -22, 0, 26, 26, 8); + var damageCollider = new CBox(EntityPosition, -18, -20 + 16, 47, 38, 8); + + var stateWaiting = new AiState(UpdateWaiting); + var stateMoving = new AiState(); + stateMoving.Trigger.Add(new AiTriggerRandomTime(StartAttacking, 5000, 7500)); + + var statePreAttack = new AiState(); + statePreAttack.Trigger.Add(new AiTriggerCountdown(500, null, ToAttack)); + var stateAttack = new AiState(); + var stateShaking = new AiState(); + stateShaking.Trigger.Add(new AiTriggerCountdown(800, null, ToRetrieving)); + var statePostAttack = new AiState(UpdatePostAttack); + + var stateBlink = new AiState(); + stateBlink.Trigger.Add(new AiTriggerCountdown(1000, DamageTick, ToDeath)); + var stateDeath = new AiState(UpdateDeath); + stateDeath.Trigger.Add(new AiTriggerCountdown(2000, DamageTick, RemoveObject)); + + _aiComponent = new AiComponent(); + + _aiComponent.Trigger.Add(_damageCountdown = new AiTriggerCountdown(CooldownTime, DamageTick, FinishDamage)); + _aiComponent.Trigger.Add(_stoneCountdown = new AiTriggerCountdown(StoneSpawnTime, null, SpawnStone)); + _aiComponent.Trigger.Add(_fishCountdown = new AiTriggerRandomTime(SpawnFish, 2000, 5000) { IsRunning = false }); + _aiComponent.Trigger.Add(_blobCountdown = new AiTriggerRandomTime(SpawnBlob, 1000, 1500)); + + _aiComponent.States.Add("waiting", stateWaiting); + _aiComponent.States.Add("moving", stateMoving); + _aiComponent.States.Add("preAttack", statePreAttack); + _aiComponent.States.Add("attack", stateAttack); + _aiComponent.States.Add("shaking", stateShaking); + _aiComponent.States.Add("postAttack", statePostAttack); + _aiComponent.States.Add("blink", stateBlink); + _aiComponent.States.Add("death", stateDeath); + + _aiComponent.ChangeState("waiting"); + + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 6)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableRectangle, OnHit)); + AddComponent(AnimationComponent.Index, animationComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerPlayer)); + AddComponent(LightDrawComponent.Index, new LightDrawComponent(DrawLight)); + } + + private void UpdateWaiting() + { + _waitingCounter += Game1.DeltaTime; + + // move up/down while waiting + EntityPosition.Set(new Vector2(EntityPosition.X, _startPosition.Y + MathF.Sin(_waitingCounter / 500f) * 7.5f)); + + if (MapManager.ObjLink.PosY > 160) + StartMoving(); + } + + private void StartMoving() + { + _aiComponent.ChangeState("moving"); + + // spawn dialog + Game1.GameManager.StartDialogPath("d4_nightmare"); + + // start moving and start spawning fish + _body.VelocityTarget.Y = 0.5f; + _fishCountdown.OnInit(); + } + + private void StartAttacking() + { + _aiComponent.ChangeState("preAttack"); + + _animator.SpeedMultiplier = 2.75f; + _preAttackVelocity = _body.VelocityTarget; + _body.VelocityTarget.Y = 0; + } + + private void ToAttack() + { + _aiComponent.ChangeState("attack"); + + Game1.GameManager.PlaySoundEffect("D370-13-0D"); + + _body.VelocityTarget.X = -3; + } + + private void ToShaking() + { + _aiComponent.ChangeState("shaking"); + + Game1.GameManager.PlaySoundEffect("D378-12-0C"); + Game1.GameManager.ShakeScreen(750, 2, 0, 5.0f, 0); + + _body.VelocityTarget.X = 0; + + // start spawning stones + _stoneCount = Game1.RandomNumber.Next(2, 4); // 2-3 stones + _stoneCountdown.OnInit(); + _stoneCountdown.CurrentTime = 1; // directly spawn a stone + _stoneCountdown.StartTime = StoneSpawnTime + Game1.RandomNumber.Next(0, 1000); + } + + private void ToRetrieving() + { + _aiComponent.ChangeState("postAttack"); + + _body.VelocityTarget.X = 2; + } + + private void UpdatePostAttack() + { + if (EntityPosition.X > _startPosition.X) + { + _aiComponent.ChangeState("moving"); + + _animator.SpeedMultiplier = 1.0f; + _body.VelocityTarget = _preAttackVelocity; + EntityPosition.Set(new Vector2(_startPosition.X, EntityPosition.Y)); + } + } + + private void SpawnStone() + { + _stoneCount--; + + if (_stoneCount > 0 && _isAlive) + _stoneCountdown.OnInit(); + + var randomX = Math.Clamp(MapManager.ObjLink.EntityPosition.X, + _body.FieldRectangle.Left + 25 + 8, _body.FieldRectangle.Right - 25 - 8) + (Game1.RandomNumber.Next(0, 50) - 25); + + var objStone = new AnglerFishStone(Map, (int)randomX, 16); + Map.Objects.SpawnObject(objStone); + } + + private void SpawnFish() + { + if (_isAlive || _currentLives < Lives) + _fishCountdown.OnInit(); + + var randomDir = (Game1.RandomNumber.Next(0, 2) * 2 - 1); + var randomX = 80 + randomDir * 88; + var randomY = Math.Clamp(MapManager.ObjLink.EntityPosition.Y, 124 + 35, 256 - 35) + (Game1.RandomNumber.Next(0, 70) - 35); + + var objFish = new EnemyAnglerFry(Map, randomX, (int)randomY, -randomDir); + Map.Objects.SpawnObject(objFish); + } + + private void SpawnBlob() + { + if (_isAlive) + _blobCountdown.OnInit(); + + var posX = (int)EntityPosition.X - 20; + var posY = (int)EntityPosition.Y - 12 + 16; + var objBlob = new AngerFishBlob(Map, posX, posY); + Map.Objects.SpawnObject(objBlob); + } + + private void OnCollision(Values.BodyCollision collision) + { + if ((collision & Values.BodyCollision.Vertical) != 0) + _body.VelocityTarget.Y = -_body.VelocityTarget.Y; + else if (_aiComponent.CurrentStateId == "attack") + ToShaking(); + } + + private void ToDeath() + { + _aiComponent.ChangeState("death"); + SetDamageSprite(false); + } + + private void DamageTick(double time) + { + var useDamageSprite = time % 133 < 66; + SetDamageSprite(useDamageSprite); + } + + private void SetDamageSprite(bool useDamageSprite) + { + // @HACK: not sure how this should be handled + // cant use a shader because there is no real color mapping that looks good + // in the original it does not look good and the sprites are not well connected + if (useDamageSprite && _sprite.SourceRectangle.X < 40) + _sprite.SourceRectangle.X += 64; + if (!useDamageSprite && _sprite.SourceRectangle.X > 40) + _sprite.SourceRectangle.X -= 64; + } + + private void UpdateDeath() + { + _deathCount += Game1.DeltaTime; + if (_deathCount > 100) + _deathCount -= 100; + else + return; + + Game1.GameManager.PlaySoundEffect("D378-19-13"); + + var posX = (int)EntityPosition.X + Game1.RandomNumber.Next(0, 28) - 34; + var posY = (int)EntityPosition.Y - (int)EntityPosition.Z + Game1.RandomNumber.Next(0, 28) - 10; + + // spawn explosion effect + Map.Objects.SpawnObject(new ObjAnimator(Map, posX, posY, Values.LayerTop, "Particles/spawn", "run", true)); + } + + private void RemoveObject() + { + SetDamageSprite(false); + + if (!string.IsNullOrEmpty(_saveKey)) + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + SpawnHeart(); + + Game1.GameManager.PlaySoundEffect("D378-26-1A"); + + // stop boss music + Game1.GameManager.SetMusic(-1, 2); + + Map.Objects.DeleteObjects.Add(this); + } + + private void SpawnHeart() + { + // spawn big heart + Map.Objects.SpawnObject(new ObjItem(Map, + (int)EntityPosition.X - 20, (int)EntityPosition.Y + 8, "", "d4_nHeart", "heartMeterFull", null)); + } + + private void FinishDamage() + { + if (_sprite.SourceRectangle.X > 40) + _sprite.SourceRectangle.X -= 64; + } + + private void DrawLight(SpriteBatch spriteBatch) + { + spriteBatch.Draw(Resources.SprLight, new Rectangle((int)EntityPosition.X - 22 - 32, (int)EntityPosition.Y - 18 - 16, 64, 64), _lightColor); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_currentLives <= 0) + return Values.HitCollision.None; + + if (damageType == HitType.Bow) + damage = 1; + if (damageType == HitType.Bomb) + damage = 4; + + if (_damageCountdown.CurrentTime <= 0) + { + _currentLives -= damage; + + // just died? + if (_currentLives <= 0) + { + Game1.GameManager.PlaySoundEffect("D370-16-10"); + _aiComponent.ChangeState("blink"); + _body.VelocityTarget = Vector2.Zero; + return Values.HitCollision.Repelling; + } + else + { + Game1.GameManager.PlaySoundEffect("D370-07-07"); + } + + _damageCountdown.OnInit(); + return Values.HitCollision.Repelling; + } + + return Values.HitCollision.None; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossEvilEagle.cs b/InGame/GameObjects/Bosses/BossEvilEagle.cs new file mode 100644 index 0000000..1ec20ca --- /dev/null +++ b/InGame/GameObjects/Bosses/BossEvilEagle.cs @@ -0,0 +1,571 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Enemies; +using ProjectZ.InGame.GameObjects.MidBoss; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + class BossEvilEagle : GameObject + { + private MBossGrimCreeper _grimCreeper; + private MBossGrimCreeperFly _creeperFly0; + private MBossGrimCreeperFly _creeperFly1; + + private readonly CSprite _sprite; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly AiDamageState _damageState; + private readonly DamageFieldComponent _damageComponent; + private readonly HittableComponent _hittableComponent; + + private readonly Vector2 _startPosition; + + private readonly string _saveKey; + + private Vector2 _slowStart; + private float _slowCounter; + private float _transparency = 0; + + private int _spawnIndex; + private int _direction; + + private const float FlySpeed = 2; + private const int Lives = 12; + + private Vector2 _wingStartPosition; + private Vector2 _wingEndPosition; + private float _wingCounter; + private float _featherCounter; + private const float WingTime = 700; + + private bool _featherAttack; + private bool _playedIntro; + private bool _introSound; + + public BossEvilEagle() : base("evil eagle") { } + + public BossEvilEagle(Map.Map map, int posX, int posY, string saveKey) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(-32, -32, 64, 64); + + _startPosition = EntityPosition.Position; + + _saveKey = saveKey; + + if (!string.IsNullOrWhiteSpace(_saveKey) && Game1.GameManager.SaveManager.GetString(_saveKey) == "1") + { + // respawn the heart if the player died after he killed the boss without collecting the heart + SpawnHeart(); + + IsDead = true; + return; + } + + _animator = AnimatorSaveLoad.LoadAnimator("Nightmares/evil eagle"); + _animator.Play("glide_-1"); + + _sprite = new CSprite(EntityPosition) { Color = Color.Transparent }; + + var animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -8, -16, 16, 16, 8) + { + CollisionTypes = Values.CollisionTypes.None, + Bounciness = 0.25f, + Drag = 1.0f, + DragAir = 1.0f, + IgnoresZ = true, + IsGrounded = false + }; + + var hittableRectangle = new CBox(EntityPosition, -8, -16, 16, 16, 8); + var damageCollider = new CBox(EntityPosition, -8, -16, 16, 16, 8); + + var stateIdle = new AiState(UpdateIdle) { Init = InitIdle }; + var stateSpawnDelay = new AiState(); + stateSpawnDelay.Trigger.Add(new AiTriggerCountdown(750, null, () => _aiComponent.ChangeState("spawning"))); + var stateSpawning = new AiState(UpdateSpawning) { Init = InitSpawning }; + var statePreJump = new AiState(); + statePreJump.Trigger.Add(new AiTriggerCountdown(1000, null, () => _aiComponent.ChangeState("grimSaddle"))); + var stateGrimSaddle = new AiState(UpdateGrimSaddle) { Init = InitGrimSaddle }; + var stateSaddled = new AiState(UpdateSaddled); + var stateAttack = new AiState(UpdateAttack) { Init = InitAttack }; + var stateDamaged = new AiState(UpdateDamaged); + stateDamaged.Trigger.Add(new AiTriggerCountdown(500, null, FlyUp)); + var stateFlyUp = new AiState(UpdateFlyUp) { Init = InitFlyUp }; + var stateAttackEnter = new AiState(UpdateWingAttackEnter) { Init = InitWingAttackEnter }; + var stateFeatherAttack = new AiState(UpdateWingAttack) { Init = InitWingAttack }; + var statePreAttack = new AiState() { Init = InitPreAttack }; + statePreAttack.Trigger.Add(new AiTriggerCountdown(800, null, () => _aiComponent.ChangeState("grabAttack"))); + var stateGrab = new AiState(UpdateAttackGrab) { Init = InitGrab }; + var stateLeave = new AiState(UpdateLeave) { Init = InitLeave }; + var stateGone = new AiState(); + stateGone.Trigger.Add(new AiTriggerCountdown(100, null, ToAttack)); + + _aiComponent = new AiComponent(); + _aiComponent.Trigger.Add(new AiTriggerUpdate(UpdateVisibility)); + + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("spawnDelay", stateSpawnDelay); + _aiComponent.States.Add("spawning", stateSpawning); + _aiComponent.States.Add("grimPreJump", statePreJump); + _aiComponent.States.Add("grimSaddle", stateGrimSaddle); + _aiComponent.States.Add("saddled", stateSaddled); + _aiComponent.States.Add("attack", stateAttack); + _aiComponent.States.Add("damaged", stateDamaged); + _aiComponent.States.Add("flyup", stateFlyUp); + _aiComponent.States.Add("attackEnter", stateAttackEnter); + _aiComponent.States.Add("featherAttack", stateFeatherAttack); + _aiComponent.States.Add("preAttack", statePreAttack); + _aiComponent.States.Add("grabAttack", stateGrab); + _aiComponent.States.Add("leave", stateLeave); + _aiComponent.States.Add("gone", stateGone); + + _damageState = new AiDamageState(this, _body, _aiComponent, _sprite, Lives, false, false, AiDamageState.BlinkTime * 2 * 10) { ExplosionOffsetY = 8 }; + _damageState.AddBossDamageState(OnDeath); + + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(DamageFieldComponent.Index, _damageComponent = new DamageFieldComponent(damageCollider, HitType.Enemy, 8)); + AddComponent(HittableComponent.Index, _hittableComponent = new HittableComponent(hittableRectangle, OnHit)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerPlayer)); + + InitStartSequence(); + _aiComponent.ChangeState("idle"); + + // spawn position + EntityPosition.Set(new Vector2(EntityPosition.X + 180, 24)); + } + + private void InitStartSequence() + { + _grimCreeper = new MBossGrimCreeper(Map, (int)EntityPosition.X - 32, (int)EntityPosition.Y + 32, null); + _grimCreeper.StartNightmareSequnece(); + Map.Objects.SpawnObject(_grimCreeper); + + _creeperFly0 = new MBossGrimCreeperFly(Map, new Vector2(EntityPosition.X - 41, EntityPosition.Y + 32), new Vector2(-24, 12)); + _creeperFly0.StartSequenceMode(); + Map.Objects.SpawnObject(_creeperFly0); + + _creeperFly1 = new MBossGrimCreeperFly(Map, new Vector2(EntityPosition.X - 7, EntityPosition.Y + 32), new Vector2(-16, -8)); + _creeperFly1.StartSequenceMode(); + Map.Objects.SpawnObject(_creeperFly1); + } + + private void UpdateVisibility() + { + var target = (_startPosition.X - 144 < EntityPosition.X && EntityPosition.X < _startPosition.X + 144 && + EntityPosition.Y > -16 && EntityPosition.Y < 160) ? 1 : 0; + _transparency = AnimationHelper.MoveToTarget(_transparency, target, 0.175f * Game1.TimeMultiplier); + _sprite.Color = Color.White * _transparency; + } + + private void InitIdle() + { + _body.Velocity = Vector3.Zero; + _body.VelocityTarget = Vector2.Zero; + _damageState.CurrentLives = Lives; + } + + private void UpdateIdle() + { + if (MapManager.ObjLink.EntityPosition.Y > _startPosition.Y + 90 || !MapManager.ObjLink.IsClimbing()) + return; + + if (!_playedIntro) + { + Game1.GameManager.StartDialogPath("grim_creeper_3"); + _aiComponent.ChangeState("spawnDelay"); + } + else + ToAttack(); + } + + private void SpawnHeart() + { + Map.Objects.SpawnObject(new ObjItem(Map, (int)_startPosition.X - 8, (int)_startPosition.Y, null, _saveKey + "_heart", "heartMeterFull", null)); + } + + private void InitPreAttack() + { + _animator.SpeedMultiplier = 1.5f; + + } + + private void InitGrab() + { + _animator.Stop(); + _animator.Play("cflap_" + _direction); + _animator.Stop(); + + // adjust the distance + var distance = MathF.Abs(MapManager.ObjLink.EntityPosition.X - EntityPosition.X); + var mult = Math.Clamp(distance / 40 * 1.45f, 0.35f, 1.5f); + var direction = new Vector2(_direction * mult, 1.45f); + direction.Normalize(); + + _body.VelocityTarget = direction * 4f; + } + + private void UpdateAttackGrab() + { + if (EntityPosition.Y > _startPosition.Y + 180) + ToAttack(); + } + + private void InitLeave() + { + //_body.VelocityTarget = new Vector2(0, -1); + } + + private void UpdateLeave() + { + if (_direction < 0 && _body.Velocity.X > -3) + _body.Velocity.X -= 0.15f * Game1.TimeMultiplier; + if (_direction > 0 && _body.Velocity.X < 3) + _body.Velocity.X += 0.15f * Game1.TimeMultiplier; + + if (_body.Velocity.Y > -2) + _body.Velocity.Y -= 0.015f * Game1.TimeMultiplier; + + // start playing the glide animation + if (_direction == -1 && EntityPosition.X < _startPosition.X || + _direction == 1 && EntityPosition.X > _startPosition.X) + { + _animator.Play("cglide_" + _direction); + } + if (_direction == -1 && EntityPosition.X < _startPosition.X - 160 || + _direction == 1 && EntityPosition.X > _startPosition.X + 160) + { + ToAttack(); + } + } + + private void InitWingAttackEnter() + { + _direction = MapManager.ObjLink.EntityPosition.X < _startPosition.X ? -1 : 1; + + // only show the first frame + _animator.Play("cflap_" + _direction); + _animator.Stop(); + + _body.Velocity = Vector3.Zero; + _body.VelocityTarget = Vector2.Zero; + + _wingCounter = 0; + _wingStartPosition = new Vector2(_startPosition.X - _direction * 100, _startPosition.Y - 24); + _wingEndPosition = new Vector2(_startPosition.X - _direction * 28, _startPosition.Y + 8); + + EntityPosition.Set(_wingStartPosition); + } + + private void UpdateWingAttackEnter() + { + _wingCounter += Game1.DeltaTime; + var percentage = _wingCounter / WingTime; + + // start flapping the wings + if (percentage > 0.80) + _animator.Continue(); + + if (percentage >= 1) + { + EntityPosition.Set(_wingEndPosition); + + // feather attack + if (_featherAttack) + _aiComponent.ChangeState("featherAttack"); + else + _aiComponent.ChangeState("preAttack"); + + _featherAttack = false; + + return; + } + + var lerpState = MathF.Sin(percentage * MathF.PI / 2); + var newPosition = Vector2.Lerp(_wingStartPosition, _wingEndPosition, lerpState); + EntityPosition.Set(newPosition); + } + + private void InitWingAttack() + { + _wingCounter = 0; + } + + private void UpdateWingAttack() + { + _wingCounter += Game1.DeltaTime; + + // end state + if (_wingCounter > 275 * 11) + { + _aiComponent.ChangeState("leave"); + } + + // move up and down + var offset = MathF.Sin(_wingCounter / 1100 * MathF.PI * 2 + MathF.PI / 2) * 4 - 4; + var newPosition = new Vector2(_wingEndPosition.X, _wingEndPosition.Y + offset); + EntityPosition.Set(newPosition); + + // push the playyer + if (MapManager.ObjLink.EntityPosition.Y < _startPosition.Y + 90) + MapManager.ObjLink._body.AdditionalMovementVT.X = _direction * 1.1f; + else + MapManager.ObjLink._body.AdditionalMovementVT.X = 0; + + // shoot a feather + _featherCounter += Game1.DeltaTime; + if (_featherCounter > 275) + { + _featherCounter = 0; + + var startPosition = new Vector2(EntityPosition.X - _direction * 4, EntityPosition.Y + 10); + var direction = MapManager.ObjLink.EntityPosition.Position - startPosition; + if (direction != Vector2.Zero) + direction.Normalize(); + + var radiants = MathF.Atan2(direction.Y, direction.X); + // randomly offset the direction a little bit + radiants += (Game1.RandomNumber.Next(0, 11) - 5) / 25f; + var aimDirection = new Vector2(MathF.Cos(radiants), MathF.Sin(radiants)); + + var eagleFeather = new BossEvilEagleFeather(Map, startPosition, aimDirection * 4); + Map.Objects.SpawnObject(eagleFeather); + + Game1.GameManager.PlaySoundEffect("D378-50-32"); + } + } + + private void UpdateDamaged() + { + if (!_damageState.IsInDamageState()) + _aiComponent.ChangeState("flyup"); + } + + private void FlyUp() + { + Game1.GameManager.PlaySoundEffect("D378-49-31"); + _animator.Play("cflap_" + _direction); + } + + private void InitFlyUp() + { + } + + private void UpdateFlyUp() + { + if (_body.Velocity.Y > -2) + _body.Velocity.Y -= 0.1f * Game1.TimeMultiplier; + + if (EntityPosition.Y < -48) + ToAttack(); + } + + private void ToAttack() + { + // reset the boss + if (MapManager.ObjLink.EntityPosition.Y > _startPosition.Y + 90) + { + _aiComponent.ChangeState("idle"); + return; + } + + _body.VelocityTarget = Vector2.Zero; + _damageComponent.IsActive = true; + + if (_damageState.CurrentLives == 4 || _damageState.CurrentLives == 5 || _featherAttack) + _aiComponent.ChangeState("attackEnter"); + else + _aiComponent.ChangeState("attack"); + } + + private void InitAttack() + { + _direction = Game1.RandomNumber.Next(0, 2) * 2 - 1; + + _body.Velocity = Vector3.Zero; + _body.VelocityTarget.X = _direction * FlySpeed; + + var randomHeight = Game1.RandomNumber.Next(0, 28) * 2; + + EntityPosition.Set(new Vector2(_startPosition.X - _direction * 160, (int)MapManager.ObjLink.EntityPosition.Y - randomHeight)); + + _animator.Play("cglide_" + _direction); + } + + private void UpdateAttack() + { + if (EntityPosition.X < _startPosition.X - 180 || _startPosition.X + 180 < EntityPosition.X) + _aiComponent.ChangeState("gone"); + } + + private void UpdateSaddled() + { + if (_body.Velocity.X > -3) + _body.Velocity.X -= 0.15f * Game1.TimeMultiplier; + if (_body.Velocity.Y > -2) + _body.Velocity.Y -= 0.01f * Game1.TimeMultiplier; + + if (EntityPosition.X < _startPosition.X - 23) + { + _animator.Play("cglide_-1"); + } + if (EntityPosition.X < _startPosition.X - 180) + { + // start attacking + ToAttack(); + } + } + + private void InitGrimSaddle() + { + _grimCreeper.StartSaddleJump(); + } + + private void UpdateGrimSaddle() + { + if (_grimCreeper.Map == null) + { + _aiComponent.ChangeState("saddled"); + _animator.Play("cflap"); + _animator.SpeedMultiplier = 0.5f; + } + } + + private void InitSpawning() + { + _playedIntro = true; + _body.VelocityTarget.X = -FlySpeed; + _spawnIndex = 0; + } + + private void UpdateSpawning() + { + MapManager.ObjLink.FreezePlayer(); + + if (_spawnIndex == 0) + { + if (EntityPosition.X < _startPosition.X - 180) + { + _animator.Play("glide_1"); + _body.VelocityTarget.X = FlySpeed; + EntityPosition.Y += 20; + _spawnIndex = 1; + } + } + else if (_spawnIndex == 1) + { + if (!_introSound && EntityPosition.X > _startPosition.X - 130) + { + _introSound = true; + Game1.GameManager.PlaySoundEffect("D378-34-22"); + } + + if (EntityPosition.X > _startPosition.X + 180) + { + _introSound = false; + _animator.Play("glide_-1"); + _body.VelocityTarget.X = -FlySpeed; + _spawnIndex = 2; + EntityPosition.Y += 20; + } + } + else if (_spawnIndex == 2) + { + if (!_introSound && EntityPosition.X < _startPosition.X + 110) + { + _introSound = true; + Game1.GameManager.PlaySoundEffect("D378-48-30"); + } + + if (EntityPosition.X < _startPosition.X + 40) + { + Game1.GameManager.PlaySoundEffect("D360-48-30"); + _animator.Play("flap"); + _slowStart = EntityPosition.Position; + _body.VelocityTarget.X = 0; + _spawnIndex = 3; + } + } + else if (_spawnIndex == 3) + { + _slowCounter += Game1.DeltaTime; + if (_slowCounter > 500) + { + _aiComponent.ChangeState("grimSaddle"); + _slowCounter = 500; + + _creeperFly0.ToLeave(); + _creeperFly1.ToLeave(); + } + + var percentage = MathF.Sin(_slowCounter / 500 * MathF.PI / 2); + var newPositionX = MathHelper.Lerp(_slowStart.X, _startPosition.X + 6, percentage); + EntityPosition.Set(new Vector2(newPositionX, EntityPosition.Y)); + } + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_damageState.IsInDamageState() || _aiComponent.CurrentStateId == "flyup") + return Values.HitCollision.None; + + if (damageType == HitType.MagicRod || damageType == HitType.Boomerang) + damage = 4; + + _damageComponent.IsActive = false; + _damageState.SetDamageState(true); + _damageState.CurrentLives -= damage; + + Game1.GameManager.PlaySoundEffect("D370-07-07"); + + // dead? + if (_damageState.CurrentLives <= 0) + { + _body.IsActive = false; + _hittableComponent.IsActive = false; + + Game1.GameManager.StartDialogPath("grim_creeper_4"); + + _damageState.OnDeathBoss(pieceOfPower); + + return Values.HitCollision.Enemy; + } + + // next move will be the wing attack; not sure how this works in the original + if (Game1.RandomNumber.Next(0, 2) == 0) + _featherAttack = true; + + _aiComponent.ChangeState("damaged"); + _body.VelocityTarget = Vector2.Zero; + + return Values.HitCollision.Enemy; + } + + private void OnDeath() + { + if (!string.IsNullOrEmpty(_saveKey)) + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + Game1.GameManager.PlaySoundEffect("D378-26-1A"); + + SpawnHeart(); + + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossEvilEagleFeather.cs b/InGame/GameObjects/Bosses/BossEvilEagleFeather.cs new file mode 100644 index 0000000..d455b66 --- /dev/null +++ b/InGame/GameObjects/Bosses/BossEvilEagleFeather.cs @@ -0,0 +1,98 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class BossEvilEagleFeather : GameObject + { + private readonly DamageFieldComponent _damageFieldComponent; + private readonly BodyComponent _body; + + private readonly CSprite _sprite; + private double _liveTime = 750; + private bool _reflected; + + public BossEvilEagleFeather(Map.Map map, Vector2 position, Vector2 velocity) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(position.X, position.Y, 0); + EntitySize = new Rectangle(-5, -5, 10, 10); + + _sprite = new CSprite("eagle feather", EntityPosition, Vector2.Zero); + _sprite.Center = new Vector2(12, 4); + + if (velocity.X > 0) + { + _sprite.Center = new Vector2(3, 4); + _sprite.SpriteEffect = SpriteEffects.FlipHorizontally; + } + + _body = new BodyComponent(EntityPosition, -3, -3, 6, 6, 8) + { + IgnoresZ = true, + IgnoreHoles = true, + CollisionTypes = Values.CollisionTypes.None + }; + + _body.VelocityTarget = velocity; + + var damageBox = new CBox(EntityPosition, -3, -3, 0, 6, 6, 8); + var pushBox = new CBox(EntityPosition, -4, -3, 0, 8, 6, 8); + var hittableBox = new CBox(EntityPosition, -6, -3, 0, 12, 6, 8); + + AddComponent(BodyComponent.Index, _body); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(DamageFieldComponent.Index, _damageFieldComponent = new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(PushableComponent.Index, new PushableComponent(pushBox, OnPush) { RepelMultiplier = 0.075f }); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerBottom)); + } + + private void Update() + { + _liveTime -= Game1.DeltaTime; + + if (_liveTime <= 75) + _sprite.Color = Color.White * ((float)_liveTime / 75f); + + if (_liveTime < 0) + Map.Objects.DeleteObjects.Add(this); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + Reflect(); + + return Values.HitCollision.Enemy; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + { + Reflect(); + return true; + } + + return false; + } + + private void Reflect() + { + if (_reflected) + return; + + Game1.GameManager.PlaySoundEffect("D360-22-16"); + + _reflected = true; + _damageFieldComponent.IsActive = false; + _body.VelocityTarget.Y = -_body.VelocityTarget.Y; + _sprite.SpriteEffect |= SpriteEffects.FlipVertically; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossFacade.cs b/InGame/GameObjects/Bosses/BossFacade.cs new file mode 100644 index 0000000..5c215e7 --- /dev/null +++ b/InGame/GameObjects/Bosses/BossFacade.cs @@ -0,0 +1,507 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Enemies; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + class BossFacade : GameObject + { + private ObjStone[] _objPots = new ObjStone[4]; + private float[] _potCounter = new float[4]; + private bool[] _potIsActive = new bool[4]; + + private Vector2[] _potPositions = { new Vector2(-4, -2), new Vector2(3, 3), new Vector2(-4, 3), new Vector2(3, -2) }; + private Vector2[] _tilePositions = + { + new Vector2(-4, -1), new Vector2(-4, 0), new Vector2(-4, 1), new Vector2(-4, 2), + new Vector2(3, -1), new Vector2(3, 0), new Vector2(3, 1), new Vector2(3, 2), + new Vector2(-3, -2), new Vector2(-2, -2), new Vector2(-1, -2), new Vector2(0, -2), new Vector2(1, -2), new Vector2(2, -2), + new Vector2(-3, 3), new Vector2(-2, 3), new Vector2(-1, 3), new Vector2(0, 3), new Vector2(1, 3), new Vector2(2, 3) + }; + + private int[] _tileOrder = + { + 12, 16, 18, 15, + 14, 19, 17, 13, + 0, 2, 4, 6, 8, 10, + 11, 9, 7, 5, 3, 1 + }; + + private readonly Animator _animatorEyes; + private Animator _animatorMouth; + private AiComponent _aiComponent; + private SpriteShader _drawEffect; + + private RectangleF _triggerField; + private readonly AiTriggerCountdown _blinkTigger; + + private readonly string _saveKey; + private readonly string _saveKeyHeart; + private readonly string _tileString; + + private int _blinkCount; + private int _currentLives = 5; + + private const int DespawnTime = 1150; + + private bool _hittable; + private bool _wasHit; + + private bool _spawnHoles; + private float _holeCounter = -3000; + + private float _deathCount = -1000; + + private bool _shakeScreen; + + public BossFacade() : base("facade") { } + + public BossFacade(Map.Map map, int posX, int posY, string saveKey, string saveKeyHeart) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 16, posY, 0); + EntitySize = new Rectangle(-24, -6, 48, 40); + + _saveKey = saveKey; + _saveKeyHeart = saveKeyHeart; + + _tileString = saveKey + "tiles"; + + _triggerField = Map.GetField(posX, posY, 16); + + SpawnTilesAndPots(); + + if (!string.IsNullOrWhiteSpace(saveKey) && Game1.GameManager.SaveManager.GetString(saveKey) == "1") + { + // respawn the heart if the player died after he killed the boss without collecting the heart + SpawnHeart(); + + IsDead = true; + return; + } + + _animatorEyes = AnimatorSaveLoad.LoadAnimator("Nightmares/facade"); + _animatorMouth = AnimatorSaveLoad.LoadAnimator("Nightmares/facade"); + + var hittableRectangle = new CBox(EntityPosition, -12, 4, 24, 24, 8); + var damageCollider = new CBox(EntityPosition, -12, -12, 24, 24, 8); + + var stateInit = new AiState(UpdateInit); + var statePre = new AiState(); + statePre.Trigger.Add(new AiTriggerCountdown(3500, null, () => _aiComponent.ChangeState("spawn"))); + var stateSpawn = new AiState { Init = InitSpawn }; + stateSpawn.Trigger.Add(new AiTriggerCountdown(1000, null, () => _aiComponent.ChangeState("preBlink"))); + var statePreBlink = new AiState { Init = InitPreBlink }; + statePreBlink.Trigger.Add(new AiTriggerCountdown(1800, null, () => _aiComponent.ChangeState("blink"))); + var stateBlink = new AiState(UpdateBlink) { Init = InitBlink }; + var statePostBlink = new AiState(UpdatePostBlink); + statePostBlink.Trigger.Add(new AiTriggerCountdown(1000, null, ToDialog)); + var stateDialog = new AiState(UpdateDialog); + var stateIdle = new AiState(UpdateIdle); + stateIdle.Trigger.Add(new AiTriggerRandomTime(BlinkAnimation, 1000, 2500)); + var stateDespawn = new AiState(); + stateDespawn.Trigger.Add(new AiTriggerCountdown(DespawnTime, DespawnTick, EndDespawn)); + var stateHidden = new AiState(); + stateHidden.Trigger.Add(new AiTriggerCountdown(2750, null, () => _aiComponent.ChangeState("respawn"))); + var stateRespawn = new AiState(UpdateRespawn) { Init = InitRespawn }; + var statePreDeath = new AiState(); + statePreDeath.Trigger.Add(new AiTriggerCountdown(1500, null, () => _aiComponent.ChangeState("death"))); + var stateDeath = new AiState(UpdateDeath); + stateDeath.Trigger.Add(new AiTriggerCountdown(3000 / AiDamageState.BlinkTime * AiDamageState.BlinkTime, UpdateBlink, DeathAnimationEnd)); + + _aiComponent = new AiComponent(); + _aiComponent.Trigger.Add(new AiTriggerUpdate(UpdateAnimations)); + _aiComponent.Trigger.Add(_blinkTigger = new AiTriggerCountdown(AiDamageState.BlinkTime * 4 * 2, BlinkTick, null)); + _aiComponent.Trigger.Add(new AiTriggerUpdate(Update)); + + _aiComponent.States.Add("init", stateInit); + _aiComponent.States.Add("preSpawn", statePre); + _aiComponent.States.Add("spawn", stateSpawn); + _aiComponent.States.Add("preBlink", statePreBlink); + _aiComponent.States.Add("blink", stateBlink); + _aiComponent.States.Add("postBlink", statePostBlink); + _aiComponent.States.Add("dialog", stateDialog); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("despawn", stateDespawn); + _aiComponent.States.Add("hidden", stateHidden); + _aiComponent.States.Add("respawn", stateRespawn); + _aiComponent.States.Add("preDeath", statePreDeath); + _aiComponent.States.Add("death", stateDeath); + + _aiComponent.ChangeState("init"); + + AddComponent(AiComponent.Index, _aiComponent); + //AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableRectangle, OnHit)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBottom, EntityPosition)); + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + + _potCounter[0] = -600; + _potCounter[1] = -300; + _potCounter[2] = -300; + _potCounter[3] = -300; + } + + private void OnKeyChange() + { + var tileState = Game1.GameManager.SaveManager.GetString(_tileString); + if (tileState == "17") + { + // get the first pot that is still on the floor + for (var i = 0; i < _objPots.Length; i++) + { + if (!_objPots[i].MakeFlyingStone()) + continue; + _potIsActive[i] = true; + + break; + } + } + + if (tileState == "20") + { + _spawnHoles = true; + } + } + + private void Update() + { + if (_shakeScreen) + Game1.GameManager.ShakeScreenContinue(50, 1, 0, 0.55f, 0); + + // update pot + for (var i = 0; i < _objPots.Length; i++) + { + if (!_potIsActive[i]) + continue; + + _potCounter[i] += Game1.DeltaTime; + + // move up + if (_potCounter[i] > 0) + _objPots[i].EntityPosition.Z += 0.25f * Game1.TimeMultiplier; + + if (_objPots[i].EntityPosition.Z > 12) + { + _objPots[i].EntityPosition.Z = 12; + + // start the throw? + if (_potCounter[i] > 1600) + { + _potIsActive[i] = false; + ThrowPot(_objPots[i]); + + // activate the next pot + for (var j = i + 1; j < _objPots.Length; j++) + { + if (!_objPots[j].MakeFlyingStone()) + continue; + _potIsActive[j] = true; + break; + } + } + } + } + + if (_spawnHoles) + { + _holeCounter -= Game1.DeltaTime; + if (_holeCounter < 0) + { + _holeCounter = Game1.RandomNumber.Next(1600, 3500); + + var posX = EntityPosition.X - 40 + Game1.RandomNumber.Next(0, 80); + var posY = EntityPosition.Y - 8 + Game1.RandomNumber.Next(0, 48); + var objHole = new BossFacadeHole(Map, new Vector2(posX, posY)); + Map.Objects.SpawnObject(objHole); + } + } + } + + private void ThrowPot(ObjStone objPot) + { + if (_currentLives <= 0) + { + objPot.LetGo(); + return; + } + + var playerDirection = MapManager.ObjLink.EntityPosition.Position - + new Vector2(objPot.EntityPosition.X, objPot.EntityPosition.Y - objPot.EntityPosition.Z + 2); + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + + objPot.ThrowStone(playerDirection * 2f); + } + + private void SpawnTilesAndPots() + { + for (var i = 0; i < _potPositions.Length; i++) + { + var parameter = MapData.GetParameter("pot", null); + parameter[1] = (int)(EntityPosition.X + _potPositions[i].X * Values.TileSize); + parameter[2] = (int)(EntityPosition.Y + _potPositions[i].Y * Values.TileSize); + + _objPots[i] = (ObjStone)ObjectManager.GetGameObject(Map, "pot", parameter); + Map.Objects.SpawnObject(_objPots[i]); + } + + Game1.GameManager.SaveManager.SetString(_tileString, "0"); + + for (var i = 0; i < _tilePositions.Length; i++) + { + var posX = (int)(EntityPosition.X + _tilePositions[i].X * Values.TileSize); + var posY = (int)(EntityPosition.Y + _tilePositions[i].Y * Values.TileSize); + // tile index starts at 1 so that they do not start automatically + var flyingTile = new EnemyFlyingTile(Map, posX, posY, _tileString, _tileOrder[i] + 1, 1); + Map.Objects.SpawnObject(flyingTile); + } + } + + private void UpdateDeath() + { + _deathCount += Game1.DeltaTime; + if (_deathCount < 100) + return; + + _deathCount -= 100; + + Game1.GameManager.PlaySoundEffect("D378-19-13"); + + var posX = (int)EntityPosition.X + Game1.RandomNumber.Next(0, 32) - 8 - 16; + var posY = (int)EntityPosition.Y - (int)EntityPosition.Z + Game1.RandomNumber.Next(0, 32) - 8; + + // spawn explosion effect + Map.Objects.SpawnObject(new ObjAnimator(Map, posX, posY, Values.LayerTop, "Particles/spawn", "run", true)); + } + + private void UpdateBlink(double time) + { + var blinkTime = AiDamageState.BlinkTime; + _drawEffect = time % (blinkTime * 2) < blinkTime ? Resources.DamageSpriteShader0 : null; + } + + private void UpdateInit() + { + if (_triggerField.Contains(MapManager.ObjLink.BodyRectangle)) + { + Game1.GameManager.SetMusic(24, 2); + _aiComponent.ChangeState("preSpawn"); + } + } + + private void BlinkTick(double time) + { + var blinkTime = AiDamageState.BlinkTime; + _drawEffect = time % (blinkTime * 2) >= blinkTime ? Resources.DamageSpriteShader0 : null; + } + + private void DespawnTick(double counter) + { + _animatorEyes.Play(counter > (DespawnTime * (16 / 70f)) ? "eye_half" : "eye_closed"); + _animatorMouth.Play(counter > (DespawnTime * (32 / 70f)) ? "mouth_opened" : "mouth_closed"); + } + + private void EndDespawn() + { + _aiComponent.ChangeState("hidden"); + } + + private void InitSpawn() + { + _hittable = true; + _animatorEyes.Play("eye_closed"); + _animatorMouth.Play("mouth_closed"); + } + + private void InitPreBlink() + { + _animatorEyes.Play("eye_half"); + } + + private void InitBlink() + { + _blinkCount = 0; + _animatorEyes.Play("eye_blink"); + } + + private void UpdateBlink() + { + // blink 2 times and change to eyes opened state + if (!_animatorEyes.IsPlaying) + { + _blinkCount++; + if (_blinkCount >= 2) + { + _animatorEyes.Play("eye_half"); + _animatorMouth.Play("mouth_opened"); + _aiComponent.ChangeState("postBlink"); + return; + } + + _animatorEyes.Play("eye_blink"); + } + } + + private void UpdatePostBlink() + { + if (!_animatorEyes.IsPlaying) + { + _animatorEyes.Play("eye"); + } + } + + private void ToDialog() + { + _aiComponent.ChangeState("dialog"); + Game1.GameManager.StartDialogPath("facade_opening"); + } + + private void UpdateDialog() + { + // finished the dialog + if (!Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen) + { + // start the tile action + Game1.GameManager.SaveManager.SetString(_tileString, "1"); + + _shakeScreen = true; + + _aiComponent.ChangeState("idle"); + } + } + + private void UpdateAnimations() + { + _animatorEyes.Update(); + _animatorMouth.Update(); + } + + private void BlinkAnimation() + { + _animatorEyes.Play("eye_blink_full"); + } + + private void UpdateIdle() + { + if (!_animatorEyes.IsPlaying) + { + _animatorEyes.Play("eye"); + } + + // was hit => despawn + if (_wasHit) + { + _wasHit = false; + ToDespawn(); + } + } + + private void ToDespawn() + { + _hittable = false; + _aiComponent.ChangeState("despawn"); + } + + private void InitRespawn() + { + _animatorEyes.Play("eye_respawn"); + _animatorMouth.Play("mouth_respawn"); + } + + private void UpdateRespawn() + { + if (!_animatorEyes.IsPlaying) + { + _hittable = true; + _aiComponent.ChangeState("idle"); + } + } + + private bool IsVisible() + { + return _aiComponent.CurrentStateId != "init" && + _aiComponent.CurrentStateId != "preSpawn" && + _aiComponent.CurrentStateId != "hidden"; + } + + private void Draw(SpriteBatch spriteBatch) + { + if (!IsVisible()) + return; + + if (_drawEffect != null) + { + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, _drawEffect); + } + + // draw the eye and the mouth + _animatorEyes.Draw(spriteBatch, new Vector2(EntityPosition.X, EntityPosition.Y), Color.White); + _animatorMouth.Draw(spriteBatch, new Vector2(EntityPosition.X, EntityPosition.Y + 23), Color.White); + + if (_drawEffect != null) + { + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, null); + } + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_blinkTigger.IsRunning() || !_hittable || !IsVisible() || (damageType & HitType.Bomb) == 0) + return Values.HitCollision.None; + + _wasHit = true; + + _currentLives--; + + if (_currentLives <= 0) + { + _spawnHoles = false; + + // stop the flying tiles from activating + Game1.GameManager.SaveManager.SetString(_tileString, "-1"); + + _hittable = false; + _shakeScreen = false; + + _aiComponent.ChangeState("preDeath"); + Game1.GameManager.StartDialogPath("facade_death"); + } + + _blinkTigger.OnInit(); + + return Values.HitCollision.None; + } + + + private void DeathAnimationEnd() + { + if (!string.IsNullOrEmpty(_saveKey)) + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + Game1.GameManager.PlaySoundEffect("D378-26-1A"); + + SpawnHeart(); + + Map.Objects.DeleteObjects.Add(this); + } + + private void SpawnHeart() + { + // spawn big heart + Map.Objects.SpawnObject(new ObjItem(Map, (int)EntityPosition.X - 8, (int)EntityPosition.Y + 8, "j", _saveKeyHeart, "heartMeterFull", null)); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossFacadeHole.cs b/InGame/GameObjects/Bosses/BossFacadeHole.cs new file mode 100644 index 0000000..b6aecc0 --- /dev/null +++ b/InGame/GameObjects/Bosses/BossFacadeHole.cs @@ -0,0 +1,57 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + internal class BossFacadeHole : GameObject + { + private readonly Animator _animator; + private readonly BoxCollisionComponent _collisionComponent; + + private bool _playedSoundEffect; + + public BossFacadeHole(Map.Map map, Vector2 position) : base(map) + { + Tags = Values.GameObjectTag.Hole; + + EntityPosition = new CPosition(position.X, position.Y - 8, 0); + EntitySize = new Rectangle(-8, 0, 16, 16); + + var sprite = new CSprite(EntityPosition); + + _animator = AnimatorSaveLoad.LoadAnimator("Nightmares/facade hole"); + _animator.Play("idle"); + + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(0, 8)); + + _collisionComponent = new BoxCollisionComponent(new CBox(EntityPosition, -7, -7 + 8, 0, 14, 14, 16), Values.CollisionTypes.Hole); + AddComponent(CollisionComponent.Index, _collisionComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerBottom)); + } + + private void Update() + { + if (!_playedSoundEffect && _animator.CurrentFrameIndex == 1) + { + _playedSoundEffect = true; + Game1.GameManager.PlaySoundEffect("D360-64-40"); + } + + // hole is only active while at the x frame + if (_animator.CurrentFrameIndex == 2 || _animator.CurrentFrameIndex == 3) + _collisionComponent.IsActive = true; + else + _collisionComponent.IsActive = false; + + // finished animation => delete the object + if(!_animator.IsPlaying) + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossFinalBoss.cs b/InGame/GameObjects/Bosses/BossFinalBoss.cs new file mode 100644 index 0000000..e3cd487 --- /dev/null +++ b/InGame/GameObjects/Bosses/BossFinalBoss.cs @@ -0,0 +1,1809 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + class BossFinalBoss : GameObject + { + public readonly CSprite Sprite; + + private readonly BodyDrawShadowComponent _bodyShadow; + private readonly DamageFieldComponent _damageField; + private readonly HittableComponent _hittableComponent; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + + private readonly Animator _animator; + private readonly Animator _animatorBody; + private readonly Animator _animatorWeapon; + private readonly Animator _animatorEye; + + private readonly DrawComponent _drawComponent; + private readonly AiDamageState _aiDamageState; + + private readonly CBox _hittableBoxMan; + + private CBox _hittableBox; + + private DictAtlasEntry _spriteBody; + + private BossFinalBossFireball _objFireball; + + private Rectangle _roomRectangle; + + private Vector2 _bodyPosition; + private Vector2 _bodyStartPosition; + private Vector2 _bodyTargetPosition; + + private Vector2 _manTargetPosition; + private Vector2[] _fireballOffset = new Vector2[] { new Vector2(-15, -8), new Vector2(0, -24), new Vector2(15, -8), new Vector2(0, -4) }; + + private Vector2[] _bodyParts = new Vector2[6]; + + private string _saveKey; + + // state slime + private const int SlimeDamageTime = 2200; + private const int RotateTime = 2500; + private int _slimeLives = 3; + private bool _slimeForm; + + // state man + private bool _manInit = true; + private int _manLives = 4; + + // state ganon + private int _ganonLives = 12; + + private Vector2 _ganonTargetPosition; + + private const int _ganonDeathTime = 2200; + private bool _ganonForm; + + private float _batCounter; + private int _batIndex; + private int _batIndexStart; + + // state moldorm + private int _moldormLives = 16; + + private const int TailMult = 8; + private BossFinalBossTail[] _moldormTails = new BossFinalBossTail[4]; + private AiTriggerSwitch _moldormSpeedUp; + private Vector2[] _moldormPositions = new Vector2[6 * TailMult]; + private Vector2[] _moldormPositionsNew = new Vector2[6 * TailMult]; + private float[] _partDist = new float[4]; + private float _moldormRadiant; + private float _moldormChangeCounter; + private float _moldormSpeed; + private float _directionChangeMultiplier; + private int _moldormDirection = 1; + private bool _moldormHit; + + private const float MoldormSpeedNormal = 1.0f; + private const float MoldormSpeedFast = 1.75f; + + private int _direction; + private int _sideIndex; + + private int _moveDist = 40; + private float _moveSpeed = 0.25f; + private float _moldormSoundCounter; + + private int _moveCounter; + + // state face + private float _faceParticleCounter; + + // state final + // objects used to deal damage + private readonly BossFinalBossFinalTail[] _finalParts = new BossFinalBossFinalTail[8]; + private readonly string[] _spriteFinalParts = new string[] { "final_part0", "final_part1", "final_part1", "final_part2" }; + private float[] _finalPartDistance = new float[] { 18, 10, 10, 10 }; + + private Vector2 _targetPosition; + + private float _finalPartCounter; + private float _finalPart0 = -MathF.PI / 2; + private float _finalPart1 = -MathF.PI / 2; + private float _finalPartSpeed0 = 1 / 2500.0f * MathF.PI * 2; + private float _finalPartSpeed1 = 1 / 2500.0f * MathF.PI * 2; + + private int _finalStateLives = 16; + private int _finalStateDeathCounter = 2500; + + private float _finalEyeCounter; + private int _finalEyeState; + private bool _finalState; + + private bool _hideBody; + private bool _hideHead; + private bool _drawGanonWeapon; + private bool _drawMoldormTail; + + private bool _pushRepel; + + public BossFinalBoss() : base("nightmare_head") { } + + public BossFinalBoss(Map.Map map, int posX, int posY, string saveKey) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 8, 0); + EntityPosition.AddPositionListener(typeof(BossFinalBoss), OnUpdatePosition); + EntitySize = new Rectangle(-16, -24, 32, 40); + + _saveKey = saveKey; + if (!string.IsNullOrEmpty(_saveKey) && + Game1.GameManager.SaveManager.GetString(_saveKey) == "1") + { + IsDead = true; + return; + } + + _bodyStartPosition = EntityPosition.Position; + _bodyTargetPosition = _bodyStartPosition - new Vector2(0, _moveDist); + + _animator = AnimatorSaveLoad.LoadAnimator("nightmares/nightmare"); + _animator.Play("head"); + + _animatorBody = AnimatorSaveLoad.LoadAnimator("nightmares/nightmare"); + _animatorBody.Play("idle"); + + _animatorWeapon = AnimatorSaveLoad.LoadAnimator("nightmares/nightmare ganon weapon"); + _animatorEye = AnimatorSaveLoad.LoadAnimator("nightmares/nightmare final"); + + _spriteBody = Resources.GetSprite("nightmare_body"); + + _bodyPosition = EntityPosition.Position; + + Sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, Sprite, Vector2.Zero); + + for (var i = 0; i < _finalParts.Length; i++) + { + _finalParts[i] = new BossFinalBossFinalTail(map, this, _spriteFinalParts[i % 4], EntityPosition.Position); + map.Objects.SpawnObject(_finalParts[i]); + } + + _roomRectangle = map.GetField(posX, posY); + + _body = new BodyComponent(EntityPosition, -7, -7, 14, 14, 8) + { + MoveCollision = OnCollision, + AbsorbPercentage = 1f, + Gravity = -0.085f, + DragAir = 1.0f, + Drag = 0.8f, + FieldRectangle = map.GetField(posX, posY), + CollisionTypes = Values.CollisionTypes.Normal + }; + + _aiComponent = new AiComponent(); + + // floor + var stateIdle = new AiState(UpdateIdle) { Init = InitIdle }; + var stateMoveBody = new AiState(UpdateMoveBody) { Init = InitMoveBody }; + var stateMoveHead = new AiState(UpdateMoveHead); + var stateWobble = new AiState(UpdateWobble) { Init = InitWobble }; + var stateDespawn = new AiState(UpdateDespawn) { Init = InitStartDespawn }; + + // slime + var stateSlimeSpawn = new AiState(UpdateSlimeSpawn) { Init = InitSlimeSpawn }; + var stateSlimeJump = new AiState(UpdateSlimeJump) { Init = InitSlimeJump }; + var stateSlimeWait = new AiState() { Init = InitSlimeWait }; + stateSlimeWait.Trigger.Add(new AiTriggerCountdown(800, null, () => _aiComponent.ChangeState("slimeJump"))); + var stateSlimeDespawn = new AiState(UpdateSlimeDespawn) { Init = InitSlimeDespawn }; + var stateSlimeHidden = new AiState() { Init = InitSlimeHidden }; + stateSlimeHidden.Trigger.Add(new AiTriggerCountdown(2200, null, EndSlimeHidden)); + var stateSlimeDamaged = new AiState() { Init = InitSlimeDamaged }; + stateSlimeDamaged.Trigger.Add(new AiTriggerCountdown(SlimeDamageTime, TickSlimeDamaged, EndSlimeDamge)); + var stateSlimeHideExplode = new AiState() { Init = InitSlimeHideExplode }; + stateSlimeHideExplode.Trigger.Add(new AiTriggerCountdown(2200, null, EndSlimeHidden)); + var stateSlimeExplode = new AiState() { Init = InitSlimeExplode }; + stateSlimeExplode.Trigger.Add(new AiTriggerCountdown(2800, null, SlimeEnd)); + + // man + var stateManPreAttack = new AiState(UpdateManPreAttack); + stateManPreAttack.Trigger.Add(new AiTriggerCountdown(1100, null, () => _aiComponent.ChangeState("manAttack"))); + var stateManAttack = new AiState(UpdateManAttack) { Init = InitManAttack }; + var stateManPostAttack = new AiState(UpdateManPostAttack) { Init = InitPostAttack }; + stateManPostAttack.Trigger.Add(new AiTriggerCountdown(1300, null, () => _aiComponent.ChangeState("manDespawn"))); + var stateManDespawn = new AiState(UpdateManDespawn) { Init = InitManDespawn }; + var stateManMove = new AiState(UpdateManMove) { Init = InitManMove }; + var stateManMoveWait = new AiState(); + stateManMoveWait.Trigger.Add(new AiTriggerCountdown(650, null, () => _aiComponent.ChangeState("manSpawn"))); + var stateManSpawn = new AiState(UpdateManSpawn) { Init = InitManSpawn }; + var stateManRotate = new AiState() { Init = InitManRotate }; + stateManRotate.Trigger.Add(new AiTriggerCountdown(RotateTime, TickRotate, EndRotate)); + + // explode + var stateExplode = new AiState() { Init = InitExplode }; + stateExplode.Trigger.Add(new AiTriggerCountdown(950, null, () => _aiComponent.ChangeState("explodeDespawn"))); + var stateExplodeDespawn = new AiState(UpdateDepawn) { Init = InitDespawn }; + var stateMove = new AiState(UpdateMove) { Init = InitMove }; + var stateMoveWait = new AiState(); + stateMoveWait.Trigger.Add(new AiTriggerCountdown(650, null, EndMoveWait)); + + // moldorm + var stateMoldormSpawn = new AiState(UpdateMoldormSpawn) { Init = InitMoldormSpawn }; + var stateMoldorm = new AiState(UpdateMoldorm) { Init = InitMoldorm }; + stateMoldorm.Trigger.Add(_moldormSpeedUp = new AiTriggerSwitch(3000)); + var stateMoldormDying = new AiState(UpdateMoldormDying) { Init = InitMoldormDying }; + stateMoldormDying.Trigger.Add(new AiTriggerCountdown(1250, null, MoldormExplode)); + var stateMoldormDespawn = new AiState(UpdateMoldormDespawn); + + // ganon + var stateGanonSpawn = new AiState(UpdateGanonSpawn) { Init = InitGanonSpawn }; + var stateGanonPreSpawnWeapon = new AiState(UpdateGanonPreSpawnWeapon); + stateGanonPreSpawnWeapon.Trigger.Add(new AiTriggerCountdown(850, null, () => _aiComponent.ChangeState("ganonSpawnWeapon"))); + var stateGanonSpawnWeapon = new AiState(UpdateGanonSpawnWeapon) { Init = InitGanonSpawnWeapon }; + var stateGanon = new AiState(UpdateGanon) { Init = InitGanon }; + stateGanon.Trigger.Add(new AiTriggerCountdown(1000, null, () => _aiComponent.ChangeState("ganonBats"))); + var stateGanonBats = new AiState(UpdateGanonBats) { Init = InitGanonBats }; + var stateGanonThrow = new AiState(UpdateGanonThrow) { Init = InitGanonThrow }; + stateGanonThrow.Trigger.Add(new AiTriggerCountdown(800, null, ThrowWeapon)); + var stateGanonPostThrow = new AiState() { Init = InitGanonPostThrow }; + stateGanonPostThrow.Trigger.Add(new AiTriggerCountdown(1100, null, () => _aiComponent.ChangeState("ganonMove"))); + var stateGanonMove = new AiState(UpdateGanonMove) { Init = InitGanonMove }; + var stateGanonCatchWeapon = new AiState(UpdateGanonCatchWeapon) { Init = InitGanonCatchWeapon }; + var stateGanonWait = new AiState(UpdateGanonWait); + stateGanonWait.Trigger.Add(new AiTriggerCountdown(1000, null, () => _aiComponent.ChangeState("ganonBats"))); + var stateGanonDeath = new AiState() { Init = InitGanonDeath }; + stateGanonDeath.Trigger.Add(new AiTriggerCountdown(_ganonDeathTime, TickGanonDamage, () => _aiComponent.ChangeState("ganonExplode"))); + var stateGanonExplode = new AiState() { Init = InitGanonExplode }; + stateGanonExplode.Trigger.Add(new AiTriggerCountdown(_ganonDeathTime, null, () => _aiComponent.ChangeState("face"))); + + // face + var stateFace = new AiState(UpdateFace) { Init = InitFace }; + var stateFaceExplode = new AiState() { Init = InitFaceExplose }; + stateFaceExplode.Trigger.Add(new AiTriggerCountdown(2200, null, () => _aiComponent.ChangeState("faceMove"))); + var stateFaceMove = new AiState(UpdateFaceMove) { Init = InitFaceMove }; + var stateFaceHidden = new AiState() { Init = InitFaceHidden }; + stateFaceHidden.Trigger.Add(new AiTriggerCountdown(1000, null, () => _aiComponent.ChangeState("faceDespawn"))); + var stateFaceDespawn = new AiState(UpdateFaceDespawn) { Init = InitFaceDespawn }; + + // final + var stateFinalSpawn = new AiState(UpdateFianalSpawn) { Init = InitFinalSpawn }; + var stateFinal = new AiState(UpdateFinal) { Init = InitFinal }; + var stateFinalBlink = new AiState() { Init = InitFinalBlink }; + stateFinalBlink.Trigger.Add(new AiTriggerCountdown(_finalStateDeathCounter, TickFinalDespawn, () => _aiComponent.ChangeState("finalDeath"))); + var stateFinalDeath = new AiState(UpdateFinalDeath) { Init = InitFinalDeath }; + + var stateTest = new AiState(); + stateTest.Trigger.Add(new AiTriggerCountdown(1500, null, TestProjectileSpawn) { ResetAfterEnd = true }); + + // spawning + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("moveBody", stateMoveBody); + _aiComponent.States.Add("moveHead", stateMoveHead); + _aiComponent.States.Add("wobble", stateWobble); + _aiComponent.States.Add("despawn", stateDespawn); + + // slime + _aiComponent.States.Add("slimeSpawn", stateSlimeSpawn); + _aiComponent.States.Add("slimeJump", stateSlimeJump); + _aiComponent.States.Add("slimeWait", stateSlimeWait); + _aiComponent.States.Add("slimeDespawn", stateSlimeDespawn); + _aiComponent.States.Add("slimeHidden", stateSlimeHidden); + _aiComponent.States.Add("slimeDamaged", stateSlimeDamaged); + _aiComponent.States.Add("slimeHideExplode", stateSlimeHideExplode); + _aiComponent.States.Add("slimeExplode", stateSlimeExplode); + + // man + _aiComponent.States.Add("manPreAttack", stateManPreAttack); + _aiComponent.States.Add("manAttack", stateManAttack); + _aiComponent.States.Add("manPostAttack", stateManPostAttack); + _aiComponent.States.Add("manDespawn", stateManDespawn); + _aiComponent.States.Add("manMove", stateManMove); + _aiComponent.States.Add("manMoveWait", stateManMoveWait); + _aiComponent.States.Add("manSpawn", stateManSpawn); + _aiComponent.States.Add("manRotate", stateManRotate); + + // moldorm + _aiComponent.States.Add("moldormSpawn", stateMoldormSpawn); + _aiComponent.States.Add("moldorm", stateMoldorm); + _aiComponent.States.Add("moldormDying", stateMoldormDying); + _aiComponent.States.Add("moldormDespawn", stateMoldormDespawn); + + // ganon + _aiComponent.States.Add("ganonSpawn", stateGanonSpawn); + _aiComponent.States.Add("ganonPreSpawnWeapon", stateGanonPreSpawnWeapon); + _aiComponent.States.Add("ganonSpawnWeapon", stateGanonSpawnWeapon); + _aiComponent.States.Add("ganon", stateGanon); + _aiComponent.States.Add("ganonBats", stateGanonBats); + _aiComponent.States.Add("ganonThrow", stateGanonThrow); + _aiComponent.States.Add("ganonPostThrow", stateGanonPostThrow); + _aiComponent.States.Add("ganonMove", stateGanonMove); + _aiComponent.States.Add("ganonCatchWeapon", stateGanonCatchWeapon); + _aiComponent.States.Add("ganonWait", stateGanonWait); + _aiComponent.States.Add("ganonDeath", stateGanonDeath); + _aiComponent.States.Add("ganonExplode", stateGanonExplode); + + // face + _aiComponent.States.Add("face", stateFace); + _aiComponent.States.Add("faceExplode", stateFaceExplode); + _aiComponent.States.Add("faceMove", stateFaceMove); + _aiComponent.States.Add("faceHidden", stateFaceHidden); + _aiComponent.States.Add("faceDespawn", stateFaceDespawn); + + // final + _aiComponent.States.Add("finalSpawn", stateFinalSpawn); + _aiComponent.States.Add("final", stateFinal); + _aiComponent.States.Add("finalBlink", stateFinalBlink); + _aiComponent.States.Add("finalDeath", stateFinalDeath); + + _aiComponent.States.Add("explode", stateExplode); + _aiComponent.States.Add("explodeDespawn", stateExplodeDespawn); + _aiComponent.States.Add("move", stateMove); + _aiComponent.States.Add("moveWait", stateMoveWait); + + _aiDamageState = new AiDamageState(this, _body, _aiComponent, Sprite, 8, false); + _aiDamageState.OnDeath = OnZeroLives; + _aiDamageState.BossHitSound = true; + + var damageCollider = new CBox(EntityPosition, -6, -6, 0, 12, 12, 8); + _hittableBox = new CBox(EntityPosition, -7, -7, 0, 14, 14, 8); + _hittableBoxMan = new CBox(EntityPosition, -6, -12, 0, 12, 18, 8); + + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(HittableComponent.Index, _hittableComponent = new HittableComponent(_hittableBox, OnHit)); + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageCollider, HitType.Enemy, 2) { IsActive = false }); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, _drawComponent = new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + AddComponent(DrawShadowComponent.Index, _bodyShadow = new BodyDrawShadowComponent(_body, Sprite) { ShadowWidth = 14, ShadowHeight = 5 }); + + _aiComponent.ChangeState("idle"); + + //DebugMan(); + } + + #region Debug + + private void DebugSlimeEnd() + { + _slimeLives = 1; + _aiComponent.ChangeState("slimeHidden"); + } + + private void DebugMan() + { + _manLives = 2; + _aiComponent.ChangeState("slimeExplode"); + } + + private void DebugMoldrom() + { + _moveCounter = 1; + _moldormLives = 1; + _aiComponent.ChangeState("moldormSpawn"); + } + + private void DebugGanon() + { + _ganonLives = 1; + _aiComponent.ChangeState("ganonSpawn"); + } + + private void DebugFace() + { + _finalStateLives = 4; + _aiComponent.ChangeState("face"); + } + + #endregion + + #region state final + + private void InitFinalDeath() + { + Sprite.SpriteShader = null; + + Game1.GameManager.PlaySoundEffect("D370-16-10"); + Game1.GameManager.PlaySoundEffect("D378-60-3D"); + } + + private void UpdateFinalDeath() + { + // spawn the parts + _finalPartCounter -= Game1.DeltaTime; + + // despawn? + if (_finalPartCounter < -300) + FinalExplose(); + + for (var i = 0; i < 4; i++) + { + if (i * 300 >= _finalPartCounter) + { + _finalParts[i].SetActive(false); + _finalParts[i + 4].SetActive(false); + } + } + } + + private void FinalExplose() + { + if (!string.IsNullOrEmpty(_saveKey)) + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + Map.Objects.DeleteObjects.Add(this); + + ExplodeAnimation(); + } + + private void InitFinalBlink() + { + Game1.GameManager.SetMusic(93, 2); + + Game1.GameManager.StopSoundEffect("D360-61-3D"); + Game1.GameManager.PlaySoundEffect("D370-16-10"); + + // hack to not allow anymore attacks + _body.VelocityTarget = Vector2.Zero; + Game1.GameManager.StartDialog("nightmareFinal0"); + + // deactivate the damge fields + _damageField.IsActive = false; + for (var i = 0; i < 8; i++) + _finalParts[i].DeactivateDamageField(); + } + + private void TickFinalDespawn(double counter) + { + var time = _finalStateDeathCounter - counter; + Sprite.SpriteShader = time % (AiDamageState.BlinkTime * 2) < AiDamageState.BlinkTime ? Resources.DamageSpriteShader0 : null; + } + + private void InitFinalSpawn() + { + Game1.GameManager.PlaySoundEffect("D370-35-23"); + Game1.GameManager.SetMusic(79, 2); + + _targetPosition = EntityPosition.Position; + _animator.Play("final_spawn"); + _damageField.IsActive = true; + _damageField.CollisionBox = new CBox(EntityPosition, -8, -12, 16, 16, 8); + _hittableComponent.HittableBox = new CBox(EntityPosition, -6, -8, 12, 14, 8); + } + + private void UpdateFianalSpawn() + { + if (!_animator.IsPlaying) + _aiComponent.ChangeState("final"); + } + + private Vector2 RandomRoomPositionFinal() + { + var posY = 0; + // make it more likeley to move around at the top + if (Game1.RandomNumber.Next(1, 10) <= 6) + posY = Game1.RandomNumber.Next(8, 6 * 8); + else if (Game1.RandomNumber.Next(1, 10) <= 6) + posY = Game1.RandomNumber.Next(8, 9 * 8); + + int posX; + if (16 < posY || posY < 64 - 16) + posX = Game1.RandomNumber.Next(16, 6 * 16); + else + posX = Game1.RandomNumber.Next(0, 8 * 16); + + return new Vector2(_roomRectangle.X + 24 + posX, _roomRectangle.Y + 24 + posY); + } + + private void InitFinal() + { + _finalState = true; + _animator.Play("final"); + } + + private void UpdateFinal() + { + _animatorEye.Update(); + + Game1.GameManager.PlaySoundEffect("D360-61-3D", false); + + // move to the target position + var distance = _targetPosition - EntityPosition.Position; + if (distance.Length() > 4) + { + distance.Normalize(); + _body.VelocityTarget = AnimationHelper.MoveToTarget(_body.VelocityTarget, distance * 0.5f, 0.0125f * Game1.TimeMultiplier); + } + else + { + // generate new target position + _targetPosition = RandomRoomPositionFinal(); + } + + if (!_animatorEye.IsPlaying) + _finalEyeCounter -= Game1.DeltaTime; + + if (_finalEyeCounter <= 0) + { + // open the eye + if (_finalEyeState == 0) + { + _finalEyeState = 1; + _finalEyeCounter += 1250 + Game1.RandomNumber.Next(750); + _animatorEye.Play("eye_open"); + } + // close the eye + else if (_finalEyeState == 1) + { + _finalEyeState = 0; + _finalEyeCounter += 2500 + Game1.RandomNumber.Next(2500); + _animatorEye.Play("eye_close"); + } + } + + // spawn the parts + if (_finalPartCounter < 4 * 300) + _finalPartCounter += Game1.DeltaTime; + + if (_finalPartCounter > 300) + { + _finalPart0 += Game1.DeltaTime * _finalPartSpeed0; + _finalPart1 += Game1.DeltaTime * _finalPartSpeed1; + + var directionPart0 = new Vector2(MathF.Cos(_finalPart0), MathF.Sin(_finalPart0)); + SetFinalPartsPosition(directionPart0, 0); + var directionPart1 = new Vector2(-MathF.Cos(_finalPart1), MathF.Sin(_finalPart1)); + SetFinalPartsPosition(directionPart1, 1); + } + } + + private void SetFinalPartsPosition(Vector2 direction, int index) + { + var position = new Vector2(EntityPosition.X, EntityPosition.Y - 5); + + for (var i = 0; i < 4; i++) + { + if ((i + 1) * 300 > _finalPartCounter) + break; + + _finalParts[i + index * 4].SetActive(true); + + position += direction * _finalPartDistance[i]; + _finalParts[i + index * 4].EntityPosition.Set(position); + } + } + + #endregion + + #region state face + + private void InitFaceDespawn() + { + _damageField.IsActive = false; + _animator.Play("slime_despawn"); + } + + private void UpdateFaceDespawn() + { + // TODO: delay + if (!_animator.IsPlaying) + _aiComponent.ChangeState("finalSpawn"); + } + + private void InitFaceHidden() + { + _animator.Play("face_hidden"); + } + + private void InitFaceExplose() + { + Game1.GameManager.SetMusic(-1, 2); + Game1.GameManager.PlaySoundEffect("D370-16-10"); + _body.VelocityTarget = Vector2.Zero; + ExplodeAnimation(); + } + + private void InitFaceMove() + { + Game1.GameManager.PlaySoundEffect("D360-53-35"); + } + + private void UpdateFaceMove() + { + var targetPosition = new Vector2(_body.FieldRectangle.X + 80, _body.FieldRectangle.Y + 40); + var direction = targetPosition - EntityPosition.Position; + var moveSpeed = 1.25f; + + if (direction.Length() > moveSpeed * Game1.TimeMultiplier) + { + direction.Normalize(); + _body.VelocityTarget = AnimationHelper.MoveToTarget(_body.VelocityTarget, direction * moveSpeed, 0.075f * Game1.TimeMultiplier); + } + else + { + _body.VelocityTarget = Vector2.Zero; + _aiComponent.ChangeState("faceHidden"); + } + } + + private void InitFace() + { + _damageField.IsActive = true; + _damageField.CollisionBox = new CBox(EntityPosition, -6, -6, 0, 12, 12, 8); + _hittableComponent.HittableBox = new CBox(EntityPosition, -6, -6, 0, 12, 12, 8); + _drawComponent.Layer = Values.LayerPlayer; + } + + private void UpdateFace() + { + // spawn paticles + _faceParticleCounter -= Game1.DeltaTime; + if (_faceParticleCounter < 0) + { + _faceParticleCounter += 125; + var objParticle = new ObjAnimator(Map, (int)EntityPosition.X, (int)EntityPosition.Y, Values.LayerBottom, "Nightmares/nightmare particle", "face_particle", true); + Map.Objects.SpawnObject(objParticle); + } + + // move towards the player + var playerDirection = MapManager.ObjLink.EntityPosition.Position - new Vector2(EntityPosition.Position.X, EntityPosition.Position.Y + 4); + if (playerDirection != Vector2.Zero) + { + playerDirection.Normalize(); + _body.VelocityTarget = AnimationHelper.MoveToTarget(_body.VelocityTarget, playerDirection * 1.5f, Game1.TimeMultiplier * 0.035f); + } + } + + #endregion + + #region state ganon + + public void CatchWeapon() + { + _body.VelocityTarget = Vector2.Zero; + + Game1.GameManager.PlaySoundEffect("D378-25-19"); + + if (_ganonLives > 0) + _aiComponent.ChangeState("ganonCatchWeapon"); + } + + private void InitGanonDeath() + { + _ganonForm = false; + _animator.Pause(); + _animatorWeapon.Pause(); + + Game1.GameManager.PlaySoundEffect("D370-16-10"); + } + + private void InitGanonExplode() + { + _drawGanonWeapon = false; + EntityPosition.Set(new Vector2(EntityPosition.X, EntityPosition.Y - 4)); + + Game1.GameManager.PlaySoundEffect("D378-55-37"); + ExplodeAnimation(); + } + + private void TickGanonDamage(double counter) + { + var time = _ganonDeathTime - counter; + Sprite.SpriteShader = time % (AiDamageState.BlinkTime * 2) < AiDamageState.BlinkTime ? Resources.DamageSpriteShader0 : null; + } + + private void UpdateGanonWait() + { + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + var dir = playerDirection.X < 0 ? -1 : 1; + + _animator.Play("ganon_" + dir); + _animatorWeapon.Play("ganon_" + dir); + } + + private void InitGanonCatchWeapon() + { + _drawGanonWeapon = true; + + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + var dir = playerDirection.X < 0 ? -1 : 1; + + _animator.Play("ganon_weapon_spawn_" + dir); + _animatorWeapon.Play("ganon_weapon_spawn_" + dir); + } + + private void UpdateGanonCatchWeapon() + { + if (!_animatorWeapon.IsPlaying) + _aiComponent.ChangeState("ganonWait"); + } + + private void InitGanonMove() + { + _ganonTargetPosition = RandomRoomPosition(); + } + + private void UpdateGanonMove() + { + var moveDirection = _ganonTargetPosition - EntityPosition.Position; + if (moveDirection.Length() > 8) + { + if (moveDirection != Vector2.Zero) + moveDirection.Normalize(); + + _body.VelocityTarget = AnimationHelper.MoveToTarget(_body.VelocityTarget, moveDirection * 1.5f, 0.075f * Game1.TimeMultiplier); + + _direction = moveDirection.X < 0 ? -1 : 1; + _animator.Play("ganon_" + _direction); + } + else + { + _body.VelocityTarget = Vector2.Zero; + } + } + + private void InitGanonPostThrow() + { + _drawGanonWeapon = false; + _animator.Play("ganon_throw_" + _direction); + } + + private void InitGanonThrow() + { + _drawGanonWeapon = true; + } + + private void UpdateGanonThrow() + { + UpdateDirection(); + _animator.Play("ganon_swing_up_" + _direction); + _animatorWeapon.Play("ganon_swing_up_" + _direction); + } + + private void ThrowWeapon() + { + _aiComponent.ChangeState("ganonPostThrow"); + + var position = EntityPosition.Position - new Vector2(-_direction * 12, 22); + var objWeapon = new BossFinalBossWeapon(Map, this, (int)position.X, (int)position.Y, _direction); + Map.Objects.SpawnObject(objWeapon); + } + + private void UpdateDirection() + { + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + _direction = playerDirection.X < 0 ? -1 : 1; + } + + private void InitGanonBats() + { + _batIndex = 0; + _batCounter = 550 - 350; + + UpdateDirection(); + + _batIndexStart = _direction < 0 ? 3 : 0; + + _animator.Play("ganon_swing_" + _direction); + _animatorWeapon.Play("ganon_swing_" + _direction); + } + + private void UpdateGanonBats() + { + _batCounter += Game1.DeltaTime; + if (_batCounter > 550) + { + _batIndex++; + _batCounter -= 550; + + if (_batIndex > 8) + { + _aiComponent.ChangeState("ganonThrow"); + return; + } + if (_batIndex >= 7) + return; + + var radians = (_batIndexStart + _batIndex - 1) / 3f * MathF.PI; + var position = EntityPosition.Position - new Vector2(_direction * 9, 26) + new Vector2(MathF.Cos(radians), _direction * -MathF.Sin(radians)) * 24; + var objBat = new BossFinalBossBat(Map, (int)position.X, (int)position.Y); + Map.Objects.SpawnObject(objBat); + } + } + + private void InitGanonSpawn() + { + _ganonForm = true; + + _pushRepel = true; + _damageField.IsActive = true; + _damageField.CollisionBox = new CBox(EntityPosition, -12, 7 - 24, 24, 24, 8); + _hittableComponent.HittableBox = new CBox(EntityPosition, -12, 7 - 24, 24, 24, 8); + + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + var dir = playerDirection.X < 0 ? -1 : 1; + + Game1.GameManager.PlaySoundEffect("D370-35-23"); + + _animator.Play("ganon_spawn_" + dir); + } + + private void UpdateGanonSpawn() + { + if (!_animator.IsPlaying) + _aiComponent.ChangeState("ganonPreSpawnWeapon"); + } + + private void UpdateGanonPreSpawnWeapon() + { + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + var dir = playerDirection.X < 0 ? -1 : 1; + + _animator.Play("ganon_weapon_" + dir); + } + + private void InitGanonSpawnWeapon() + { + _drawGanonWeapon = true; + + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + var dir = playerDirection.X < 0 ? -1 : 1; + + Game1.GameManager.PlaySoundEffect("D360-57-39"); + + _animator.Play("ganon_weapon_spawn_" + dir); + _animatorWeapon.Play("ganon_weapon_spawn_" + dir); + } + + private void UpdateGanonSpawnWeapon() + { + if (!_animatorWeapon.IsPlaying) + _aiComponent.ChangeState("ganon"); + } + + private void InitGanon() + { + } + + private void UpdateGanon() + { + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + var dir = playerDirection.X < 0 ? -1 : 1; + + _animator.Play("ganon_" + dir); + _animatorWeapon.Play("ganon_" + dir); + } + + #endregion + + #region state moldorm + + private void InitMoldormSpawn() + { + _animator.Play("meldorm_spawn"); + } + + private void UpdateMoldormSpawn() + { + if (!_animator.IsPlaying) + _aiComponent.ChangeState("moldorm"); + } + + private void InitMoldorm() + { + _pushRepel = true; + _body.CollisionTypes = Values.CollisionTypes.Normal; + _drawMoldormTail = true; + _damageField.IsActive = true; + + for (var i = 0; i < _moldormPositions.Length; i++) + _moldormPositions[i] = EntityPosition.Position; + + for (var i = 0; i < _moldormTails.Length; i++) + { + string animationId; + if (i == _moldormTails.Length - 1) + animationId = "moldorm_tail"; + else if (i == _moldormTails.Length - 2) + animationId = "moldorm_body_2"; + else + animationId = "moldorm_body"; + + _moldormTails[i] = new BossFinalBossTail(Map, this, animationId, i == _moldormTails.Length - 1); + Map.Objects.SpawnObject(_moldormTails[i]); + } + } + + private void UpdateMoldormTail() + { + // blinking tail + _moldormTails[3].Sprite.SpriteShader = Game1.TotalGameTime % (AiDamageState.BlinkTime * 2) < AiDamageState.BlinkTime ? Resources.DamageSpriteShader0 : null; + } + + private void UpdateMoldorm() + { + UpdateMoldormTail(); + + // change the direction? + _moldormChangeCounter -= Game1.DeltaTime; + if (_moldormChangeCounter < 0) + { + _moldormChangeCounter += Game1.RandomNumber.Next(500, 2000); + _moldormDirection = -_moldormDirection; + } + + _moldormRadiant += Game1.TimeMultiplier * 0.065f * _moldormDirection; + + _moldormSpeed = _moldormSpeedUp.State ? MoldormSpeedNormal : MoldormSpeedFast; + if (_moldormHit) + { + _moldormSpeed = 0; + UpdateMoldormTail(EntityPosition); + } + else + { + _moldormSoundCounter -= Game1.DeltaTime * _moldormSpeed; + if (_moldormSoundCounter < 0) + { + _moldormSoundCounter += 250; + Game1.GameManager.PlaySoundEffect("D360-56-38"); + } + } + + _body.VelocityTarget = new Vector2(MathF.Sin(_moldormRadiant), MathF.Cos(_moldormRadiant)) * _moldormSpeed; + + _directionChangeMultiplier = AnimationHelper.MoveToTarget(_directionChangeMultiplier, 1, 0.1f * Game1.TimeMultiplier); + } + + private void InitMoldormDying() + { + _body.VelocityTarget = Vector2.Zero; + } + + private void UpdateMoldormDying() + { + UpdateMoldormTail(); + + _moldormRadiant += Game1.TimeMultiplier * 0.065f * _moldormDirection; + + UpdateMoldormTail(EntityPosition); + } + + private void MoldormExplode() + { + _aiComponent.ChangeState("moldormDespawn"); + _animator.Play("slime_despawn"); + + _drawMoldormTail = false; + + _pushRepel = false; + _damageField.IsActive = false; + _bodyShadow.IsActive = false; + _drawComponent.Layer = Values.LayerBottom; + + Game1.GameManager.PlaySoundEffect("D378-55-37"); + + ExplosionParticle(); + } + + private void UpdateMoldormDespawn() + { + if (!_animator.IsPlaying) + _aiComponent.ChangeState("move"); + } + + private void OnUpdatePosition(CPosition position) + { + if (_aiComponent.CurrentStateId == "moldorm") + UpdateMoldormTail(position); + } + + private void UpdateMoldormTail(CPosition position) + { + // set the rotation to be 0 < rotation < Pi * 2 to allow for correct calculations + while (_moldormRadiant < MathF.PI * 2) + _moldormRadiant += MathF.PI * 2; + _moldormRadiant %= MathF.PI * 2; + + var radiantIndex = (int)(((_moldormRadiant + MathF.PI / 8) / (2 * MathF.PI)) * 8) % 8; + _animator.Play("moldorm_head_" + (8 - radiantIndex) % 8); + + _moldormPositions[0] = position.Position; + + if (!_aiDamageState.IsInDamageState()) + { + if (_moldormHit) + { + _moldormHit = false; + _moldormSpeedUp.Reset(); + } + + _partDist = new float[] { 12, 12, 12, 10 }; + } + else + { + for (int i = 0; i < _partDist.Length; i++) + { + if (_partDist[i] > 0) + { + _partDist[i] -= Game1.TimeMultiplier * 1.75f; + if (_partDist[i] < 0) + _partDist[i] = 0; + break; + } + } + } + + var partPos = 0f; + var partIndex = 0; + var targetDist = _partDist[0] / TailMult; + + for (int i = 1; i < _moldormPositions.Length; i++) + { + // this loop is only used to make sure to not have and endless loop incase of a problem with the code below + while (partIndex + 1 < _moldormPositions.Length) + { + var dist = (_moldormPositions[partIndex + 1] - _moldormPositions[partIndex]).Length(); + if (dist - partPos >= targetDist) + { + var percentage = dist > 0 ? (dist - partPos - targetDist) / dist : 1; + var newPosition = Vector2.Lerp(_moldormPositions[partIndex + 1], _moldormPositions[partIndex], percentage); + partPos += targetDist; + if (i / TailMult < _partDist.Length) + targetDist = _partDist[i / TailMult] / TailMult; + + _moldormPositionsNew[i] = newPosition; + + break; + } + else + { + partIndex++; + targetDist -= (dist - partPos); + partPos = 0; + } + } + + // the tail is not expaneded + if (partIndex + 1 >= _moldormPositions.Length) + _moldormPositionsNew[i] = _moldormPositions[_moldormPositions.Length - 1]; + } + + for (int i = 1; i < _moldormPositions.Length; i++) + _moldormPositions[i] = _moldormPositionsNew[i]; + + // set the newly calculated positions + for (var i = 0; i < _moldormTails.Length; i++) + _moldormTails[i].EntityPosition.Set(_moldormPositions[(i + 1) * TailMult]); + } + + #endregion + + #region state init + + private void InitIdle() + { + Game1.GameManager.StartDialogPath("final_boss_intro"); + } + + private void UpdateIdle() + { + if (!Game1.GameManager.DialogIsRunning() && + !Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen) + { + _aiComponent.ChangeState("moveBody"); + } + } + + private void InitMoveBody() + { + Game1.GameManager.PlaySoundEffect("D360-53-35"); + } + + private void UpdateBodyPartPosition(float state) + { + var direction = _bodyPosition - EntityPosition.Position; + + // this is supposed to make it look better by moving the first element more than the following elements + // TODO: should be replaced by constant speed up moving up? + var stateRad = MathF.PI / 2 - state * MathF.PI / 2; + var max = MathF.Sin(stateRad); + var min = MathF.Sin(stateRad - MathF.PI / 2); + for (var i = 0; i < _bodyParts.Length; i++) + { + var percentage = stateRad - (float)(i + 1) / (_bodyParts.Length + 1) * MathF.PI / 2; + var sinState = (MathF.Sin(percentage) - min) / (max - min); + _bodyParts[i] = EntityPosition.Position + direction * (1 - sinState); + } + } + + private void UpdateMoveBody() + { + _moveSpeed = AnimationHelper.MoveToTarget(_moveSpeed, 1.75f, 0.05f * Game1.TimeMultiplier); + _bodyPosition = AnimationHelper.MoveToTarget(_bodyPosition, _bodyTargetPosition, _moveSpeed * Game1.TimeMultiplier); + + var bodyState = Math.Clamp(0.5f - (_bodyPosition.Y - _bodyTargetPosition.Y) / (_moveDist * 0.5f), 0, 0.5f); + UpdateBodyPartPosition(bodyState); + + if (_bodyPosition == _bodyTargetPosition) + { + _moveSpeed = 0.25f; + _animatorBody.Play("spawn"); + _aiComponent.ChangeState("moveHead"); + } + } + + private void UpdateMoveHead() + { + _moveSpeed = AnimationHelper.MoveToTarget(_moveSpeed, 1.75f, 0.05f * Game1.TimeMultiplier); + var newPosition = AnimationHelper.MoveToTarget(EntityPosition.Position, _bodyTargetPosition, _moveSpeed * Game1.TimeMultiplier); + EntityPosition.X = newPosition.X; + EntityPosition.Y = newPosition.Y; + + var bodyState = Math.Clamp(2.5f - (EntityPosition.Y - _bodyTargetPosition.Y) / (_moveDist * 0.5f), 0.5f, 1.0f); + UpdateBodyPartPosition(bodyState); + + if (EntityPosition.Position == _bodyTargetPosition) + _aiComponent.ChangeState("wobble"); + } + + private void InitWobble() + { + _animatorBody.Play("wobble"); + } + + private void UpdateWobble() + { + if (!_animatorBody.IsPlaying) + _aiComponent.ChangeState("despawn"); + } + + private void InitStartDespawn() + { + _hideBody = true; + _animator.Play("despawn"); + Game1.GameManager.PlaySoundEffect("D360-04-04"); + } + + private void UpdateDespawn() + { + if (!_animator.IsPlaying) + _aiComponent.ChangeState("slimeSpawn"); + } + + #endregion + + #region state explode + + private void InitExplode() + { + _pushRepel = false; + Game1.GameManager.PlaySoundEffect("D378-55-37"); + ExplodeAnimation(); + } + + private void ExplodeAnimation() + { + _animator.Play("head"); + + _damageField.IsActive = false; + _bodyShadow.IsActive = false; + _drawComponent.Layer = Values.LayerBottom; + + ExplosionParticle(); + } + + private void ExplosionParticle() + { + for (int i = 0; i < 8; i++) + { + var radiant = i / 4f * MathF.PI; + var velocity = new Vector2(MathF.Sin(radiant), MathF.Cos(radiant)) * 2.5f; + var objParticle0 = new BossFinalBossParticle(Map, new Vector2(EntityPosition.X, EntityPosition.Y - EntityPosition.Z), velocity); + Map.Objects.SpawnObject(objParticle0); + } + } + + private void InitDespawn() + { + _animator.Play("slime_despawn"); + } + + private void UpdateDepawn() + { + if (!_animator.IsPlaying) + _aiComponent.ChangeState("move"); + } + + private void InitMove() + { + Game1.GameManager.PlaySoundEffect("D360-53-35"); + _body.CollisionTypes = Values.CollisionTypes.None; + } + + private void UpdateMove() + { + var direction = new Vector2(_roomRectangle.Center.X, _roomRectangle.Y + 43) - EntityPosition.Position; + + if (direction.Length() < 2) + { + _body.CollisionTypes = Values.CollisionTypes.Normal; + _aiComponent.ChangeState("moveWait"); + } + else + { + direction.Normalize(); + var targetVelocity = AnimationHelper.MoveToTarget(new Vector2(_body.Velocity.X, _body.Velocity.Y), direction, 0.15f * Game1.TimeMultiplier); + _body.Velocity.X = targetVelocity.X; + _body.Velocity.Y = targetVelocity.Y; + } + } + + private void EndMoveWait() + { + if (_moveCounter == 0) + _aiComponent.ChangeState("moldormSpawn"); + else if (_moveCounter == 1) + _aiComponent.ChangeState("ganonSpawn"); + + _moveCounter++; + } + + #endregion + + #region state slime + + private void InitSlimeSpawn() + { + _slimeForm = true; + _hideHead = false; + _pushRepel = true; + _bodyShadow.IsActive = true; + _damageField.IsActive = true; + + _hittableComponent.HittableBox = new CBox(EntityPosition, -8, -8, 0, 16, 16, 8, true); + _hittableComponent.IsActive = true; + + _drawComponent.Layer = Values.LayerPlayer; + + _animator.Play("slime_spawn"); + } + + private void UpdateSlimeSpawn() + { + if (!_animator.IsPlaying) + _aiComponent.ChangeState("slimeJump"); + } + + private void InitSlimeJump() + { + _animator.Play("slime_jump"); + + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + + _body.IsGrounded = false; + _body.Velocity.X = playerDirection.X * 0.5f; + _body.Velocity.Y = playerDirection.Y * 0.5f; + _body.Velocity.Z = 1.75f; + } + + private void UpdateSlimeJump() + { + if (_body.IsGrounded) + { + Game1.GameManager.PlaySoundEffect("D360-32-20"); + + if (Game1.RandomNumber.Next(0, 2) == 0) + _aiComponent.ChangeState("slimeWait"); + else + _aiComponent.ChangeState("slimeDespawn"); + } + else if (_body.Velocity.Y < -0.5f) + { + _animator.Play("slime_land"); + } + } + + private void InitSlimeWait() + { + _animator.Play("slime"); + } + + private void InitSlimeDespawn() + { + _bodyShadow.IsActive = false; + _damageField.IsActive = false; + _hittableComponent.IsActive = false; + _pushRepel = false; + + _animator.Play("slime_despawn"); + + EntityPosition.Offset(new Vector2(0, -2)); + } + + private void UpdateSlimeDespawn() + { + if (!_animator.IsPlaying) + _aiComponent.ChangeState("slimeHidden"); + } + + private void InitSlimeHidden() + { + _hideHead = true; + } + + private void EndSlimeHidden() + { + // random new position + EntityPosition.Set(RandomRoomPosition()); + + _aiComponent.ChangeState("slimeSpawn"); + } + + private void InitSlimeDamaged() + { + _animator.Play("slime_damaged"); + Game1.GameManager.PlaySoundEffect("D360-55-37"); + } + + private void TickSlimeDamaged(double counter) + { + var time = SlimeDamageTime - counter; + if (time < AiDamageState.CooldownTime && time % (AiDamageState.BlinkTime * 2) < AiDamageState.BlinkTime) + Sprite.SpriteShader = Resources.DamageSpriteShader0; + else + Sprite.SpriteShader = null; + } + + private void EndSlimeDamge() + { + _slimeForm = false; + + if (_slimeLives <= 0) + _aiComponent.ChangeState("slimeExplode"); + else + _aiComponent.ChangeState("slimeDespawn"); + } + + private void InitSlimeHideExplode() + { + _pushRepel = false; + _hideHead = true; + _bodyShadow.IsActive = false; + _damageField.IsActive = false; + _hittableComponent.IsActive = false; + + InitSlimeExplode(); + } + + private void InitSlimeExplode() + { + EntityPosition.Offset(new Vector2(0, -2)); + Game1.GameManager.PlaySoundEffect("D370-33-21"); + + _body.VelocityTarget = Vector2.Zero; + ExplodeAnimation(); + } + + #endregion + + #region state man + + // @TODO: + // type 2 spawn rate + + private void SlimeEnd() + { + _aiComponent.ChangeState("manMove"); + _manTargetPosition = new Vector2(_roomRectangle.Center.X, _roomRectangle.Y + 43); + } + + private void InitManSpawn() + { + _animator.Play("man_spawn"); + } + + private void UpdateManSpawn() + { + if (_animator.IsPlaying) + return; + + _pushRepel = true; + _damageField.IsActive = true; + Game1.GameManager.PlaySoundEffect("D370-35-23"); + _aiComponent.ChangeState("manPreAttack"); + } + + private void TestProjectileSpawn() + { + _animator.Play("man_" + _direction); + _objFireball = new BossFinalBossFireball(this, EntityPosition.Position + _fireballOffset[_direction]); + Map.Objects.SpawnObject(_objFireball); + + _objFireball.Fire(); + } + + private void UpdateManPreAttack() + { + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + _direction = AnimationHelper.GetDirection(playerDirection); + + if (_manInit) + { + _animator.Play("man_" + _direction); + _animator.Pause(); + } + else + { + _animator.Play("man_attack_" + _direction); + } + } + + private void InitManAttack() + { + _manInit = false; + _animator.Play("man_" + _direction); + Game1.GameManager.PlaySoundEffect("D370-34-22"); + + _objFireball = new BossFinalBossFireball(this, EntityPosition.Position + _fireballOffset[_direction]); + Map.Objects.SpawnObject(_objFireball); + } + + private void UpdateManAttack() + { + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + var newDirection = AnimationHelper.GetDirection(playerDirection); + + if (newDirection != _direction) + { + _direction = newDirection; + _animator.Play("man_" + _direction); + _objFireball.EntityPosition.Set(EntityPosition.Position + _fireballOffset[_direction]); + } + + if (_objFireball.IsReady) + { + _aiComponent.ChangeState("manPostAttack"); + _objFireball.Fire(); + } + } + + private void InitPostAttack() + { + _animator.Play("man_attack_" + _direction); + } + + private void UpdateManPostAttack() { } + + private void InitManDespawn() + { + _pushRepel = false; + _damageField.IsActive = false; + _animator.Play("man_despawn"); + } + + private void UpdateManDespawn() + { + if (!_animator.IsPlaying) + _aiComponent.ChangeState("manMove"); + } + + private void InitManMove() + { + Game1.GameManager.PlaySoundEffect("D360-53-35"); + _body.CollisionTypes = Values.CollisionTypes.None; + _manTargetPosition = RandomRoomPositionSide(); + } + + private void UpdateManMove() + { + var direction = _manTargetPosition - EntityPosition.Position; + + if (direction.Length() < 2) + { + _body.CollisionTypes = Values.CollisionTypes.Normal; + _aiComponent.ChangeState("manMoveWait"); + } + else + { + direction.Normalize(); + var targetVelocity = AnimationHelper.MoveToTarget(new Vector2(_body.Velocity.X, _body.Velocity.Y), direction, 0.15f * Game1.TimeMultiplier); + _body.Velocity.X = targetVelocity.X; + _body.Velocity.Y = targetVelocity.Y; + } + } + + private void InitManRotate() + { + Game1.GameManager.PlaySoundEffect("D360-54-36"); + _animator.Play("man_rotate"); + // first frame = up + // make sure to not jump to a different direction + _animator.SetFrame((_direction + 3) % 4); + } + + private void TickRotate(double time) + { + // speed up the rotation speed + var rotateSpeed = Math.Clamp((RotateTime - (float)time) / (RotateTime * 0.65f), 0, 1); + _animator.SpeedMultiplier = rotateSpeed * 3 + 1; + } + + private void EndRotate() + { + _pushRepel = false; + EntityPosition.Set(new Vector2(EntityPosition.X, EntityPosition.Y - 4)); + + _animator.SpeedMultiplier = 1; + _aiComponent.ChangeState("explode"); + } + + #endregion + + public bool HitBoss(GameObject origin, Vector2 direction, CBox damageBox) + { + // getting hit by the fireball? + if (!_aiDamageState.IsInDamageState() && _aiComponent.CurrentStateId == "manPostAttack" && damageBox.Box.Intersects(_hittableBoxMan.Box)) + { + _aiDamageState.OnHit(origin, direction, HitType.Boss, 1, false); + + _manLives--; + if (_manLives <= 0) + _aiComponent.ChangeState("manRotate"); + + return true; + } + + return false; + } + + private void OnZeroLives(bool pieceOfPower) { } + + private Vector2 RandomRoomPositionSide() + { + // always change the side + _sideIndex = (_sideIndex + Game1.RandomNumber.Next(1, 4)) % 4; + if (_sideIndex == 0) + return new Vector2(_roomRectangle.X + 16 + 16, _roomRectangle.Y + 32 + 16 + Game1.RandomNumber.Next(0, 2 * 16)); + else if (_sideIndex == 2) + return new Vector2(_roomRectangle.X + 128, _roomRectangle.Y + 32 + 16 + Game1.RandomNumber.Next(0, 2 * 16)); + else if (_sideIndex == 1) + return new Vector2(_roomRectangle.X + 32 + 16 + Game1.RandomNumber.Next(0, 4 * 16), _roomRectangle.Y + 32); + else + return new Vector2(_roomRectangle.X + 32 + 16 + Game1.RandomNumber.Next(0, 4 * 16), _roomRectangle.Y + 100); + } + + private Vector2 RandomRoomPosition() + { + var posY = Game1.RandomNumber.Next(0, 5 * 16); + int posX; + if (16 < posY || posY < 64 - 16) + posX = Game1.RandomNumber.Next(16, 6 * 16); + else + posX = Game1.RandomNumber.Next(0, 8 * 16); + + return new Vector2(_roomRectangle.X + 24 + posX, _roomRectangle.Y + 24 + posY); + } + + private void Update() + { + _animatorBody.Update(); + + if (_drawGanonWeapon) + _animatorWeapon.Update(); + } + + private void Draw(SpriteBatch spriteBatch) + { + // draw the tail + if (_drawMoldormTail) + for (var i = _moldormTails.Length - 1; i >= 0; i--) + { + if (i != _moldormTails.Length - 1) + _moldormTails[i].Sprite.SpriteShader = Sprite.SpriteShader; + _moldormTails[i].Sprite.Draw(spriteBatch); + } + + // draw the body parts + if (!_hideBody) + for (var i = 0; i < _bodyParts.Length; i++) + DrawHelper.DrawNormalized(spriteBatch, _spriteBody, _bodyParts[i], Color.White); + + if (!_hideBody) + _animatorBody.Draw(spriteBatch, _bodyPosition, Color.White); + + if (Sprite.SpriteShader != null) + { + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, Sprite.SpriteShader); + } + + // draw the weapon of ganon + if (_drawGanonWeapon) + _animatorWeapon.Draw(spriteBatch, EntityPosition.Position, Color.White); + + if (!_hideHead) + Sprite.Draw(spriteBatch); + + if (Sprite.SpriteShader != null) + { + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, Sprite.SpriteShader); + } + + if (_finalState && (_finalEyeState == 1 || (_finalEyeState == 0 && _animatorEye.IsPlaying))) + _animatorEye.Draw(spriteBatch, new Vector2(EntityPosition.X, EntityPosition.Y + 1), Color.White); + + if (Sprite.SpriteShader != null) + { + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, null); + } + } + + public Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + // slime attacked by powder + if (_slimeForm && (damageType & HitType.MagicPowder) != 0) + { + _body.Velocity.X = direction.X; + _body.Velocity.Y = direction.Y; + if (_body.Velocity.Z > 0) + _body.Velocity.Z = 0; + + _aiComponent.ChangeState("slimeDamaged"); + _slimeLives--; + + return Values.HitCollision.Enemy; + } + + if ((damageType & (HitType.Sword | HitType.SwordHold)) != 0 && + (_aiComponent.CurrentStateId == "slimeJump" || _aiComponent.CurrentStateId == "slimeWait")) + { + _aiComponent.ChangeState("slimeHideExplode"); + return Values.HitCollision.Enemy; + } + + if (_aiComponent.CurrentStateId == "moldorm") + { + return Values.HitCollision.RepellingParticle; + } + + // ganon damage form + if (_ganonForm && !_aiDamageState.IsInDamageState() && (damageType & HitType.PegasusBootsSword) != 0) + { + _ganonLives -= damage; + if (_ganonLives <= 0) + _aiComponent.ChangeState("ganonDeath"); + + Game1.GameManager.PlaySoundEffect("D370-07-07"); + _aiDamageState.SetDamageState(); + + return Values.HitCollision.Repelling; + } + if (_ganonForm && (damageType & HitType.Sword) != 0) + { + return Values.HitCollision.Repelling; + } + + if (_aiComponent.CurrentStateId == "face" && !_aiDamageState.IsInDamageState()) + { + if ((damageType & (HitType.Hookshot | HitType.MagicRod | HitType.Bomb | HitType.Boomerang | HitType.Bow)) != 0) + { + _aiDamageState.SetDamageState(); + _aiComponent.ChangeState("faceExplode"); + return Values.HitCollision.Enemy; + } + else + { + _aiDamageState.SetDamageState(false); + + _body.Velocity.X += direction.X; + _body.Velocity.Y += direction.Y; + + Game1.GameManager.PlaySoundEffect("D360-09-09"); + Game1.GameManager.PlaySoundEffect("D370-17-11"); + + return Values.HitCollision.Repelling | Values.HitCollision.Repelling1; + } + } + + if (_aiComponent.CurrentStateId == "final") + { + // bow hit from below with an open eye + if (!_aiDamageState.IsInDamageState() && ( + (_finalEyeState == 0 && _animatorEye.CurrentFrameIndex < 1) || + (_finalEyeState == 1 && _animatorEye.CurrentFrameIndex >= 1)) && (damageType & HitType.Bow) != 0 && + MathF.Abs(direction.Y) > MathF.Abs(direction.X) && direction.Y < 0) + { + _aiDamageState.SetDamageState(); + + _finalStateLives--; + if (_finalStateLives <= 0) + _aiComponent.ChangeState("finalBlink"); + + Game1.GameManager.PlaySoundEffect("D370-07-07"); + + // randomly change the speed of the two parts + _finalPartSpeed0 = (1 / 2500.0f * MathF.PI * 2) * (1 + (Game1.RandomNumber.Next(0, 101) - 50) / 500f); + _finalPartSpeed1 = (1 / 2500.0f * MathF.PI * 2) * (1 + (Game1.RandomNumber.Next(0, 101) - 50) / 500f); + + return Values.HitCollision.Enemy; + } + else + { + return Values.HitCollision.RepellingParticle; + } + } + + return Values.HitCollision.None; + } + + public Values.HitCollision HitTail(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (!_aiDamageState.IsInDamageState() && _aiComponent.CurrentStateId == "moldorm" && ((damageType & HitType.Sword) != 0)) + { + _moldormLives -= damage; + if (_moldormLives <= 0) + _aiComponent.ChangeState("moldormDying"); + + Game1.GameManager.PlaySoundEffect("D370-07-07"); + Game1.GameManager.StopSoundEffect("D360-56-38"); + + _moldormHit = true; + _aiDamageState.SetDamageState(true); + return Values.HitCollision.Enemy; + } + + return Values.HitCollision.None; + } + + private void OnCollision(Values.BodyCollision collision) + { + if (_aiComponent.CurrentStateId == "moldorm") + { + if (Game1.RandomNumber.Next(0, 2) == 0) + _moldormDirection = -_moldormDirection; + + if ((collision & Values.BodyCollision.Horizontal) != 0) + _moldormRadiant = (float)Math.Atan2(-_body.VelocityTarget.X * _directionChangeMultiplier, _body.VelocityTarget.Y); + else if ((collision & Values.BodyCollision.Vertical) != 0) + _moldormRadiant = (float)Math.Atan2(_body.VelocityTarget.X, -_body.VelocityTarget.Y * _directionChangeMultiplier); + + _directionChangeMultiplier *= 0.75f; + } + + if (_aiComponent.CurrentStateId == "face") + { + if ((collision & Values.BodyCollision.Horizontal) != 0) + { + _body.Velocity.X = -_body.VelocityTarget.X * 0.125f; + _body.VelocityTarget.X = 0; + } + else if ((collision & Values.BodyCollision.Vertical) != 0) + { + _body.Velocity.Y = -_body.VelocityTarget.Y * 0.125f; + _body.VelocityTarget.Y = 0; + } + } + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (!_pushRepel) + return false; + + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossFinalBossBat.cs b/InGame/GameObjects/Bosses/BossFinalBossBat.cs new file mode 100644 index 0000000..ea06af7 --- /dev/null +++ b/InGame/GameObjects/Bosses/BossFinalBossBat.cs @@ -0,0 +1,107 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + class BossFinalBossBat : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly CSprite _sprite; + + public BossFinalBossBat(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(-8, -8, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Nightmares/nightmare bat"); + + _sprite = new CSprite(EntityPosition); + var animatorComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -5, -4, 10, 8, 8) + { + IgnoresZ = true, + IgnoreHoles = true, + CollisionTypes = Values.CollisionTypes.None + }; + + _aiComponent = new AiComponent(); + + var stateIdle = new AiState() { Init = InitIdle }; + stateIdle.Trigger.Add(new AiTriggerCountdown(400, null, () => _aiComponent.ChangeState("fire"))); + var stateFire = new AiState() { Init = InitFire }; + stateFire.Trigger.Add(new AiTriggerCountdown(400, null, () => _aiComponent.ChangeState("bat"))); + var stateBat = new AiState() { Init = InitBat }; + stateBat.Trigger.Add(new AiTriggerCountdown(550, null, () => _aiComponent.ChangeState("flying"))); + var stateFlying = new AiState() { Init = InitFlying }; + stateFlying.Trigger.Add(new AiTriggerCountdown(2000, FadeOut, Despawn)); + + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("fire", stateFire); + _aiComponent.States.Add("bat", stateBat); + _aiComponent.States.Add("flying", stateFlying); + + _aiComponent.ChangeState("idle"); + + var damageCollider = new CBox(EntityPosition, -5, -4, 0, 10, 8, 8); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 2)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(BaseAnimationComponent.Index, animatorComponent); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerTop)); + } + + private void Update() + { + _sprite.SpriteShader = + Game1.TotalGameTime % (AiDamageState.BlinkTime * 2) < AiDamageState.BlinkTime ? Resources.DamageSpriteShader0 : null; + } + + private void InitIdle() + { + _animator.Play("idle"); + } + + private void InitFire() + { + _animator.Play("fire"); + } + + private void InitBat() + { + _animator.Play("bat"); + } + + private void InitFlying() + { + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + _body.VelocityTarget = playerDirection * 1.75f; + + Game1.GameManager.PlaySoundEffect("D378-40-28"); + } + + private void FadeOut(double time) + { + var percentage = MathHelper.Clamp((float)time / 75, 0, 1); + _sprite.Color = Color.White * percentage; + } + + private void Despawn() + { + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossFinalBossFinalTail.cs b/InGame/GameObjects/Bosses/BossFinalBossFinalTail.cs new file mode 100644 index 0000000..9ea7247 --- /dev/null +++ b/InGame/GameObjects/Bosses/BossFinalBossFinalTail.cs @@ -0,0 +1,57 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + class BossFinalBossFinalTail : GameObject + { + private readonly BossFinalBoss _owner; + + private readonly DrawComponent _drawComponent; + private readonly DamageFieldComponent _damageFieldComponent; + + public readonly CSprite Sprite; + + public BossFinalBossFinalTail(Map.Map map, BossFinalBoss owner, string spriteId, Vector2 position) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(position.X, position.Y, 0); + EntitySize = new Rectangle(-8, -8, 16, 16); + + _owner = owner; + + Sprite = new CSprite(spriteId, EntityPosition); + + var damageCollider = new CBox(EntityPosition, -3, -3, 6, 6, 3); + AddComponent(DamageFieldComponent.Index, _damageFieldComponent = new DamageFieldComponent(damageCollider, HitType.Enemy, 2)); + AddComponent(DrawComponent.Index, _drawComponent = new DrawComponent(Draw, Values.LayerBottom, EntityPosition)); + + SetActive(false); + } + + public void DeactivateDamageField() + { + _damageFieldComponent.IsActive = false; + } + + public void SetActive(bool state) + { + _damageFieldComponent.IsActive = state; + _drawComponent.IsActive = state; + } + + private void Draw(SpriteBatch spriteBatch) + { + if (!_drawComponent.IsActive) + return; + + Sprite.SpriteShader = _owner.Sprite.SpriteShader; + Sprite.Draw(spriteBatch); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossFinalBossFireball.cs b/InGame/GameObjects/Bosses/BossFinalBossFireball.cs new file mode 100644 index 0000000..50b840d --- /dev/null +++ b/InGame/GameObjects/Bosses/BossFinalBossFireball.cs @@ -0,0 +1,263 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.GameObjects.Enemies; +using ProjectZ.InGame.GameObjects.Things; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + class BossFinalBossFireball : GameObject + { + private readonly BossFinalBoss _finalBoss; + + private readonly CSprite _sprite; + private readonly BodyComponent _body; + private readonly Animator _animator; + private readonly AiComponent _aiComponent; + private readonly CBox _damageBox; + + private ObjAnimator _objTrail0; + private ObjAnimator _objTrail1; + + private bool _isMoving; + private bool _isRepelled; + private double _moveTime = 0; + + private const double BlinkTime = 2000 / 60.0; + private const float Speed = 1.5f; + + private bool _isReady; + + private bool _damageState; + + public bool IsReady { get => _isReady; } + + public BossFinalBossFireball(BossFinalBoss boss, Vector2 position) : base(boss.Map) + { + _finalBoss = boss; + + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(position.X, position.Y, 0); + EntitySize = new Rectangle(-8, -8, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Nightmares/nightmare fireball"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -3, -3, 6, 6, 8) + { + IgnoresZ = true, + IgnoreHoles = true + }; + + _aiComponent = new AiComponent(); + + var state0 = new AiState() { Init = () => _animator.Play("idle_0") }; + state0.Trigger.Add(new AiTriggerCountdown(1100, null, () => _aiComponent.ChangeState("idle1"))); + var state1 = new AiState() { Init = () => _animator.Play("idle_1") }; + state1.Trigger.Add(new AiTriggerCountdown(1100, null, () => _aiComponent.ChangeState("idle2"))); + var state2 = new AiState() { Init = () => _animator.Play("idle_2") }; + state2.Trigger.Add(new AiTriggerCountdown(1100, null, () => _isReady = true)); + var stateMoving = new AiState(); + + _aiComponent.States.Add("idle0", state0); + _aiComponent.States.Add("idle1", state1); + _aiComponent.States.Add("idle2", state2); + _aiComponent.States.Add("moving", stateMoving); + + _aiComponent.ChangeState("idle0"); + + var damageCollider = new CBox(EntityPosition, -3, -3, 0, 6, 6, 8); + var hittableBox = new CBox(EntityPosition, -4, -4, 0, 8, 8, 8); + _damageBox = new CBox(EntityPosition, -4, -4, 0, 8, 8, 8); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 2)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerTop)); + } + + public void Fire() + { + Game1.GameManager.PlaySoundEffect("D378-56-38"); + + _isMoving = true; + _aiComponent.ChangeState("moving"); + + if (Game1.RandomNumber.Next(0, 4) == 0) + { + _damageState = true; + _body.MoveCollision = OnMoveCollision; + _animator.Play("idle_3"); + } + else + { + EntityPosition.AddPositionListener(typeof(BossFinalBossFireball), UpdateTrail); + _body.CollisionTypes = Values.CollisionTypes.None; + _animator.Play("idle_2"); + SpawnTrail(); + } + + var playerDirection = new Vector2(MapManager.ObjLink.EntityPosition.X, MapManager.ObjLink.EntityPosition.Y - 4) - EntityPosition.Position; + if (playerDirection != Vector2.Zero) + { + playerDirection.Normalize(); + _body.VelocityTarget = playerDirection * Speed; + } + } + + private void Update() + { + if (_isMoving) + { + _moveTime += Game1.DeltaTime; + + if (_isRepelled && _finalBoss.HitBoss(this, _body.VelocityTarget * 0.75f, _damageBox)) + _moveTime = 1300; + + // fade away + if (_moveTime > 1300) + { + _sprite.Color = Color.White * MathHelper.Clamp(1 - ((float)_moveTime - 1300) / 100, 0, 1); + + if (_objTrail0 != null) + _objTrail0.Sprite.Color = Color.White * MathHelper.Clamp(1 - ((float)_moveTime - 1350) / 100, 0, 1); + if (_objTrail1 != null) + _objTrail1.Sprite.Color = Color.White * MathHelper.Clamp(1 - ((float)_moveTime - 1400) / 100, 0, 1); + } + + if (_moveTime > 1500) + { + DeleteObject(); + return; + } + } + + // blink + var shader = Game1.TotalGameTime % (BlinkTime * 2) < BlinkTime ? Resources.DamageSpriteShader0 : null; + _sprite.SpriteShader = shader; + if (_objTrail0 != null) + _objTrail0.Sprite.SpriteShader = shader; + if (_objTrail1 != null) + _objTrail1.Sprite.SpriteShader = shader; + } + + private void SpawnTrail() + { + _objTrail0 = new ObjAnimator(Map, (int)EntityPosition.X, (int)EntityPosition.Y, Values.LayerPlayer, "Nightmares/nightmare fireball", "idle_1", false); + _objTrail1 = new ObjAnimator(Map, (int)EntityPosition.X, (int)EntityPosition.Y, Values.LayerBottom, "Nightmares/nightmare fireball", "idle_0", false); + + Map.Objects.SpawnObject(_objTrail0); + Map.Objects.SpawnObject(_objTrail1); + } + + private void UpdateTrail(CPosition position) + { + var dist0 = _objTrail0.EntityPosition.Position - position.Position; + if (dist0.Length() > 7) + { + dist0.Normalize(); + dist0 *= 7; + } + _objTrail0.EntityPosition.Set(EntityPosition.Position + dist0); + + var dist1 = _objTrail1.EntityPosition.Position - _objTrail0.EntityPosition.Position; + if (dist1.Length() > 8) + { + dist1.Normalize(); + dist1 *= 8; + } + _objTrail1.EntityPosition.Set(_objTrail0.EntityPosition.Position + dist1); + } + + private void Repell() + { + Game1.GameManager.PlaySoundEffect("D378-56-38"); + + _isRepelled = true; + _moveTime = 0; + + var playerDirection = EntityPosition.Position - + new Vector2(MapManager.ObjLink.EntityPosition.X, MapManager.ObjLink.EntityPosition.Y - 4); + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + + _body.VelocityTarget = playerDirection * Speed; + } + + private void OnMoveCollision(Values.BodyCollision collision) + { + OnDeath(); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + if ((type & HitType.Sword) == 0 || (type & HitType.SwordHold) != 0) + return Values.HitCollision.None; + + // can not be hit before moving for a little while + if (_moveTime < 125) + return Values.HitCollision.None; + + if (_damageState) + OnDeath(); + else + Repell(); + + return Values.HitCollision.Enemy; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (_damageState && type == PushableComponent.PushType.Impact) + OnDeath(); + + return true; + } + + private void OnDeath() + { + var posX = (int)EntityPosition.X; + var posY = (int)EntityPosition.Y; + var speed = 2.75f / 1.4f; + + var objFireball0 = new EnemyFireball(Map, posX - 2, posY - 2, 1, false); + var objFireball1 = new EnemyFireball(Map, posX + 2, posY - 2, 1, false); + var objFireball2 = new EnemyFireball(Map, posX - 2, posY + 2, 1, false); + var objFireball3 = new EnemyFireball(Map, posX + 2, posY + 2, 1, false); + + objFireball0.SetVelocity(new Vector2(-1, -1) * speed); + objFireball1.SetVelocity(new Vector2(1, -1) * speed); + objFireball2.SetVelocity(new Vector2(-1, 1) * speed); + objFireball3.SetVelocity(new Vector2(1, 1) * speed); + + Map.Objects.SpawnObject(objFireball0); + Map.Objects.SpawnObject(objFireball1); + Map.Objects.SpawnObject(objFireball2); + Map.Objects.SpawnObject(objFireball3); + + Map.Objects.DeleteObjects.Add(this); + } + + private void DeleteObject() + { + if (_objTrail0 != null) + Map.Objects.DeleteObjects.Add(_objTrail0); + if (_objTrail1 != null) + Map.Objects.DeleteObjects.Add(_objTrail1); + + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossFinalBossParticle.cs b/InGame/GameObjects/Bosses/BossFinalBossParticle.cs new file mode 100644 index 0000000..25b6cd6 --- /dev/null +++ b/InGame/GameObjects/Bosses/BossFinalBossParticle.cs @@ -0,0 +1,55 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + internal class BossFinalBossParticle : GameObject + { + private readonly BodyComponent _body; + private readonly CSprite _sprite; + + private float _transparency = 1; + + public BossFinalBossParticle(Map.Map map, Vector2 position, Vector2 velocity) : base(map) + { + EntityPosition = new CPosition(position.X, position.Y, 0); + EntitySize = new Rectangle(-8, -8, 16, 16); + + var animator = AnimatorSaveLoad.LoadAnimator("Nightmares/nightmare particle"); + animator.Play("idle"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -5, -5, 10, 10, 8) + { + Velocity = new Vector3(velocity, 0), + Drag = 0.94f, + CollisionTypes = Values.CollisionTypes.None + }; + + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerPlayer)); + } + + private void Update() + { + // fade away + if (_body.Velocity.Length() < 0.125f) + { + _transparency -= Game1.TimeMultiplier * 0.165f; + _sprite.Color = Color.White * _transparency; + + if (_transparency <= 0) + Map.Objects.DeleteObjects.Add(this); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossFinalBossTail.cs b/InGame/GameObjects/Bosses/BossFinalBossTail.cs new file mode 100644 index 0000000..9c1d00f --- /dev/null +++ b/InGame/GameObjects/Bosses/BossFinalBossTail.cs @@ -0,0 +1,35 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + class BossFinalBossTail : GameObject + { + public readonly CSprite Sprite; + + public BossFinalBossTail(Map.Map map, BossFinalBoss nightmare, string animationId, bool hittable) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(nightmare.EntityPosition.X, nightmare.EntityPosition.Y, 0); + EntitySize = new Rectangle(-8, -8, 16, 16); + + var animator = AnimatorSaveLoad.LoadAnimator("Nightmares/nightmare"); + animator.Play(animationId); + + Sprite = new CSprite(EntityPosition); + + if (hittable) + { + var hittableBox = new CBox(EntityPosition, -6, -6, 12, 12, 8); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, nightmare.HitTail)); + } + + AddComponent(BaseAnimationComponent.Index, new AnimationComponent(animator, Sprite, Vector2.Zero)); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossFinalBossWeapon.cs b/InGame/GameObjects/Bosses/BossFinalBossWeapon.cs new file mode 100644 index 0000000..5abfc86 --- /dev/null +++ b/InGame/GameObjects/Bosses/BossFinalBossWeapon.cs @@ -0,0 +1,145 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Map; +using ProjectZ.Base; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + class BossFinalBossWeapon : GameObject + { + private readonly BossFinalBoss _owner; + + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly CSprite _sprite; + + private float _soundCounter; + + public BossFinalBossWeapon(Map.Map map, BossFinalBoss owner, int posX, int posY, int dir) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(-28, -28, 56, 56); + + _owner = owner; + + _animator = AnimatorSaveLoad.LoadAnimator("Nightmares/nightmare ganon weapon"); + _animator.Play("throw_" + dir); + + _sprite = new CSprite(EntityPosition); + var animatorComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -5, -4, 10, 8, 8) + { + IgnoresZ = true, + IgnoreHoles = true, + CollisionTypes = Values.CollisionTypes.None + }; + + _aiComponent = new AiComponent(); + + var stateForward = new AiState(UpdateForward) { Init = InitForward }; + stateForward.Trigger.Add(new AiTriggerCountdown(1000, null, () => _aiComponent.ChangeState("backward"))); + var stateBackward = new AiState(UpdateBackward) { Init = InitBackward }; + + _aiComponent.States.Add("forward", stateForward); + _aiComponent.States.Add("backward", stateBackward); + + _aiComponent.ChangeState("forward"); + + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(BaseAnimationComponent.Index, animatorComponent); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBottom, EntityPosition)); + } + + private void InitForward() + { + var direction = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (direction != Vector2.Zero) + { + direction.Normalize(); + _body.VelocityTarget = direction * 1.25f; + } + } + + private void UpdateForward() + { + + } + + private void InitBackward() + { + + } + + private void UpdateBackward() + { + var direction = new Vector2(_owner.EntityPosition.X, _owner.EntityPosition.Y - 24) - EntityPosition.Position; + + if (direction.Length() < 4) + { + _owner.CatchWeapon(); + Despawn(); + return; + } + + if (direction != Vector2.Zero) + direction.Normalize(); + + _body.VelocityTarget = AnimationHelper.MoveToTarget(_body.VelocityTarget, direction * 1.25f, 0.075f * Game1.TimeMultiplier); + } + + private void Update() + { + _soundCounter -= Game1.DeltaTime; + if (_soundCounter < 0) + { + _soundCounter += 250; + Game1.GameManager.PlaySoundEffect("D378-58-3A"); + } + + var rectangle = _animator.CollisionRectangle; + + // collider is mirrored because the animation only supports one collider + var collisionBox0 = new Box(EntityPosition.X + rectangle.X, EntityPosition.Y + rectangle.Y, 0, rectangle.Width, rectangle.Height, 8); + var collisionBox1 = new Box(EntityPosition.X - rectangle.X - rectangle.Width, + EntityPosition.Y - rectangle.Y - rectangle.Height, 0, rectangle.Width, rectangle.Height, 8); + + // hit the player + if (collisionBox0.Intersects(MapManager.ObjLink._body.BodyBox.Box)) + MapManager.ObjLink.HitPlayer(collisionBox0, HitType.Enemy, 1); + if (collisionBox1.Intersects(MapManager.ObjLink._body.BodyBox.Box)) + MapManager.ObjLink.HitPlayer(collisionBox1, HitType.Enemy, 1); + } + + private void Draw(SpriteBatch spriteBatch) + { + _sprite.Draw(spriteBatch); + + return; + + var rectangle = _animator.CollisionRectangle; + + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + (int)EntityPosition.Position.X + rectangle.X, (int)EntityPosition.Position.Y + rectangle.Y, rectangle.Width, rectangle.Height), Color.White * 0.5f); + + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + (int)EntityPosition.Position.X - rectangle.X - rectangle.Width, (int)EntityPosition.Position.Y - rectangle.Y - rectangle.Height, rectangle.Width, rectangle.Height), Color.White * 0.5f); + } + + private void Despawn() + { + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossGenie.cs b/InGame/GameObjects/Bosses/BossGenie.cs new file mode 100644 index 0000000..d8a9059 --- /dev/null +++ b/InGame/GameObjects/Bosses/BossGenie.cs @@ -0,0 +1,492 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + class BossGenie : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly DamageFieldComponent _damageField; + private readonly AiDamageState _damageState; + private readonly ShadowBodyDrawComponent _shadowComponent; + + private readonly BossGenieBottle _objBottle; + + private readonly Animator _smokeBottom; + private readonly Animator _smokeTop; + + private readonly Animator _bodyAnimator; + private readonly Animator _tailAnimator; + + private readonly CSprite _sprite; + + private readonly string _saveKey; + + private const float FollowSpeed = 1.5f; + private const int AttackTime = 10000; + private const int RotateTime = 2100; + private const int Lives = 8; + + private Vector2 _spawnPosition; + private readonly Vector2 _roomCenter; + + private BossGenieFireball[] _fireballs; + private int _fireballCount; + private int _fireballIndex; + + private bool _isVisible; + + private const int RotationOffsetY = 38; + private float _currentRotation; + private float _rotationDistance; + + private Vector2 _smokePosition0; + private Vector2 _smokePosition1; + private float _spawnCounter; + private bool _drawSmoke; + private bool _attackMode; + + public BossGenie(Map.Map map, string saveKey, Vector3 position, BossGenieBottle objBottle) : base(map) + { + _saveKey = saveKey; + + _objBottle = objBottle; + + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(position.X, position.Y, position.Z); + EntitySize = new Rectangle(-20, -80, 40, 80); + + _roomCenter = Map.GetRoomCenter(position.X, position.Y); + + _bodyAnimator = AnimatorSaveLoad.LoadAnimator("Nightmares/genie"); + _bodyAnimator.Play("idle"); + + _tailAnimator = AnimatorSaveLoad.LoadAnimator("Nightmares/genie"); + _tailAnimator.Play("tail"); + + _smokeTop = AnimatorSaveLoad.LoadAnimator("Nightmares/genie smoke"); + _smokeBottom = AnimatorSaveLoad.LoadAnimator("Nightmares/genie smoke"); + + _sprite = new CSprite(EntityPosition); + + _body = new BodyComponent(EntityPosition, -5, -10, 10, 10, 8) + { + IgnoresZ = true, + CollisionTypes = Values.CollisionTypes.None + }; + + var hittableBox = new CBox(EntityPosition, -15, -38, 0, 30, 26, 8, true); + var damageCollider = new CBox(EntityPosition, -15, -38, 0, 30, 30, 8, true); + + var stateIdle = new AiState(); + var stateSpawn = new AiState(UpdateSpawn) { Init = InitSpawn }; + var stateSpawnDelay = new AiState(); + stateSpawnDelay.Trigger.Add(new AiTriggerCountdown(1000, null, SpawnDelayEnd)); + var stateDespawn = new AiState(UpdateDespawn) { Init = InitDespawn }; + var stateAttack = new AiState { Init = InitAttack }; + stateAttack.Trigger.Add(new AiTriggerCountdown(AttackTime, AttackTick, AttackEnd)); + var stateFollow = new AiState(UpdateFollow) { Init = InitFollow }; + var stateRotate = new AiState { Init = InitRotation }; + stateRotate.Trigger.Add(new AiTriggerCountdown(RotateTime, RotateTick, RotateEnd)); + + _aiComponent = new AiComponent(); + + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("spawn", stateSpawn); + _aiComponent.States.Add("spawnDelay", stateSpawnDelay); + _aiComponent.States.Add("despawn", stateDespawn); + _aiComponent.States.Add("attack", stateAttack); + _aiComponent.States.Add("follow", stateFollow); + _aiComponent.States.Add("rotate", stateRotate); + _damageState = new AiDamageState(this, _body, _aiComponent, _sprite, Lives, true, false); + _damageState.AddBossDamageState(OnDeath); + _damageState.ExplosionOffsetY = -8; + _damageState.BossHitSound = true; + + _aiComponent.ChangeState("idle"); + + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageCollider, HitType.Enemy, 4) { IsActive = false }); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + AddComponent(DrawShadowComponent.Index, _shadowComponent = new ShadowBodyDrawComponent(EntityPosition) { ShadowWidth = 18, ShadowHeight = 6 }); + } + + public void Spawn(Vector3 position) + { + EntityPosition.Set(position); + + _aiComponent.ChangeState("spawn"); + + _spawnPosition = new Vector2(position.X, position.Y); + } + + public void AttackSpawn(Vector3 position) + { + EntityPosition.Set(position); + _aiComponent.ChangeState("spawn"); + + // do not start at the beginning + _smokeTop.SetFrame(3); + _spawnCounter = 600; + UpdateSpawn(); + _attackMode = true; + } + + private void SpawnDelayEnd() + { + if (_attackMode) + { + Game1.GameManager.StartDialogPath("d2_boss_3"); + _aiComponent.ChangeState("follow"); + } + else + { + Game1.GameManager.StartDialogPath("d2_boss_1"); + _aiComponent.ChangeState("attack"); + } + } + + private void InitDespawn() + { + _damageField.IsActive = false; + _smokePosition0 = new Vector2(EntityPosition.X, EntityPosition.Y - 54); + _smokePosition1 = new Vector2(EntityPosition.X, EntityPosition.Y - 54); + _smokeTop.Play("despawn"); + _spawnCounter = _smokeTop.GetAnimationTime(); + + Game1.GameManager.PlaySoundEffect("D360-31-1F"); + + _drawSmoke = true; + } + + private void UpdateDespawn() + { + _spawnCounter -= Game1.DeltaTime; + UpdateSmoke(_spawnCounter); + + if (!_smokeTop.IsPlaying) + DespawnEnd(); + + // despawn the genie + if (_smokeTop.CurrentFrameIndex > 0) + _isVisible = false; + } + + private void DespawnEnd() + { + _drawSmoke = false; + _shadowComponent.IsActive = false; + _aiComponent.ChangeState("idle"); + _objBottle.StartFollowing(); + } + + private void InitSpawn() + { + _spawnCounter = 0; + _smokePosition0 = new Vector2(EntityPosition.X, EntityPosition.Y - 29); + _smokePosition1 = new Vector2(EntityPosition.X, EntityPosition.Y - 29); + _smokeTop.Play("top"); + + Game1.GameManager.PlaySoundEffect("D360-06-06"); + + _shadowComponent.IsActive = true; + _drawSmoke = true; + } + + private void UpdateSpawn() + { + _spawnCounter += Game1.DeltaTime; + UpdateSmoke(_spawnCounter); + + if (!_smokeTop.IsPlaying) + SpawnEnd(); + + // spawn the genie + if (_smokeTop.CurrentFrameIndex == 6) + _isVisible = true; + } + + private void SpawnEnd() + { + _damageField.IsActive = true; + _drawSmoke = false; + _aiComponent.ChangeState("spawnDelay"); + } + + private void UpdateSmoke(float state) + { + _smokeBottom.Update(); + _smokeTop.Update(); + + if (330 < _spawnCounter && _spawnCounter < 600) + { + _smokeBottom.Play("bottom"); + _smokePosition1.Y = EntityPosition.Y - 29 - ((_spawnCounter - 330) / 600f) * 25; + } + else + { + _smokeBottom.Stop(); + } + + var movePercentage = MathF.Sin(_spawnCounter / 600f * MathF.PI / 3) / MathF.Sin(MathF.PI / 3); + + // move up + if (_spawnCounter < 600) + _smokePosition0.Y = EntityPosition.Y - 29 - movePercentage * 25; + else + _smokePosition0.Y = EntityPosition.Y - 54; + } + + private void InitFollow() + { + _bodyAnimator.Play("attack"); + } + + private void UpdateFollow() + { + // fly towards the player + var playerDirection = MapManager.ObjLink.EntityPosition.Position - new Vector2(EntityPosition.X, EntityPosition.Y - EntityPosition.Z - 8); + if (playerDirection != Vector2.Zero) + { + playerDirection.Normalize(); + // have momentum and not directly change the direction + var percentage = (float)Math.Pow(0.98, Game1.TimeMultiplier); + _body.VelocityTarget = percentage * _body.VelocityTarget + (1 - percentage) * playerDirection * FollowSpeed; + } + } + + private void InitRotation() + { + _shadowComponent.IsActive = false; + _damageField.IsActive = false; + _body.VelocityTarget = Vector2.Zero; + var centerOffset = new Vector2(EntityPosition.Position.X, EntityPosition.Position.Y - RotationOffsetY) - _roomCenter; + _currentRotation = MathF.Atan2(centerOffset.Y, centerOffset.X); + _rotationDistance = centerOffset.Length(); + } + + private void RotateTick(double counter) + { + // do not get to close the mirrored version + if (_rotationDistance > 4) + _rotationDistance -= Game1.TimeMultiplier * MathHelper.Clamp(_rotationDistance / 100, 0, 0.3f); + + // move the same distance each frame independent of how far we are away from the rotation origin + var rotationSpeed = MathHelper.Clamp(_rotationDistance, 0, 6); + _currentRotation += rotationSpeed / (_rotationDistance * MathF.PI) * Game1.TimeMultiplier; + + var newPosition = new Vector2(_roomCenter.X, _roomCenter.Y + RotationOffsetY) + new Vector2(MathF.Cos(_currentRotation), MathF.Sin(_currentRotation)) * _rotationDistance; + EntityPosition.Set(newPosition); + } + + private void RotateEnd() + { + _shadowComponent.IsActive = true; + _damageField.IsActive = true; + + // throw fireball + var fireball = new BossGenieFireball(Map, EntityPosition.ToVector3()); + Map.Objects.SpawnObject(fireball); + + // spawn the ball on the left or right side + if (MapManager.ObjLink.EntityPosition.X < EntityPosition.X) + _fireballIndex = 0; + else + _fireballIndex = 1; + + ThrowFireball(fireball); + + _aiComponent.ChangeState("follow"); + } + + private void InitAttack() + { + _fireballIndex = 0; + _fireballCount = 8; + _fireballs = new BossGenieFireball[_fireballCount]; + for (var i = 0; i < _fireballCount; i++) + { + // spawn behind the genie for the initial frame + _fireballs[i] = new BossGenieFireball(Map, new Vector3(EntityPosition.X, EntityPosition.Y - 1, EntityPosition.Z + 12)); + Map.Objects.SpawnObject(_fireballs[i]); + } + } + + private void AttackTick(double counter) + { + var state = (float)((AttackTime - counter) / AttackTime); + + for (var i = _fireballIndex; i < _fireballCount; i++) + { + // 5 fireballs form a full circle + var circleCount = 5; + var fullTurns = 7; + var radiant = (state * MathF.PI * 2 * fullTurns + i * 2 * (2 * MathF.PI) / 5); + + var newPosition = new Vector3(EntityPosition.X - MathF.Sin(radiant) * 12, EntityPosition.Y - 1, EntityPosition.Z + 30 - MathF.Cos(radiant) * 15); + _fireballs[i].SetPosition(newPosition); + + // throw fireball at the time where the ball is behind the genie + if (state > 2f / fullTurns + (_fireballIndex * (3 / (float)circleCount)) * (1 / (float)fullTurns)) + { + ThrowFireball(); + } + } + + // move the genie left/right and up/down + var moveState = state * MathF.PI * 2 * 2; + var offsetX = MathF.Sin(moveState) * 27; + var offsetY = MathF.Sin(moveState * 7) * 4; + EntityPosition.Set(new Vector2(_spawnPosition.X + offsetX, _spawnPosition.Y + offsetY)); + } + + private void ThrowFireball() + { + ThrowFireball(_fireballs[_fireballIndex]); + _bodyAnimator.Play(_fireballIndex % 2 == 0 ? "attack_0" : "attack_1"); + _fireballIndex++; + } + + private void ThrowFireball(BossGenieFireball fireball) + { + fireball.EntityPosition.Set(new Vector3( + EntityPosition.X + (_fireballIndex % 2 == 0 ? -15 : 15), EntityPosition.Y, EntityPosition.Z + 30)); + + // throw the fireball in the direction of the player + var playerDirection = MapManager.ObjLink.EntityPosition.ToVector3() - + fireball.EntityPosition.ToVector3(); + if (playerDirection != Vector3.Zero) + { + playerDirection.Normalize(); + playerDirection *= 2.25f; + } + + fireball.ThrowFireball(playerDirection); + + Game1.GameManager.PlaySoundEffect("D378-40-28"); + } + + private void AttackEnd() + { + _aiComponent.ChangeState("despawn"); + } + + private void Update() + { + _bodyAnimator.Update(); + _tailAnimator.Update(); + } + + private void Draw(SpriteBatch spriteBatch) + { + if (_isVisible) + { + var color = Color.White; + + // change the draw effect + if (_sprite.SpriteShader != null) + { + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, _sprite.SpriteShader); + } + + if (_aiComponent.CurrentStateId == "rotate") + { + color *= 0.5f; + + var drawPosition = new Vector2(EntityPosition.Position.X, EntityPosition.Position.Y); + var centerOffset = drawPosition - new Vector2(_roomCenter.X, _roomCenter.Y + RotationOffsetY); + var newPosition = drawPosition - centerOffset * 2 + new Vector2(0, -EntityPosition.Z); + + // draw the body + _bodyAnimator.Draw(spriteBatch, newPosition, color); + // draw the tail + _tailAnimator.Draw(spriteBatch, newPosition, color); + } + + // draw the body + _bodyAnimator.Draw(spriteBatch, new Vector2(EntityPosition.X, EntityPosition.Y - EntityPosition.Z), color); + // draw the tail + _tailAnimator.Draw(spriteBatch, new Vector2(EntityPosition.X, EntityPosition.Y - EntityPosition.Z), color); + + // change the draw effect + if (_sprite.SpriteShader != null) + { + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, null); + } + } + + // draw the smoke while spawning/despawning + if (_drawSmoke) + DrawSpawn(spriteBatch); + } + + private void DrawSpawn(SpriteBatch spriteBatch) + { + if (_smokeTop.IsPlaying) + _smokeTop.Draw(spriteBatch, _smokePosition0, Color.White); + if (_smokeBottom.IsPlaying) + _smokeBottom.Draw(spriteBatch, _smokePosition1, Color.White); + } + + private void OnDeath() + { + if (!string.IsNullOrEmpty(_saveKey)) + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + // stop boss music + Game1.GameManager.SetMusic(-1, 2); + + var heartPosition = new Vector2(EntityPosition.X, EntityPosition.Y - EntityPosition.Z); + var centerDistance = heartPosition - _roomCenter; + centerDistance.X = MathHelper.Clamp(centerDistance.X, -56, 56); + centerDistance.Y = MathHelper.Clamp(centerDistance.Y, -24, 54); + + heartPosition = _roomCenter + centerDistance; + + // spawn big heart + Map.Objects.SpawnObject(new ObjItem(Map, + (int)heartPosition.X - 8, (int)heartPosition.Y - 16, "j", "d2_nHeart", "heartMeterFull", null)); + + // remove the boss from the map + Map.Objects.DeleteObjects.Add(this); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + // can only get attacked in the follow state + if (_aiComponent.CurrentStateId != "follow" || + _damageState.IsInDamageState() || + damageType == HitType.MagicPowder) + return Values.HitCollision.None; + + _aiComponent.ChangeState("rotate"); + + if (damageType == HitType.Bomb) + damage *= 2; + + var damageReturn = _damageState.OnHit(MapManager.ObjLink, direction, HitType.ThrownObject, damage, pieceOfPower); + + // stop if we are dead + if (_damageState.CurrentLives <= 0) + _body.VelocityTarget = Vector2.Zero; + + return damageReturn; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossGenieBottle.cs b/InGame/GameObjects/Bosses/BossGenieBottle.cs new file mode 100644 index 0000000..de5f834 --- /dev/null +++ b/InGame/GameObjects/Bosses/BossGenieBottle.cs @@ -0,0 +1,375 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + class BossGenieBottle : GameObject + { + private readonly BossGenie _objGenie; + + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly DamageFieldComponent _damageField; + private readonly AiTriggerSwitch _aiDamageSwitch; + private readonly BoxCollisionComponent _collisionComponent; + private readonly AnimationComponent _animationComponent; + private readonly CarriableComponent _carriableComponent; + private readonly AiDamageState _damageState; + + private readonly Vector2 _spawnTargetPosition; + + private const float SpawnMoveSpeed = 0.5f; + private const float FollowSpeed = 0.75f; + private const int Lives = 3; + + private bool _showedStunnedMessage; + + public BossGenieBottle() : base("genie") { } + + public BossGenieBottle(Map.Map map, int posX, int posY, string saveKey) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -32, 16, 32); + + _spawnTargetPosition = new Vector2(EntityPosition.X, EntityPosition.Y + 24); + + if (!string.IsNullOrWhiteSpace(saveKey) && Game1.GameManager.SaveManager.GetString(saveKey) == "1") + { + // respawn the heart if the player died after he killed the boss without collecting the heart + SpawnHeart(); + + IsDead = true; + return; + } + + // add the genie to the map + _objGenie = new BossGenie(map, saveKey, new Vector3(EntityPosition.X, EntityPosition.Y, 0), this); + map.Objects.SpawnObject(_objGenie); + + _animator = AnimatorSaveLoad.LoadAnimator("Nightmares/genie bottle"); + _animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + + _animationComponent = new AnimationComponent(_animator, sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -5, -10, 10, 10, 8) + { + CollisionTypes = Values.CollisionTypes.Normal, + Bounciness = 0.0f, + Gravity = -0.15f, + Drag = 0.65f, + DragAir = 1.0f, + MoveCollision = OnCollision, + FieldRectangle = Map.GetField(posX, posY, 16) + }; + + var hittableBox = new CBox(EntityPosition, -8, -16, 0, 16, 16, 8, true); + var pushableBox = new CBox(EntityPosition, -8, -16, 0, 16, 16, 8, true); + var damageCollider = new CBox(EntityPosition, -7, -14, 14, 14, 8); + var carryRectangle = new CRectangle(EntityPosition, new Rectangle(-8, -16, 16, 16)); + + var stateIdle = new AiState(UpdateIdle); + var stateTriggered = new AiState(); + stateTriggered.Trigger.Add(new AiTriggerCountdown(500, null, () => _aiComponent.ChangeState("spawn"))); + var stateSpawn = new AiState(UpdateSpawn) { Init = InitSpawn }; + var stateSpawnDelay = new AiState { Init = InitSpawnDelay }; + stateSpawnDelay.Trigger.Add(new AiTriggerCountdown(3300, null, EndSpawnDelay)); + var stateReturnDelay = new AiState(); + stateReturnDelay.Trigger.Add(new AiTriggerCountdown(800, null, EndSpawnDelay)); + var stateSpawned = new AiState(); + var stateFollow = new AiState(UpdateFollow) { Init = InitFollow }; + var stateStunned = new AiState(UpdateStunned); + stateStunned.Trigger.Add(new AiTriggerCountdown(2500, null, () => _aiComponent.ChangeState("shaking"))); + var stateShaking = new AiState(); + stateShaking.Trigger.Add(new AiTriggerCountdown(600, TickShake, ShakeEnd)); + var stateGrabbed = new AiState(); + var stateReturn = new AiState(UpdateReturn) { Init = InitReturn }; + var stateThrown = new AiState(UpdateThrown); + + _aiComponent = new AiComponent(); + _aiComponent.Trigger.Add(_aiDamageSwitch = new AiTriggerSwitch(500)); + + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("triggered", stateTriggered); + _aiComponent.States.Add("spawn", stateSpawn); + _aiComponent.States.Add("spawnDelay", stateSpawnDelay); + _aiComponent.States.Add("returnDelay", stateReturnDelay); + _aiComponent.States.Add("spawned", stateSpawned); + _aiComponent.States.Add("follow", stateFollow); + _aiComponent.States.Add("stunned", stateStunned); + _aiComponent.States.Add("shaking", stateShaking); + _aiComponent.States.Add("grabbed", stateGrabbed); + _aiComponent.States.Add("return", stateReturn); + _aiComponent.States.Add("thrown", stateThrown); + _damageState = new AiDamageState(this, _body, _aiComponent, sprite, Lives) { MoveBody = false, OnDeath = OnDeath, BossHitSound = true }; + + _aiComponent.ChangeState("idle"); + + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageCollider, HitType.Enemy, 2) { IsActive = false }); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(CarriableComponent.Index, _carriableComponent = new CarriableComponent(carryRectangle, CarryInit, CarryUpdate, CarryThrow) { IsActive = false }); + AddComponent(BaseAnimationComponent.Index, _animationComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(CollisionComponent.Index, _collisionComponent = new BoxCollisionComponent(pushableBox, Values.CollisionTypes.Enemy) { IsActive = false }); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite) { ShadowWidth = 12, ShadowHeight = 6 }); + } + + private void UpdateIdle() + { + // player entered the room? + if (_body.FieldRectangle.Contains(MapManager.ObjLink.BodyRectangle)) + { + Game1.GameManager.StartDialogPath("d2_boss"); + _aiComponent.ChangeState("triggered"); + } + } + + private void UpdateStunned() + { + // show the message one time + if (_body.IsGrounded && !_showedStunnedMessage) + { + _showedStunnedMessage = true; + Game1.GameManager.StartDialogPath("d2_boss_2"); + } + } + + private void OnDeath(bool pieceOfPower) + { + // spawn the genie + _objGenie.AttackSpawn(new Vector3(EntityPosition.X, EntityPosition.Y + 38, 27)); + + // remove the bottle from the map + Map.Objects.DeleteObjects.Add(this); + + Game1.GameManager.PlaySoundEffect("D378-41-29"); + } + + public void StartFollowing() + { + _aiComponent.ChangeState("follow"); + } + + private void EndSpawnDelay() + { + // spawn the genie + _objGenie.Spawn(new Vector3(EntityPosition.X, EntityPosition.Y + 1, 27)); + _aiComponent.ChangeState("spawned"); + } + + private void InitSpawnDelay() + { + _collisionComponent.IsActive = true; + } + + private void InitReturn() + { + _animator.Play("wobble"); + // make sure to not get blocked by the lamps + _body.CollisionTypes = Values.CollisionTypes.None; + } + + private void UpdateReturn() + { + var direction = _spawnTargetPosition - EntityPosition.Position; + if (!MoveTowards(direction)) + { + _body.CollisionTypes = Values.CollisionTypes.Normal; + _aiComponent.ChangeState("returnDelay"); + } + } + + private Vector3 CarryInit() + { + _aiComponent.ChangeState("grabbed"); + + _carriableComponent.IsActive = false; + _body.IsActive = false; + + return new Vector3(EntityPosition.X, EntityPosition.Y, EntityPosition.Z); + } + + private bool CarryUpdate(Vector3 newPosition) + { + EntityPosition.Set(newPosition); + return true; + } + + private void CarryThrow(Vector2 velocity) + { + _aiComponent.ChangeState("thrown"); + _body.Bounciness = 0.65f; + _body.DragAir = 0.99f; + _body.IsGrounded = false; + _body.JumpStartHeight = 0; + _body.IsActive = true; + _body.Velocity = new Vector3(velocity.X, velocity.Y, 0) * 0.85f; + } + + private void UpdateThrown() + { + // stopped without hitting a wall? + if (_body.Velocity.Length() < 0.1f) + { + _aiComponent.ChangeState("return"); + } + } + + private void InitSpawn() + { + _animator.Play("wobble"); + } + + private void UpdateSpawn() + { + var direction = _spawnTargetPosition - EntityPosition.Position; + + if (!MoveTowards(direction)) + _aiComponent.ChangeState("spawnDelay"); + } + + private bool MoveTowards(Vector2 direction) + { + // jump + if (_body.IsGrounded) + { + _body.Velocity.Z = 1.25f; + Game1.GameManager.PlaySoundEffect("D360-32-20"); + } + + // move towards the target position + if (direction.Length() > SpawnMoveSpeed * Game1.TimeMultiplier) + { + direction.Normalize(); + _body.VelocityTarget = direction * SpawnMoveSpeed; + } + else + { + EntityPosition.Set(_spawnTargetPosition); + _body.VelocityTarget = Vector2.Zero; + return false; + } + + return true; + } + + private void InitFollow() + { + _collisionComponent.IsActive = false; + _damageField.IsActive = true; + _animator.Play("wobble"); + } + + private void UpdateFollow() + { + if (!_body.IsGrounded || _body.Velocity.Z > 0) + return; + + _body.Velocity.X = 0; + _body.Velocity.Y = 0; + + // jump + _body.Velocity.Z = 1.25f; + + Game1.GameManager.PlaySoundEffect("D360-32-20"); + + // follow the player + var direction = MapManager.ObjLink.EntityPosition.Position - new Vector2(EntityPosition.X, EntityPosition.Y - 4); + if (direction != Vector2.Zero) + { + direction.Normalize(); + _body.VelocityTarget = direction * FollowSpeed; + } + } + + private void ToStun(Vector2 velocity) + { + _carriableComponent.IsActive = true; + _damageField.IsActive = false; + _body.Bounciness = 0f; + _body.VelocityTarget = Vector2.Zero; + _body.Velocity = new Vector3(velocity.X, velocity.Y, 2); + _collisionComponent.IsActive = true; + _animator.Play("idle"); + _aiComponent.ChangeState("stunned"); + } + + private void TickShake(double time) + { + _animationComponent.SpriteOffset.X = (float)Math.Sin(time / 25f); + _animationComponent.UpdateSprite(); + } + + private void ShakeEnd() + { + _animationComponent.SpriteOffset.X = 0; + _animationComponent.UpdateSprite(); + _carriableComponent.IsActive = false; + _aiComponent.ChangeState("follow"); + } + + private void SpawnHeart() + { + // spawn big heart + Map.Objects.SpawnObject(new ObjItem(Map, (int)EntityPosition.X - 8, (int)EntityPosition.Y, "", "d2_nHeart", "heartMeterFull", null)); + } + + private void OnCollision(Values.BodyCollision collision) + { + if (_aiComponent.CurrentStateId == "thrown" && + (collision & (Values.BodyCollision.Horizontal | Values.BodyCollision.Vertical)) != 0) + { + _aiComponent.ChangeState("return"); + _damageState.OnHit(MapManager.ObjLink, Vector2.Zero, HitType.ThrownObject, 1, false); + + _body.Velocity.X = -_body.Velocity.X * 0.2f; + _body.Velocity.Y = -_body.Velocity.Y * 0.2f; + _body.Bounciness = 0.5f; + } + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_aiComponent.CurrentStateId == "follow") + { + _aiDamageSwitch.Reset(); + ToStun(direction * 0.75f); + return Values.HitCollision.RepellingParticle; + } + + if (_aiDamageSwitch.State) + return Values.HitCollision.RepellingParticle; + + return Values.HitCollision.None; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type != PushableComponent.PushType.Impact) + return false; + + if (_aiComponent.CurrentStateId == "follow") + { + _body.Velocity = new Vector3(direction.X, direction.Y, 1); + _body.Bounciness = 0.0f; + } + + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossGenieFireball.cs b/InGame/GameObjects/Bosses/BossGenieFireball.cs new file mode 100644 index 0000000..7faace3 --- /dev/null +++ b/InGame/GameObjects/Bosses/BossGenieFireball.cs @@ -0,0 +1,54 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + internal class BossGenieFireball : GameObject + { + private readonly BodyComponent _body; + + public BossGenieFireball(Map.Map map, Vector3 position) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(position); + EntitySize = new Rectangle(-7, -64, 14, 64); + + var sprite = new CSprite("fireball", EntityPosition, new Vector2(-7, -16)); + + _body = new BodyComponent(EntityPosition, -5, -10, 10, 10, 8) + { + IgnoresZ = true, + DragAir = 1.0f, + Gravity = 0.0f, + CollisionTypes = Values.CollisionTypes.None, + MoveCollision = OnCollision, + }; + + var damageCollider = new CBox(EntityPosition, -6, -12, 0, 12, 12, 8, true); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 4)); + AddComponent(BodyComponent.Index, _body); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite)); + } + + public void ThrowFireball(Vector3 velocity) + { + _body.IgnoresZ = false; + _body.Velocity = velocity; + } + + public void SetPosition(Vector3 newPosition) + { + EntityPosition.Set(newPosition); + } + + private void OnCollision(Values.BodyCollision collision) + { + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossHardhitBeetle.cs b/InGame/GameObjects/Bosses/BossHardhitBeetle.cs new file mode 100644 index 0000000..06c5747 --- /dev/null +++ b/InGame/GameObjects/Bosses/BossHardhitBeetle.cs @@ -0,0 +1,289 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Dungeon; +using ProjectZ.InGame.GameObjects.Enemies; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + class BossHardhitBeetle : GameObject + { + private readonly Animator _animator; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _aiDamageState; + private readonly CSprite _sprite; + private readonly AiTriggerCountdown _hitCooldown; + private readonly AiTriggerCountdown _colorCountdown; + private readonly DamageFieldComponent _damageField; + + private EnemyStalfosGreen[] _stalfos = new EnemyStalfosGreen[2]; + + private readonly Color[] _colors = { + new Color(42, 41, 254), + new Color(0, 149, 114), + new Color(34, 212, 16), + new Color(141, 206, 9), + new Color(254, 198, 1), + new Color(253, 131, 0), + new Color(255, 66, 1), + new Color(253, 0, 0) + }; + + private readonly string _saveKey; + + // small delay before starting to walk + private float _idleDelayCounter = 250; + + private const int CooldownTime = 250; + private const float MoveSpeed = 0.375f; + private int _colorIndex; + + private bool _isDead; + + private float _stalfosCounter; + private bool _spawnedStalfos; + + public BossHardhitBeetle() : base("hardhit beetle") { } + + public BossHardhitBeetle(Map.Map map, int posX, int posY, string saveKey) : base(map) + { + EntityPosition = new CPosition(posX + 16, posY + 32, 0); + EntitySize = new Rectangle(-16, -40, 32, 40); + + _saveKey = saveKey; + + // was already killed? + if (!string.IsNullOrEmpty(_saveKey) && + Game1.GameManager.SaveManager.GetString(_saveKey) == "1") + { + IsDead = true; + return; + } + + _animator = AnimatorSaveLoad.LoadAnimator("Nightmares/hardhit beetle"); + _animator.Play("idle"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -14, -26, 28, 26, 8) + { + Gravity = -0.1f, + FieldRectangle = Map.GetField(posX, posY, 16) + }; + + var stateIdle = new AiState(UpdateIdle); + var stateIdleDelay = new AiState(UpdateIdleDelay); + var stateWalk = new AiState(UpdateWalk) { Init = InitWalk }; + stateWalk.Trigger.Add(new AiTriggerRandomTime(EndWalk, 500, 1000)); + + _aiComponent = new AiComponent(); + _aiComponent.Trigger.Add(new AiTriggerRandomTime(Shoot, 750, 2500)); + _aiComponent.Trigger.Add(_colorCountdown = new AiTriggerCountdown(2000, null, OnColorReset)); + _aiComponent.Trigger.Add(_hitCooldown = new AiTriggerCountdown(CooldownTime, TickCooldown, null)); + + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("idleDelay", stateIdleDelay); + _aiComponent.States.Add("walk", stateWalk); + _aiDamageState = new AiDamageState(this, _body, _aiComponent, _sprite, 1) + { + HitMultiplierX = 0, + HitMultiplierY = 0, + BossHitSound = true + }; + _aiDamageState.DamageSpriteShader = Resources.DamageSpriteShader1; + _aiDamageState.AddBossDamageState(OnDeathAnimationEnd); + + _aiComponent.ChangeState("idle"); + + var damageBox = new CBox(EntityPosition, -14, -24, 0, 28, 24, 8); + var hittableBox = new CBox(EntityPosition, -13, -34, 0, 26, 30, 8); + + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageBox, HitType.Enemy, 4)); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _sprite)); + } + + private void UpdateIdle() + { + // player enters the room? + if (_body.FieldRectangle.Contains(MapManager.ObjLink.BodyRectangle)) + { + Game1.GameManager.StartDialogPath("hardhit_beetle_enter"); + _aiComponent.ChangeState("idleDelay"); + } + } + + private void UpdateIdleDelay() + { + if (Game1.GameManager.DialogIsRunning()) + return; + + _idleDelayCounter -= Game1.DeltaTime; + if (0 < _idleDelayCounter) + return; + + _aiComponent.ChangeState("walk"); + } + + private void TickCooldown(double counter) + { + _sprite.SpriteShader = (CooldownTime - counter) <= 4200 / 60f ? Resources.DamageSpriteShader0 : null; + } + + private void OffsetColor(int offset) + { + _colorIndex = MathHelper.Clamp(_colorIndex + offset, 0, _colors.Length - 1); + + if (_colorIndex == 0) + Game1.GameManager.StartDialogPath("hardhit_beetle_1"); + + if (_colorIndex < 4) + _spawnedStalfos = false; + + // spawn stalfos? + if (!_spawnedStalfos && offset > 0 && _colorIndex >= 6) + { + Game1.GameManager.StartDialogPath("hardhit_beetle_2"); + + // spawn stalfos with a little delay + _spawnedStalfos = true; + _stalfosCounter = 250; + } + } + + private void OnColorReset() + { + OffsetColor(-1); + _colorCountdown.OnInit(); + } + + private void InitWalk() + { + var direction = Game1.RandomNumber.Next(0, 8) / 4f * MathF.PI; + _body.VelocityTarget = new Vector2(MathF.Sin(direction), MathF.Cos(direction)) * MoveSpeed; + } + + private void UpdateWalk() + { + if (!_spawnedStalfos || _stalfosCounter <= 0) + return; + + _stalfosCounter -= Game1.DeltaTime; + if (_stalfosCounter <= 0) + { + for (var i = 0; i < _stalfos.Length; i++) + { + if (_stalfos[i] != null && _stalfos[i].Map != null) + continue; + + var randomOffsetX = Game1.RandomNumber.Next(0, 13) - 6; + var randomOffsetY = Game1.RandomNumber.Next(0, 8) - 4; + + _stalfos[i] = new EnemyStalfosGreen(Map, + (int)MapManager.ObjLink.EntityPosition.X - 8 + randomOffsetX, + (int)MapManager.ObjLink.EntityPosition.Y - 15 + randomOffsetY); + _stalfos[i].SetAirPosition(32); + Map.Objects.SpawnObject(_stalfos[i]); + } + } + } + + private void Shoot() + { + if (_aiComponent.CurrentStateId != "walk") + return; + + var objShot = new BossHardhitBeetleShot(Map, new Vector2(EntityPosition.X, EntityPosition.Y - 16), 1); + Map.Objects.SpawnObject(objShot); + } + + private void EndWalk() + { + _aiComponent.ChangeState("walk"); + } + + private void Draw(SpriteBatch spriteBatch) + { + _sprite.Draw(spriteBatch); + + var sourceRectangle = _sprite.SourceRectangle; + + _sprite.SourceRectangle.X += sourceRectangle.Width + (int)(_sprite.Scale * 2); + + _sprite.Color = _colors[_colorIndex]; + _sprite.Draw(spriteBatch); + + _sprite.SourceRectangle = sourceRectangle; + _sprite.Color = Color.White; + } + + private void OnDeathAnimationEnd() + { + if (!string.IsNullOrEmpty(_saveKey)) + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + // stop boss music + Game1.GameManager.SetMusic(-1, 2); + + Game1.GameManager.PlaySoundEffect("D378-26-1A"); + + // spawns a fairy + Game1.GameManager.PlaySoundEffect("D360-27-1B"); + Map.Objects.SpawnObject(new ObjDungeonFairy(Map, (int)EntityPosition.X, (int)EntityPosition.Y, 8)); + + Map.Objects.DeleteObjects.Add(this); + } + + public Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_hitCooldown.CurrentTime > 0 || _isDead || _aiComponent.CurrentStateId == "idle") + return Values.HitCollision.None; + + _hitCooldown.OnInit(); + + if (damageType == HitType.Boomerang) + damage = 2; + + if (_colorIndex == 0) + _colorCountdown.OnInit(); + + if (_colorIndex == 7) + { + _isDead = true; + _animator.Pause(); + _damageField.IsActive = false; + _body.VelocityTarget = Vector2.Zero; + _aiDamageState.OnHit(gameObject, direction, damageType, damage, false); + } + else + { + _body.Velocity.X = direction.X; + _body.Velocity.Y = direction.Y; + Game1.GameManager.PlaySoundEffect("D370-07-07"); + } + + OffsetColor(damage); + + return Values.HitCollision.Repelling | Values.HitCollision.Repelling0; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + return true; + } + } +} diff --git a/InGame/GameObjects/Bosses/BossHardhitBeetleShot.cs b/InGame/GameObjects/Bosses/BossHardhitBeetleShot.cs new file mode 100644 index 0000000..e82b868 --- /dev/null +++ b/InGame/GameObjects/Bosses/BossHardhitBeetleShot.cs @@ -0,0 +1,73 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + internal class BossHardhitBeetleShot : GameObject + { + private readonly CSprite _sprite; + private double _liveTime = 2000; + + public BossHardhitBeetleShot(Map.Map map, Vector2 position, float speed) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(position.X, position.Y, 0); + EntitySize = new Rectangle(-8, -8, 16, 16); + + var animator = AnimatorSaveLoad.LoadAnimator("Nightmares/hardhit beetle shot"); + animator.Play("idle"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(animator, _sprite, Vector2.Zero); + + var body = new BodyComponent(EntityPosition, -5, -5, 10, 10, 8) + { + IgnoresZ = true, + IgnoreHoles = true, + CollisionTypes = Values.CollisionTypes.None + }; + + // move towards the player + var velocity = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (velocity != Vector2.Zero) + velocity.Normalize(); + body.VelocityTarget = velocity * speed; + + var hittableBox = new CBox(EntityPosition, -6, -6, 0, 12, 12, 8); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(hittableBox, HitType.Enemy, 2)); + AddComponent(BodyComponent.Index, body); + AddComponent(PushableComponent.Index, new PushableComponent(body.BodyBox, OnPush)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerTop)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + } + + private void Update() + { + _liveTime -= Game1.DeltaTime; + + if (_liveTime <= 125) + _sprite.Color = Color.White * ((float)_liveTime / 125f); + + if (_liveTime < 0) + Map.Objects.DeleteObjects.Add(this); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + return Values.HitCollision.RepellingParticle; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossHotHead.cs b/InGame/GameObjects/Bosses/BossHotHead.cs new file mode 100644 index 0000000..119d928 --- /dev/null +++ b/InGame/GameObjects/Bosses/BossHotHead.cs @@ -0,0 +1,405 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.GameObjects.Enemies; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Map; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + internal class BossHotHead : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _damageState; + private readonly CSprite _sprite; + private readonly Animator _animator; + private readonly Animator _animatorFaceTrail; + private readonly AnimationComponent _animationComponent; + private readonly AiTriggerCountdown _hitMoveReset; + + private readonly Vector2 _spawnPosition; + private readonly string _saveKey; + + private const float MoveSpeed = 2f; + + private Vector2[] _facePosition = new Vector2[2]; + + private bool _damaged; + private bool _hasSpawned; + + public BossHotHead() : base("hot head") { } + + public BossHotHead(Map.Map map, int posX, int posY, string saveKey) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-16, -32, 32, 32); + + _spawnPosition = EntityPosition.Position; + _saveKey = saveKey; + + if (!string.IsNullOrEmpty(saveKey) && + Game1.GameManager.SaveManager.GetString(saveKey) == "1") + { + SpawnHeart(); + IsDead = true; + return; + } + + _animator = AnimatorSaveLoad.LoadAnimator("Nightmares/hot head"); + _animator.Play("flame"); + + _animatorFaceTrail = AnimatorSaveLoad.LoadAnimator("Nightmares/hot head"); + _animatorFaceTrail.Play("green"); + + _sprite = new CSprite(EntityPosition) { IsVisible = false }; + _animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -9, -12, 18, 12, 8) + { + Gravity = -0.075f, + FieldRectangle = map.GetField(posX, posY, 16), + MoveCollision = OnMoveCollision, + }; + + var stateIdle = new AiState(UpdateIdle); + var stateEndIdle = new AiState(); + stateEndIdle.Trigger.Add(new AiTriggerCountdown(1000, null, EndIdle)); + var stateJumping = new AiState(UpdateJumping) { Init = InitJump }; + var stateHidden = new AiState() { Init = InitHidden }; + stateHidden.Trigger.Add(new AiTriggerCountdown(500, null, () => _aiComponent.ChangeState("jumping"))); + var stateDamaged = new AiState() { Init = InitDamaged }; + stateDamaged.Trigger.Add(new AiTriggerCountdown(1000, TickDamaged, DamageEnd)); + var stateMoving = new AiState(UpdateMoving) { Init = InitMoving }; + stateMoving.Trigger.Add(new AiTriggerCountdown(100, null, UpdateFaceTrail) { ResetAfterEnd = true }); + stateMoving.Trigger.Add(_hitMoveReset = new AiTriggerCountdown(200, null, ContinueMoving, false)); + stateMoving.Trigger.Add(new AiTriggerCountdown(2500, null, FallDown)); + var stateBreaking = new AiState() { Init = InitBreaking }; + stateBreaking.Trigger.Add(new AiTriggerCountdown(1000, TickDamaged, BreakingEnd)); + var stateBroken = new AiState(); + stateBroken.Trigger.Add(new AiTriggerCountdown(1000, null, FallDown)); + var stateFrozen = new AiState() { Init = InitFrozen }; + stateFrozen.Trigger.Add(new AiTriggerCountdown(250, null, EndFreeze)); + var stateDead = new AiState(); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("endIdle", stateEndIdle); + _aiComponent.States.Add("jumping", stateJumping); + _aiComponent.States.Add("hidden", stateHidden); + _aiComponent.States.Add("damaged", stateDamaged); + _aiComponent.States.Add("moving", stateMoving); + _aiComponent.States.Add("breaking", stateBreaking); + _aiComponent.States.Add("broken", stateBroken); + _aiComponent.States.Add("freeze", stateFrozen); + _aiComponent.States.Add("dead", stateDead); + _damageState = new AiDamageState(this, _body, _aiComponent, _sprite, 20, false, false) + { + HitMultiplierX = 0, + HitMultiplierY = 0, + ExplosionOffsetY = 4, + BossHitSound = true + }; + _damageState.AddBossDamageState(OnDeath); + + _aiComponent.ChangeState("idle"); + + var drawPosition = new CPosition(EntityPosition.X, EntityPosition.Y, 0); + drawPosition.SetParent(EntityPosition, Vector2.Zero, true); + + var damageCollider = new CBox(EntityPosition, -7, -11, 0, 14, 11, 8, true); + var hittableBox = new CBox(EntityPosition, -8, -14, 0, 16, 14, 8, true); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 16)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, _animationComponent); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, drawPosition)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _sprite) { ShadowWidth = 20, ShadowHeight = 6 }); + } + + private void UpdateIdle() + { + // player entered the room? + if (_body.FieldRectangle.Contains(MapManager.ObjLink.BodyRectangle)) + { + Game1.GameManager.StartDialogPath("hot_head"); + _aiComponent.ChangeState("endIdle"); + } + } + + private void EndIdle() + { + _hasSpawned = true; + _aiComponent.ChangeState("jumping"); + } + + private void InitHidden() + { + _body.VelocityTarget = Vector2.Zero; + _sprite.IsVisible = false; + } + + private void InitJump() + { + var newPosition = new Vector2(_body.FieldRectangle.Center.X - 8, _body.FieldRectangle.Center.Y); + var dir = Game1.RandomNumber.Next(0, 2) * 2 - 1; + newPosition.X = MathF.Round(newPosition.X) - dir * Game1.RandomNumber.Next(24, 32); + newPosition.Y = MathF.Round(newPosition.Y) - 14 + Game1.RandomNumber.Next(0, 36); + EntityPosition.Set(newPosition); + + _body.VelocityTarget = new Vector2(dir * 1.35f, (Game1.RandomNumber.Next(0, 9) - 4) / 12f); + _body.Velocity.Z = 1.5f; + + _sprite.IsVisible = true; + _animator.Play(_damaged ? "damaged" : "flame"); + Game1.GameManager.PlaySoundEffect("D370-22-16"); + + SpawnSplashAnimation(); + } + + private void UpdateJumping() + { + // landed after a jump? + if (!_body.IsGrounded) + return; + + Game1.GameManager.PlaySoundEffect("D360-50-32"); + + SpawnSplashAnimation(); + SpawnSplashParticles(); + + _aiComponent.ChangeState("hidden"); + } + + private void InitFrozen() + { + _body.IsActive = false; + } + + private void EndFreeze() + { + _body.IsActive = true; + _aiComponent.ChangeState("jumping", true); + } + + private void FallDown() + { + _body.IsActive = true; + _body.IgnoresZ = false; + _body.VelocityTarget = Vector2.Zero; + _aiComponent.ChangeState("jumping", true); + } + + private void InitMoving() + { + _body.IsActive = true; + _body.IgnoresZ = true; + _body.VelocityTarget = new Vector2(1, 1); + _body.VelocityTarget.Normalize(); + _body.VelocityTarget *= MoveSpeed; + + _facePosition[0] = new Vector2(EntityPosition.X, EntityPosition.Y - EntityPosition.Z); + _facePosition[1] = new Vector2(EntityPosition.X, EntityPosition.Y - EntityPosition.Z); + } + + private void UpdateMoving() + { + Game1.GameManager.PlaySoundEffect("D378-13-0D", false); + } + + private void ContinueMoving() + { + _body.IsActive = true; + } + + private void UpdateFaceTrail() + { + _facePosition[0] = _facePosition[1]; + _facePosition[1] = new Vector2(EntityPosition.X, EntityPosition.Y - EntityPosition.Z); + } + + private void InitDamaged() + { + _body.IsActive = false; + _body.Velocity = Vector3.Zero; + _animator.Play("red"); + + Map.Objects.SpawnObject(new ObjAnimator(Map, (int)EntityPosition.X - 16, (int)(EntityPosition.Y - EntityPosition.Z - 32), Values.LayerPlayer, "Particles/spawn", "run", true)); + Map.Objects.SpawnObject(new ObjAnimator(Map, (int)EntityPosition.X, (int)(EntityPosition.Y - EntityPosition.Z - 32), Values.LayerPlayer, "Particles/spawn", "run", true)); + } + + private void TickDamaged(double counter) + { + // 2 frames to move left to right + _animationComponent.SpriteOffset.X = MathF.Sin((float)Game1.TotalGameTime / 1000f * 30 * MathF.PI) / 2f; + _animationComponent.UpdateSprite(); + } + + private void DamageEnd() + { + _animationComponent.SpriteOffset.X = 0; + _animationComponent.UpdateSprite(); + + _aiComponent.ChangeState("moving"); + } + + private void InitBreaking() + { + _body.IsActive = false; + _body.Velocity = Vector3.Zero; + } + + private void BreakingEnd() + { + _animationComponent.SpriteOffset.X = 0; + _animationComponent.UpdateSprite(); + + FaceBreak(); + } + + private void FaceBreak() + { + _damaged = true; + + Game1.GameManager.PlaySoundEffect("D378-41-29"); + + _animator.Play("damaged"); + _aiComponent.ChangeState("broken"); + + Map.Objects.SpawnObject(new BossHotHeadFace(Map, new Vector3(EntityPosition.X - 7, EntityPosition.Y, EntityPosition.Z), new Vector3(-1, 0.125f, 0.25f), "face_left")); + Map.Objects.SpawnObject(new BossHotHeadFace(Map, new Vector3(EntityPosition.X + 7, EntityPosition.Y, EntityPosition.Z), new Vector3(1, 0.125f, 0.25f), "face_right")); + } + + private void SpawnSplashAnimation() + { + var splashAnimator = new ObjAnimator(Map, 0, 0, 0, 0, Values.LayerPlayer, "Nightmares/hot head", "splash", true); + splashAnimator.EntityPosition.Set(new Vector2(EntityPosition.X, EntityPosition.Y + 0.01f)); + Map.Objects.SpawnObject(splashAnimator); + } + + private void SpawnSplashParticles() + { + var speedMult = 0.65f; + Map.Objects.SpawnObject(new BossHotHeadSplash(Map, new Vector2(EntityPosition.X - 8, EntityPosition.Y - 8), new Vector2(-1, -1) * speedMult)); + Map.Objects.SpawnObject(new BossHotHeadSplash(Map, new Vector2(EntityPosition.X - 8, EntityPosition.Y), new Vector2(-1, 1) * speedMult)); + Map.Objects.SpawnObject(new BossHotHeadSplash(Map, new Vector2(EntityPosition.X + 8, EntityPosition.Y - 8), new Vector2(1, -1) * speedMult)); + Map.Objects.SpawnObject(new BossHotHeadSplash(Map, new Vector2(EntityPosition.X + 8, EntityPosition.Y), new Vector2(1, 1) * speedMult)); + } + + private void Draw(SpriteBatch spriteBatch) + { + // is hidden? + if (!_hasSpawned) + return; + + if (_aiComponent.CurrentStateId == "moving") + for (var i = 0; i < _facePosition.Length; i++) + _animatorFaceTrail.Draw(spriteBatch, _facePosition[i], Color.White); + + _sprite.Draw(spriteBatch); + } + + private void OnDeath() + { + if (!string.IsNullOrEmpty(_saveKey)) + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + Map.Objects.DeleteObjects.Add(this); + + // spawn big heart + var spawnPosition = new Vector2((int)(MapManager.ObjLink.EntityPosition.X / 16) * 16, (int)((MapManager.ObjLink.EntityPosition.Y - 1) / 16) * 16); + // make sure to not spawn the heart over the lava + if (Map.GetFieldState(spawnPosition) != MapStates.FieldStates.None) + spawnPosition = new Vector2((int)_spawnPosition.X, (int)_spawnPosition.Y + 32); + + var objHeart = new ObjItem(Map, (int)spawnPosition.X, (int)spawnPosition.Y, "d", _saveKey + "Heart", "heartMeterFull", null); + Map.Objects.SpawnObject(objHeart); + } + + private void SpawnHeart() + { + var objHeart = new ObjItem(Map, (int)_spawnPosition.X, (int)_spawnPosition.Y + 32, "d", _saveKey + "Heart", "heartMeterFull", null); + Map.Objects.SpawnObject(objHeart); + } + + private void OnMoveCollision(Values.BodyCollision collision) + { + if (_aiComponent.CurrentStateId == "moving") + { + if ((collision & Values.BodyCollision.Horizontal) != 0) + _body.VelocityTarget.X = -_body.VelocityTarget.X; + if ((collision & Values.BodyCollision.Vertical) != 0) + _body.VelocityTarget.Y = -_body.VelocityTarget.Y; + } + } + + public Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (damageType != HitType.MagicRod || _damageState.CurrentLives <= 0) + return Values.HitCollision.None; + + if (_aiComponent.CurrentStateId == "breaking" || _aiComponent.CurrentStateId == "broken" || + _damageState.IsInDamageState()) + return Values.HitCollision.Enemy; + + // flame jump => damaged + if (!_damaged && _aiComponent.CurrentStateId == "jumping") + { + _damageState.SetDamageState(); + _aiComponent.ChangeState("damaged"); + Game1.GameManager.PlaySoundEffect("D370-07-07"); + return Values.HitCollision.Enemy; + } + + // moving/wobbling => hit + if (_aiComponent.CurrentStateId == "moving" || _aiComponent.CurrentStateId == "damaged") + { + _damageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + + if (!_damaged && _damageState.CurrentLives <= 4) + { + _aiComponent.ChangeState("breaking"); + return Values.HitCollision.Enemy; + } + + // stop moving for a short while + _body.IsActive = false; + _hitMoveReset.Restart(); + + return Values.HitCollision.Enemy; + } + + // damage state while jumping => hit + if (_damaged && _aiComponent.CurrentStateId == "jumping") + { + if (_damageState.CurrentLives > 2) + _aiComponent.ChangeState("freeze"); + else + _aiComponent.ChangeState("dead"); + + _damageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + + // freeze in the air + show final dialog + if (_damageState.CurrentLives <= 0) + { + _body.IsActive = false; + Game1.GameManager.StartDialogPath("hot_head_death"); + } + + return Values.HitCollision.Enemy; + } + + return Values.HitCollision.None; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossHotHeadFace.cs b/InGame/GameObjects/Bosses/BossHotHeadFace.cs new file mode 100644 index 0000000..17f0454 --- /dev/null +++ b/InGame/GameObjects/Bosses/BossHotHeadFace.cs @@ -0,0 +1,74 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using ProjectZ.InGame.GameObjects.Base.Components.AI; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class BossHotHeadFace : GameObject + { + private readonly BodyComponent _body; + private readonly Animator _animator; + private readonly AnimationComponent _animationComponent; + private readonly AiComponent _aiComponent; + private readonly CSprite _sprite; + + public BossHotHeadFace(Map.Map map, Vector3 position, Vector3 velocity, string animation) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(position); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Nightmares/hot head"); + _animator.Play(animation); + + _sprite = new CSprite(EntityPosition); + _animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -5, -10, 10, 10, 8) + { + Gravity = -0.075f, + CollisionTypes = Values.CollisionTypes.None, + Velocity = velocity, + IsGrounded = false + }; + + _aiComponent = new AiComponent(); + + var stateFlying = new AiState(UpdateFlying); + var stateSplash = new AiState(UpdateSplash); + + _aiComponent.States.Add("flying", stateFlying); + _aiComponent.States.Add("splash", stateSplash); + + _aiComponent.ChangeState("flying"); + + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, _animationComponent); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerPlayer)); + } + + private void UpdateFlying() + { + if (_body.IsGrounded) + { + _body.VelocityTarget = Vector2.Zero; + _animator.Play("fireball_splash"); + _aiComponent.ChangeState("splash"); + } + } + + private void UpdateSplash() + { + if (!_animator.IsPlaying) + { + Map.Objects.DeleteObjects.Add(this); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossHotHeadSplash.cs b/InGame/GameObjects/Bosses/BossHotHeadSplash.cs new file mode 100644 index 0000000..a7f771b --- /dev/null +++ b/InGame/GameObjects/Bosses/BossHotHeadSplash.cs @@ -0,0 +1,77 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using ProjectZ.InGame.GameObjects.Base.Components.AI; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class BossHotHeadSplash : GameObject + { + private readonly BodyComponent _body; + private readonly Animator _animator; + private readonly AnimationComponent _animationComponent; + private readonly AiComponent _aiComponent; + private readonly CSprite _sprite; + + public BossHotHeadSplash(Map.Map map, Vector2 position, Vector2 velocity) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(position.X, position.Y, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Nightmares/hot head"); + _animator.Play("fireball"); + + _sprite = new CSprite(EntityPosition); + _animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -5, -10, 10, 10, 8) + { + Gravity = -0.1f, + CollisionTypes = Values.CollisionTypes.None, + Velocity = new Vector3(0, 0, 2.25f), + VelocityTarget = new Vector2(velocity.X, velocity.Y), + IsGrounded = false + }; + + _aiComponent = new AiComponent(); + + var stateFlying = new AiState(UpdateFlying); + var stateSplash = new AiState(UpdateSplash); + + _aiComponent.States.Add("flying", stateFlying); + _aiComponent.States.Add("splash", stateSplash); + + _aiComponent.ChangeState("flying"); + + var damageCollider = new CBox(EntityPosition, -5, -10, 0, 10, 10, 8, true); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, _animationComponent); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 16)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerPlayer)); + } + + private void UpdateFlying() + { + if (_body.IsGrounded) + { + _body.VelocityTarget = Vector2.Zero; + _animator.Play("fireball_splash"); + _aiComponent.ChangeState("splash"); + } + } + + private void UpdateSplash() + { + if (!_animator.IsPlaying) + { + Map.Objects.DeleteObjects.Add(this); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossMoldorm.cs b/InGame/GameObjects/Bosses/BossMoldorm.cs new file mode 100644 index 0000000..640964a --- /dev/null +++ b/InGame/GameObjects/Bosses/BossMoldorm.cs @@ -0,0 +1,399 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + class BossMoldorm : GameObject + { + private BossMoldormTail _tail; + + private BodyDrawComponent _bodyDrawComponent; + private BodyComponent _body; + private AiComponent _aiComponent; + private CSprite _sprite; + + private Rectangle _headSourceRectangle = new Rectangle(2, 4, 28, 24); + private Rectangle _headSourceRectangleDamage = new Rectangle(34, 4, 28, 24); + + private Rectangle[] _tailRectangles = { + new Rectangle(8, 40, 16, 16), new Rectangle(8, 40, 16, 16), new Rectangle(41, 41, 14, 14) + }; + private Rectangle[] _tailRectanglesDamage = { + new Rectangle(8, 72, 16, 16), new Rectangle(8, 72, 16, 16), new Rectangle(41, 73, 14, 14) + }; + + private Vector2[] _tailPositions = new Vector2[4]; + private float[] _tailDistance = { 6.5f, 4.5f, 4.5f, 4.5f }; + + private Vector2[] _savedPosition = new Vector2[20]; + + private string _saveKey; + private string _triggerKey; + + private float _saveInterval = 33; + private float _saveCounter; + private int _saveIndex; + + private float _directionChangeMultiplier; + private float _direction; + private float _runCounter; + private int _changeDirCount; + private int _dir = 1; + private int _lives = 4; + + private int _dyingState = 4; + private int _tailState = 2; + private float _dyingCounter = 250; + + private bool _blinking; + + public BossMoldorm() : base("moldorm") { } + + public BossMoldorm(Map.Map map, int posX, int posY, string saveKey, string triggerKey) : base(map) + { + if (!string.IsNullOrEmpty(saveKey) && + Game1.GameManager.SaveManager.GetString(saveKey) == "1") + { + IsDead = true; + return; + } + + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 16, posY + 16, 0); + EntitySize = new Rectangle(-24, -24, 48, 48); + + for (var i = 0; i < 4; i++) + _tailPositions[i] = EntityPosition.Position; + for (var i = 0; i < _savedPosition.Length; i++) + _savedPosition[i] = EntityPosition.Position; + + _saveKey = saveKey; + _triggerKey = triggerKey; + + _sprite = new CSprite(EntityPosition); + _sprite.SprTexture = Resources.SprNightmares; + _sprite.SourceRectangle = _headSourceRectangle; + _sprite.Center = new Vector2(16, 12); + + _direction = (float)Math.PI * 2; + _sprite.Rotation = -_direction - (float)Math.PI / 2; + + _body = new BodyComponent(EntityPosition, -7, -7, 14, 14, 8) + { + MoveCollision = OnCollision, + AbsorbPercentage = 1f, + Gravity = -0.1f, + DragAir = 1.0f, + Drag = 0.925f, + CollisionTypes = + Values.CollisionTypes.Normal | + Values.CollisionTypes.Hole, + FieldRectangle = map.GetField(posX, posY) + }; + + _aiComponent = new AiComponent(); + + var stateWaiting = new AiState(); + var stateMoving = new AiState(UpdateMoving); + var stateRunning = new AiState(UpdateRunning); + var stateDamage = new AiState(UpdateDamage); + stateDamage.Trigger.Add(new AiTriggerCountdown(500, UpdateDamageTick, ToRunning)); + var stateDying = new AiState(UpdateDying); + + _aiComponent.States.Add("waiting", stateWaiting); + _aiComponent.States.Add("moving", stateMoving); + _aiComponent.States.Add("running", stateRunning); + _aiComponent.States.Add("damage", stateDamage); + _aiComponent.States.Add("dying", stateDying); + + _aiComponent.ChangeState("waiting"); + + _bodyDrawComponent = new BodyDrawComponent(_body, _sprite, 1); + var damageCollider = new CBox(EntityPosition, -6, -6, 0, 12, 12, 8); + + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChang)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush) { RepelMultiplier = 2.0f }); + AddComponent(HittableComponent.Index, new HittableComponent(damageCollider, OnHit)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 4)); + + // add the tail to the map + _tail = new BossMoldormTail(map, this); + map.Objects.SpawnObject(_tail); + } + + private void ToWalking() + { + _aiComponent.ChangeState("moving"); + _sprite.SourceRectangle = _headSourceRectangle; + _blinking = false; + } + + private void UpdateMoving() + { + Move(1); + UpdateTailPositions(1); + } + + private void ToRunning() + { + _aiComponent.ChangeState("running"); + _sprite.SourceRectangle = _headSourceRectangle; + _blinking = false; + } + + private void UpdateRunning() + { + // dont stop running with one live left + if (_lives > 1) + { + _runCounter -= Game1.DeltaTime; + if (_runCounter <= 0) + _aiComponent.ChangeState("moving"); + } + + Move(1.75f); + UpdateTailPositions(1.75f); + } + + private void Move(float speedMultiplier) + { + _changeDirCount -= (int)(Game1.DeltaTime * speedMultiplier); + if (_changeDirCount < 0) + ChangeDirection(); + + _direction += _dir * 0.05f * Game1.TimeMultiplier * speedMultiplier; + + _sprite.Rotation = -_direction - (float)Math.PI / 2; + + // move + var vecDirection = new Vector2((float)Math.Sin(_direction), (float)Math.Cos(_direction)); + _body.VelocityTarget = vecDirection * 1.0f * speedMultiplier; + + _directionChangeMultiplier = AnimationHelper.MoveToTarget(_directionChangeMultiplier, 1, 0.1f * Game1.TimeMultiplier); + } + + private void UpdateDamage() + { + _body.VelocityTarget = Vector2.Zero; + UpdateTailPositions(1.5f); + } + + private void UpdateDamageTick(double time) + { + _blinking = (time % 150) >= 75; + + _direction += _dir * (float)Math.Sin(((time + 150) / 800f) * Math.PI) * 0.1f * Game1.TimeMultiplier; + _sprite.Rotation = -_direction - (float)Math.PI / 2; + _sprite.SourceRectangle = _blinking ? _headSourceRectangleDamage : _headSourceRectangle; + } + + private void ToDying() + { + _body.Velocity = new Vector3(_body.VelocityTarget.X, _body.VelocityTarget.Y, _body.Velocity.Z); + _body.VelocityTarget = Vector2.Zero; + + _aiComponent.ChangeState("dying"); + Game1.GameManager.PlaySoundEffect("D370-16-10"); + } + + private void UpdateDying() + { + UpdateTailPositions(_body.Velocity.Length()); + + _dyingCounter -= Game1.DeltaTime; + + if (_dyingCounter <= 0) + { + _dyingCounter = 250; + _dyingState--; + + if (_tail != null) + { + Map.Objects.DeleteObjects.Add(_tail); + _tail = null; + } + else + _tailState--; + + if (_dyingState < -10) + { + Map.Objects.DeleteObjects.Add(this); + + // stop boss music + Game1.GameManager.SetMusic(-1, 2); + + // set the save key + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + // spawn big heart + Map.Objects.SpawnObject(new ObjItem(Map, (int)EntityPosition.X - 8, (int)EntityPosition.Y - 8, "j", "d1_nHeart", "heartMeterFull", null)); + + Game1.GameManager.PlaySoundEffect("D378-26-1A"); + } + else if (_dyingState < 0) + { + _dyingCounter = 50; + Game1.GameManager.PlaySoundEffect("D378-19-13"); + + // spawn explosion effect arount the head + var position = new Point((int)(Math.Sin(-_dyingState / 1.5f) * 8), (int)(Math.Cos(-_dyingState / 1.5f) * 8)); + Map.Objects.SpawnObject(new ObjAnimator(Map, + (int)EntityPosition.X - 8 + position.X, + (int)EntityPosition.Y - 8 + position.Y, Values.LayerTop, "Particles/spawn", "run", true)); + } + else + { + Game1.GameManager.PlaySoundEffect("D378-19-13"); + + // spawn explosion at the tail + Map.Objects.SpawnObject(new ObjAnimator(Map, + (int)_tailPositions[_dyingState].X - 8, + (int)_tailPositions[_dyingState].Y - 8, Values.LayerTop, "Particles/spawn", "run", true)); + } + } + } + + private void Draw(SpriteBatch spriteBatch) + { + // draw the tail + var tailRectangles = _blinking ? _tailRectanglesDamage : _tailRectangles; + for (var i = _tailState; i >= 0; i--) + { + spriteBatch.Draw(Resources.SprNightmares, _tailPositions[i] - + new Vector2(tailRectangles[i].Width / 2f, tailRectangles[i].Height / 2f), tailRectangles[i], Color.White); + } + + // draw the head + _bodyDrawComponent.Draw(spriteBatch); + } + + public Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + return Values.HitCollision.RepellingParticle; + } + + public Values.HitCollision OnHitTail(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_aiComponent.CurrentStateId == "damage" || _aiComponent.CurrentStateId == "dying") + return Values.HitCollision.None; + + // can only be damaged with the sword + if ((damageType & HitType.Sword) == 0) + return Values.HitCollision.None; + + _lives -= damage; + _runCounter = 2000; + + Game1.GameManager.PlaySoundEffect("D370-07-07"); + + if (_lives > 0) + _aiComponent.ChangeState("damage"); + else + ToDying(); + + return Values.HitCollision.Enemy; + } + + private void UpdateTailPositions(float speedMultiplier) + { + SavePosition(speedMultiplier); + + var indexCount = _saveIndex + (_saveCounter / _saveInterval); + var timeDiff = _saveCounter + _saveInterval * 1000; + + for (var i = 0; i < _tailPositions.Length; i++) + { + indexCount -= _tailDistance[i]; + if (indexCount < 0) + indexCount += _savedPosition.Length; + + timeDiff -= _tailDistance[i] * _saveInterval; + var index = (int)indexCount; + + _tailPositions[i] = Vector2.Lerp( + _savedPosition[index], _savedPosition[(index + 1) % _savedPosition.Length], + (timeDiff % _saveInterval) / _saveInterval); + } + + // set the position of the tail + _tail?.EntityPosition.Set(_tailPositions[_tailPositions.Length - 1]); + } + + private void SavePosition(float speedMultiplier) + { + var position = EntityPosition.Position + _body.VelocityTarget * (Game1.DeltaTime / 16.6667f) * speedMultiplier; + _saveCounter += Game1.DeltaTime * speedMultiplier; + var diff = _saveCounter % _saveInterval; + + var updateSteps = (int)(_saveCounter / _saveInterval); + _saveIndex = (_saveIndex + updateSteps) % _savedPosition.Length; + var index = _saveIndex; + + var currentDirection = _direction; + + while (_saveCounter >= _saveInterval) + { + _saveCounter -= _saveInterval; + + index--; + if (index < 0) + index = _savedPosition.Length - 1; + + var vecDir = new Vector2((float)Math.Sin(currentDirection), (float)Math.Cos(currentDirection)); + _savedPosition[index] = position - vecDir * (diff / 16.6667f); + + position = _savedPosition[index]; + diff = _saveInterval; + currentDirection -= _dir * 0.025f * (_saveInterval / 16.6667f); + } + } + + private void OnCollision(Values.BodyCollision collision) + { + if (Game1.RandomNumber.Next(0, 2) == 0) + _dir = -_dir; + + if ((collision & Values.BodyCollision.Horizontal) != 0) + _direction = (float)Math.Atan2(-_body.VelocityTarget.X * _directionChangeMultiplier, _body.VelocityTarget.Y); + else if ((collision & Values.BodyCollision.Vertical) != 0) + _direction = (float)Math.Atan2(_body.VelocityTarget.X, -_body.VelocityTarget.Y * _directionChangeMultiplier); + + _directionChangeMultiplier *= 0.75f; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X * 0.25f, direction.Y * 0.25f, _body.Velocity.Z); + + return true; + } + + private void ChangeDirection() + { + _changeDirCount = Game1.RandomNumber.Next(500, 2500); + _dir = -_dir; + } + + private void OnKeyChang() + { + // activate the boss if the trigger key was set + if (_aiComponent.CurrentStateId == "waiting" && + !string.IsNullOrEmpty(_triggerKey) && Game1.GameManager.SaveManager.GetString(_triggerKey) == "1") + { + _aiComponent.ChangeState("moving"); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossMoldormTail.cs b/InGame/GameObjects/Bosses/BossMoldormTail.cs new file mode 100644 index 0000000..311aac4 --- /dev/null +++ b/InGame/GameObjects/Bosses/BossMoldormTail.cs @@ -0,0 +1,35 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + class BossMoldormTail : GameObject + { + public BossMoldormTail(Map.Map map, BossMoldorm nightmare) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(nightmare.EntityPosition.X, nightmare.EntityPosition.Y, 0); + + var animator = AnimatorSaveLoad.LoadAnimator("Nightmares/nightmare tail"); + animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + + var hittableBox = new CBox(EntityPosition, -6, -6, 12, 12, 8); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, nightmare.OnHitTail)); + AddComponent(BaseAnimationComponent.Index, new AnimationComponent(animator, sprite, new Vector2(-8, -8))); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerBottom)); + AddComponent(PushableComponent.Index, new PushableComponent(new CBox(EntityPosition, -6, -6, 12, 12, 8), OnPush) { RepelMultiplier = 1.5f }); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossSlimeEel.cs b/InGame/GameObjects/Bosses/BossSlimeEel.cs new file mode 100644 index 0000000..dad5928 --- /dev/null +++ b/InGame/GameObjects/Bosses/BossSlimeEel.cs @@ -0,0 +1,630 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + class BossSlimeEel : GameObject + { + private readonly Animator _animator; + private readonly AnimationComponent _animationComponent; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly CSprite _sprite; + private readonly DamageFieldComponent _damageField; + private readonly AiDamageState _aiDamageState; + + private readonly Animator _explosionAnimator; + + private readonly BossSlimeEelSpawn _eelSpawner; + + // parts are used to deal damage and have a hittable box + private readonly BossSlimeEelTail[] _tailParts = new BossSlimeEelTail[5]; + + private readonly DictAtlasEntry _spriteTail; + private readonly DictAtlasEntry _spriteTailEnd; + private readonly DictAtlasEntry _spriteHeart0; + private readonly DictAtlasEntry _spriteHeart1; + + private readonly Vector2 _centerPosition; + + private Vector2 _startPosition; + + private Vector2 _hockshotPosition; + private Vector2 _hookshotOffset; + private float _pullSound; + + private double _retreatCount; + private float _moveSpeed; + private int _moveDirection = 1; + + private bool _attackOut; + private bool _isFullyOut; + + private float _moveRotation; + private float _rotationDir = 1; + + private const float MoveSpeed = 0.75f; + + private readonly float[] _tailDistance = { 10.0f, 8f, 9f }; + private readonly Vector2[] _savedPosition = new Vector2[30]; + private readonly Vector2[] _tailPositions = new Vector2[3]; + + private string _saveKey; + + private bool _attackSound; + + private float _saveInterval = 33; + private float _saveCounter; + private int _saveIndex; + + public BossSlimeEel(Map.Map map, Vector2 centerPosition, BossSlimeEelSpawn eelSpawner, string saveKey) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + _centerPosition = centerPosition; + _eelSpawner = eelSpawner; + + _saveKey = saveKey; + + EntityPosition = new CPosition(centerPosition.X, centerPosition.Y, 0); + EntitySize = new Rectangle(-16, -16, 32, 32); + + _body = new BodyComponent(EntityPosition, -8, -8, 16, 16, 8) + { + MoveCollision = OnCollision, + IgnoreHoles = true + }; + + _spriteTail = Resources.GetSprite("eel_tail_0"); + _spriteTailEnd = Resources.GetSprite("eel_tail_2"); + _spriteHeart0 = Resources.GetSprite("eel_heart_0"); + _spriteHeart1 = Resources.GetSprite("eel_heart_1"); + + for (var i = 0; i < _tailParts.Length; i++) + { + if (i == 0) + _tailParts[i] = new BossSlimeEelTail(Map, EntityPosition.Position, 0, OnHitHeart); + else + _tailParts[i] = new BossSlimeEelTail(Map, EntityPosition.Position, 0, null); + + _tailParts[i].SetActive(false); + + Map.Objects.SpawnObject(_tailParts[i]); + } + + _explosionAnimator = AnimatorSaveLoad.LoadAnimator("Objects/explosion"); + + _animator = AnimatorSaveLoad.LoadAnimator("Nightmares/slime eel"); + + _sprite = new CSprite(EntityPosition); + _animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _aiComponent = new AiComponent(); + + var stateSpawn = new AiState { Init = InitSpawn }; + var stateSpawnAttack = new AiState(UpdateSpawnAttack); + var stateHidden = new AiState { Init = InitHidden }; + stateHidden.Trigger.Add(new AiTriggerCountdown(1000, null, EndHidden)); + var stateAttack = new AiState(UpdateAttack) { Init = InitAttack }; + var statePulled = new AiState(UpdatePulled) { Init = InitPulled }; + var stateRetreat = new AiState(UpdateRetreat) { Init = InitRetreat }; + var stateJumpingOut = new AiState(UpdateJumpingOut) { Init = InitJumpingOut }; + var statePulledOut = new AiState(UpdatePulledOut) { Init = InitPulledOut }; + statePulledOut.Trigger.Add(new AiTriggerRandomTime(ChangeDirection, 650, 1000)); + statePulledOut.Trigger.Add(new AiTriggerCountdown(1600, null, () => _aiComponent.ChangeState("blink"))); + var stateBlink = new AiState { Init = InitBlink }; + stateBlink.Trigger.Add(new AiTriggerCountdown(AiDamageState.CooldownTime, TickBlink, Explode)); + var stateExplode = new AiState(UpdateExplode) { Init = InitExplode }; + + _aiComponent.States.Add("spawn", stateSpawn); + _aiComponent.States.Add("spawnAttack", stateSpawnAttack); + _aiComponent.States.Add("hidden", stateHidden); + _aiComponent.States.Add("attack", stateAttack); + _aiComponent.States.Add("pulled", statePulled); + _aiComponent.States.Add("retreat", stateRetreat); + _aiComponent.States.Add("jumpingOut", stateJumpingOut); + _aiComponent.States.Add("pulledOut", statePulledOut); + _aiComponent.States.Add("blink", stateBlink); + _aiComponent.States.Add("explode", stateExplode); + _aiDamageState = new AiDamageState(this, _body, _aiComponent, _sprite, 8, false, false) + { + HitMultiplierX = 0, + HitMultiplierY = 0, + ExplosionOffsetY = 16, + BossHitSound = true + }; + _aiDamageState.AddBossDamageState(OnDeath); + + _aiComponent.ChangeState("spawn"); + + var damageCollider = new CBox(EntityPosition, -6, -6, 0, 12, 12, 8); + var hittableBox = new CBox(EntityPosition, -6, -6, 0, 12, 12, 8); + + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, _animationComponent); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBottom, EntityPosition)); + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageCollider, HitType.Enemy, 2) { IsActive = false }); + } + + public void SpawnAttack(int positionIndex) + { + SetAttackPosition(positionIndex); + + _attackSound = false; + _sprite.IsVisible = true; + _animator.Play("attack_spawn"); + _aiComponent.ChangeState("spawnAttack"); + } + + public void ToSpawned() + { + _aiComponent.ChangeState("hidden"); + } + + private void InitSpawn() + { + _sprite.IsVisible = false; + } + + private void UpdateSpawnAttack() + { + if (!_attackSound && _animator.CurrentFrameIndex == 2) + { + _attackSound = true; + Game1.GameManager.PlaySoundEffect("D370-22-16"); + } + + if (!_animator.IsPlaying) + { + _aiComponent.ChangeState("spawn"); + } + } + + private void InitExplode() + { + Game1.GameManager.PlaySoundEffect("D378-12-0C"); + _explosionAnimator.Play("idle"); + + _isFullyOut = false; + _sprite.IsVisible = false; + } + + private void UpdateExplode() + { + var collisionRect = _explosionAnimator.CollisionRectangle; + if (collisionRect != Rectangle.Empty) + { + var collisionBox = new Box( + EntityPosition.X + collisionRect.X, + EntityPosition.Y + collisionRect.Y, 0, + collisionRect.Width, collisionRect.Height, 16); + + if (collisionBox.Intersects(MapManager.ObjLink._body.BodyBox.Box)) + MapManager.ObjLink.HitPlayer(collisionBox, HitType.Bomb, 4); + } + + _explosionAnimator.Update(); + if (!_explosionAnimator.IsPlaying) + _aiComponent.ChangeState("hidden"); + } + + private void InitBlink() + { + _damageField.IsActive = false; + _body.VelocityTarget = Vector2.Zero; + } + + private void TickBlink(double counter) + { + _sprite.SpriteShader = (AiDamageState.CooldownTime - counter) % (AiDamageState.BlinkTime * 2) < + AiDamageState.BlinkTime ? Resources.DamageSpriteShader0 : null; + } + + private void Explode() + { + _aiComponent.ChangeState("explode"); + } + + private void InitJumpingOut() + { + Game1.GameManager.PlaySoundEffect("D370-22-16"); + + _animator.Play("head_0"); + _body.VelocityTarget = _moveDirection * new Vector2(0, 1) * 1.5f; + _moveRotation = _moveDirection != 1 ? MathF.PI : 0; + _isFullyOut = true; + + for (var i = 0; i < _savedPosition.Length; i++) + _savedPosition[i] = _startPosition; + } + + private void UpdateJumpingOut() + { + var distance = Math.Abs(_startPosition.Y - EntityPosition.Y); + var tailState = 1 - Math.Clamp(distance / 48, 0, 1); + + _eelSpawner.SetTailState(tailState); + + if (distance > 48) + _aiComponent.ChangeState("pulledOut"); + + UpdateTailPositions(); + } + + private void ChangeDirection() + { + _rotationDir = -_rotationDir; + } + + private void OnCollision(Values.BodyCollision collision) + { + _moveRotation += MathF.PI; + } + + private void InitPulledOut() + { + } + + private void UpdatePulledOut() + { + _moveRotation += _rotationDir * Game1.TimeMultiplier * 0.1f; + + var newVelocity = new Vector2(-MathF.Sin(_moveRotation), MathF.Cos(_moveRotation)) * MoveSpeed; + _body.VelocityTarget = newVelocity; + + UpdateTailPositions(); + + while (_moveRotation < MathF.PI * 2) + _moveRotation += MathF.PI * 2; + + // update the animation + var animationIndex = (int)((_moveRotation + Math.PI / 8) / (MathF.PI / 4)) % 8; + + if (animationIndex % 2 == 0) + { + if (animationIndex == 0 || animationIndex == 4) + _animator.Play("head_0"); + else + _animator.Play("head_2"); + } + else + { + _animationComponent.MirroredH = animationIndex > 4; + _animationComponent.MirroredV = animationIndex != 1 && animationIndex != 7; + _animator.Play("head_1"); + } + } + + private void OnDeath() + { + // spawn a heart + var objItem = new ObjItem(Map, (int)EntityPosition.X - 8, (int)EntityPosition.Y - 8, "j", "d5_nHeart", "heartMeterFull", null); + Map.Objects.SpawnObject(objItem); + + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + // stop boss music + Game1.GameManager.SetMusic(-1, 2); + + DespawnObjects(); + } + + private void DespawnObjects() + { + // delete the head + Map.Objects.DeleteObjects.Add(this); + + // delete the tail + for (var i = 0; i < _tailParts.Length; i++) + Map.Objects.DeleteObjects.Add(_tailParts[i]); + } + + private void UpdateTail() + { + var distance = Math.Abs(_startPosition.Y - EntityPosition.Y); + var tailState = 1 - Math.Clamp(distance / 80, 0, 1); + + _eelSpawner.SetTailState(tailState); + } + + private void InitRetreat() + { + _retreatCount = 0; + _moveSpeed = 1 / 16f; + _animator.Play("head_open"); + } + + private void UpdateRetreat() + { + _retreatCount += Game1.DeltaTime; + + var direction = _startPosition - EntityPosition.Position; + + if (_retreatCount > 1500) + { + _moveSpeed = AnimationHelper.MoveToTarget(_moveSpeed, 1, 0.05f * Game1.TimeMultiplier); + } + + var moveDistance = _moveSpeed * Game1.TimeMultiplier; + + if (direction.Length() > moveDistance) + { + direction.Normalize(); + EntityPosition.Offset(direction * moveDistance); + } + else + { + _attackOut = false; + EntityPosition.Set(_startPosition); + _aiComponent.ChangeState("hidden"); + } + + UpdateTail(); + } + + private void InitPulled() + { + _damageField.IsActive = false; + _attackOut = true; + _pullSound = 0; + + _animator.Play("head_0"); + } + + private void UpdatePulled() + { + // finished pull + if (!MapManager.ObjLink.Hookshot.IsMoving) + { + FinishPull(); + } + + UpdateTail(); + + _pullSound += Game1.DeltaTime; + if (_pullSound > 75) + { + _pullSound -= 75; + Game1.GameManager.PlaySoundEffect("D360-41-29"); + } + } + + private void FinishPull() + { + MapManager.ObjLink.Hookshot.HookshotPosition.PositionChangedDict.Remove(typeof(BossSlimeEel)); + + _aiComponent.ChangeState("retreat"); + } + + private void InitAttack() + { + SetAttackPosition(Game1.RandomNumber.Next(0, 4)); + + // activate damage + for (var i = 0; i < _tailParts.Length; i++) + _tailParts[i].SetActive(true); + + _damageField.IsActive = true; + _sprite.IsVisible = true; + _animator.Play("attack"); + } + + private void SetAttackPosition(int index) + { + _moveDirection = index < 2 ? 1 : -1; + + var spawnPosition = new Vector2( + _centerPosition.X + (index % 2 == 0 ? -32 : 32), + _centerPosition.Y + (index < 2 ? -56 : 56)); + + _animationComponent.MirroredV = index >= 2; + _animationComponent.MirroredH = index >= 2; + + EntityPosition.Set(spawnPosition); + _startPosition = spawnPosition; + } + + private void UpdateAttack() + { + if (!_attackSound && _animator.CurrentFrameIndex == 3) + { + _attackSound = true; + Game1.GameManager.PlaySoundEffect("D370-22-16"); + } + + // finished attacking? + if (!_animator.IsPlaying) + { + _aiComponent.ChangeState("hidden"); + } + } + + private void InitHidden() + { + _sprite.IsVisible = false; + _eelSpawner.SetTailIsMoving(true); + } + + private void EndHidden() + { + _attackSound = false; + _aiComponent.ChangeState("attack"); + } + + private void Draw(SpriteBatch spriteBatch) + { + // change the draw effect + if (_sprite.SpriteShader != null) + { + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, _sprite.SpriteShader); + } + + // draw the tail + if (_attackOut) + for (var i = 0; i < 5; i++) + { + var centerPosition = new Vector2(EntityPosition.X, EntityPosition.Y + (14 + i * 14) * -_moveDirection); + var position = new Vector2(centerPosition.X - 8, centerPosition.Y - 8); + _tailParts[i].EntityPosition.Set(centerPosition); + + if (_moveDirection == 1 && position.Y + 16 < _startPosition.Y || + _moveDirection == -1 && position.Y > _startPosition.Y) + continue; + + var sprite = _spriteTail; + // draw the part with the heart + if (i == 0) + sprite = Game1.TotalGameTime % (32000 / 60f) < (16000 / 60f) ? _spriteHeart0 : _spriteHeart1; + + DrawHelper.DrawNormalized(spriteBatch, sprite, position, Color.White); + } + + // draw the tail while moving around outside + if (_isFullyOut) + { + for (var i = _tailPositions.Length - 1; i >= 0; i--) + { + var sprite = i == 2 ? _spriteTailEnd : _spriteTail; + var position = new Vector2(_tailPositions[i].X - 8, _tailPositions[i].Y - 8); + DrawHelper.DrawNormalized(spriteBatch, sprite, position, Color.White); + } + } + + // draw the head + _sprite.Draw(spriteBatch); + + // change the draw effect + if (_sprite.SpriteShader != null) + { + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, null); + } + + // draw the explosion + if (_explosionAnimator.IsPlaying) + _explosionAnimator.Draw(spriteBatch, EntityPosition.Position, Color.White); + } + + public Values.HitCollision OnHitHeart(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + // can not get attacked while not visible + if (!_attackOut || (type & HitType.Sword) == 0) + return Values.HitCollision.None; + + var wasAlive = _aiDamageState.CurrentLives > 0; + var hitReturn = _aiDamageState.OnHit(originObject, direction, type, damage, false); + + if (_aiDamageState.CurrentLives <= 0 && wasAlive) + { + Game1.GameManager.StartDialogPath("slime_eel_1"); + _eelSpawner.ToDespawn(); + } + + return hitReturn; + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + // can get pulled out by the hookshot at animation frame 1, 2 and 3 + if (_aiComponent.CurrentStateId == "attack" && 0 < _animator.CurrentFrameIndex && _animator.CurrentFrameIndex < 4 && type == HitType.Hookshot) + { + _hockshotPosition = MapManager.ObjLink.Hookshot.HookshotPosition.Position; + _hookshotOffset = EntityPosition.Position - _hockshotPosition; + + //TODO: not sure what the real condition for this is + if (_aiDamageState.CurrentLives <= 4 && Game1.RandomNumber.Next(0, 10) < 5) + _aiComponent.ChangeState("jumpingOut"); + else + { + MapManager.ObjLink.Hookshot.HookshotPosition.AddPositionListener(typeof(BossSlimeEel), OnPositionChange); + _aiComponent.ChangeState("pulled"); + } + + _eelSpawner.SetTailIsMoving(false); + _eelSpawner.ChangeRotation(); + + return Values.HitCollision.Blocking; + } + + if (_aiComponent.CurrentStateId == "attack") + return Values.HitCollision.RepellingParticle; + + if (!_isFullyOut && !_attackOut) + return Values.HitCollision.None; + + return Values.HitCollision.RepellingParticle; + } + + private void OnPositionChange(CPosition position) + { + // head gets pulled out of the hole + var newPosition = position.Position + _hookshotOffset; + EntityPosition.Set(newPosition); + } + + private void UpdateTailPositions() + { + SavePosition(); + + var indexCount = _saveIndex + (_saveCounter / _saveInterval); + var timeDiff = _saveCounter + _saveInterval * 1000; + + for (var i = 0; i < _tailPositions.Length; i++) + { + indexCount -= _tailDistance[i]; + if (indexCount < 0) + indexCount += _savedPosition.Length; + + timeDiff -= _tailDistance[i] * _saveInterval; + var index = (int)indexCount; + + _tailPositions[i] = Vector2.Lerp( + _savedPosition[index], _savedPosition[(index + 1) % _savedPosition.Length], + (timeDiff % _saveInterval) / _saveInterval); + } + } + + // TODO: make this better; does not work correctly + private void SavePosition() + { + var position = EntityPosition.Position + _body.VelocityTarget * (Game1.DeltaTime / 16.6667f); + _saveCounter += Game1.DeltaTime; + var diff = _saveCounter % _saveInterval; + + var updateSteps = (int)(_saveCounter / _saveInterval); + _saveIndex = (_saveIndex + updateSteps) % _savedPosition.Length; + var index = _saveIndex; + + var currentDirection = _moveRotation; + + while (_saveCounter >= _saveInterval) + { + _saveCounter -= _saveInterval; + + index--; + if (index < 0) + index = _savedPosition.Length - 1; + + var vecDir = new Vector2((float)Math.Sin(currentDirection), (float)Math.Cos(currentDirection)); + _savedPosition[index] = position - vecDir * (diff / 16.6667f); + + position = _savedPosition[index]; + diff = _saveInterval; + currentDirection -= _moveDirection * 0.025f * (_saveInterval / 16.6667f); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossSlimeEelSpawn.cs b/InGame/GameObjects/Bosses/BossSlimeEelSpawn.cs new file mode 100644 index 0000000..930f00a --- /dev/null +++ b/InGame/GameObjects/Bosses/BossSlimeEelSpawn.cs @@ -0,0 +1,407 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + class BossSlimeEelSpawn : GameObject + { + private enum SpawnState + { + Init, + Shake, + FloorBreak, + FloorGone, + Wall0, + ShakeEnd, + Wall1, + Wall2, + Wall3, + } + + private SpawnState _spawnState; + private float _spawnCounter; + + private readonly BossSlimeEel _slimeEel; + + private readonly BossSlimeEelTail[] _tailParts = new BossSlimeEelTail[5]; + + private readonly AiComponent _aiComponent; + + private readonly CSprite[] _sprite = new CSprite[20]; + + private RectangleF _fieldRectangle; + private Vector2 _centerPosition; + + private float _rotation; + private readonly float _rotationSpeed; + private int _rotationDirection = 1; + + private float _shakeSoundCounter; + + private float _tailState; + private int _tailIndex; + + private bool _tailIsMoving = true; + private bool _tailComeOut = true; + private bool _isVisible = false; + + public BossSlimeEelSpawn() : base("slime eel") { } + + public BossSlimeEelSpawn(Map.Map map, int posX, int posY, string saveKey) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + _centerPosition = new Vector2(posX + 8, posY + 8); + + if (!string.IsNullOrWhiteSpace(saveKey) && Game1.GameManager.SaveManager.GetString(saveKey) == "1") + { + // respawn the heart if the player died after he killed the boss without collecting the heart + SpawnHeart(); + + SpawnHoles(); + + IsDead = true; + return; + } + + _sprite[0] = new CSprite("eel_floor_broken", new CPosition(posX - 8, posY - 8, 0), Vector2.Zero); + _sprite[1] = new CSprite("eel_floor_broken", new CPosition(posX + 8, posY - 8, 0), Vector2.Zero); + _sprite[2] = new CSprite("eel_floor_broken", new CPosition(posX - 8, posY + 8, 0), Vector2.Zero); + _sprite[3] = new CSprite("eel_floor_broken", new CPosition(posX + 8, posY + 8, 0), Vector2.Zero); + + _sprite[4] = new CSprite("eel_floor", new CPosition(posX - 8, posY - 8, 0), Vector2.Zero); + _sprite[5] = new CSprite("eel_floor", new CPosition(posX + 8, posY - 8, 0), Vector2.Zero); + _sprite[6] = new CSprite("eel_floor", new CPosition(posX - 8, posY + 8, 0), Vector2.Zero); + _sprite[7] = new CSprite("eel_floor", new CPosition(posX + 8, posY + 8, 0), Vector2.Zero); + + _sprite[8] = new CSprite("eel_wall_open", new CPosition(posX - 40, posY - 56, 0), Vector2.Zero); + _sprite[9] = new CSprite("eel_wall_open", new CPosition(posX + 24, posY - 56, 0), Vector2.Zero); + _sprite[10] = new CSprite("eel_wall_open", new CPosition(posX - 40, posY + 56, 0), Vector2.Zero) { SpriteEffect = SpriteEffects.FlipVertically }; + _sprite[11] = new CSprite("eel_wall_open", new CPosition(posX + 24, posY + 56, 0), Vector2.Zero) { SpriteEffect = SpriteEffects.FlipVertically }; + + _sprite[12] = new CSprite("eel_wall", new CPosition(posX - 40, posY - 72, 0), Vector2.Zero) { SpriteEffect = SpriteEffects.FlipVertically }; + _sprite[13] = new CSprite("eel_wall", new CPosition(posX + 24, posY - 72, 0), Vector2.Zero) { SpriteEffect = SpriteEffects.FlipVertically }; + _sprite[14] = new CSprite("eel_wall", new CPosition(posX - 40, posY + 72, 0), Vector2.Zero); + _sprite[15] = new CSprite("eel_wall", new CPosition(posX + 24, posY + 72, 0), Vector2.Zero); + + _sprite[16] = new CSprite("eel_wall", new CPosition(posX - 40, posY - 56, 0), Vector2.Zero); + _sprite[17] = new CSprite("eel_wall", new CPosition(posX + 24, posY - 56, 0), Vector2.Zero); + _sprite[18] = new CSprite("eel_wall", new CPosition(posX - 40, posY + 56, 0), Vector2.Zero) { SpriteEffect = SpriteEffects.FlipVertically }; + _sprite[19] = new CSprite("eel_wall", new CPosition(posX + 24, posY + 56, 0), Vector2.Zero) { SpriteEffect = SpriteEffects.FlipVertically }; + + // moved down so that we draw over the door + EntityPosition = new CPosition(posX + 8, posY + 64, 0); + EntitySize = new Rectangle(-80, -120, 160, 128); + + _fieldRectangle = Map.GetField(posX, posY, 16); + + // ~4 sec for turn + _rotationSpeed = (MathF.PI * 2) / 60 / 4; + + for (var i = 0; i < _tailParts.Length; i++) + { + var spriteIndex = i < 4 ? 1 : 2; + if (i == 0) + spriteIndex = 0; + + _tailParts[i] = new BossSlimeEelTail(map, _centerPosition, spriteIndex, null); + map.Objects.SpawnObject(_tailParts[i]); + } + + _slimeEel = new BossSlimeEel(map, _centerPosition, this, saveKey); + map.Objects.SpawnObject(_slimeEel); + + var stateHidden = new AiState(UpdateHidden); + var stateSpawn = new AiState(UpdateSpawn); + var stateIdle = new AiState(UpdateIdle); + var stateDespawn = new AiState(UpdateDespawn); + + _aiComponent = new AiComponent(); + + _aiComponent.States.Add("hidden", stateHidden); + _aiComponent.States.Add("spawn", stateSpawn); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("despawn", stateDespawn); + + _aiComponent.ChangeState("hidden"); + + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBottom, EntityPosition)); + } + + public void SetTailState(float tailState) + { + _tailComeOut = false; + _tailState = tailState; + } + + public void ToDespawn() + { + _aiComponent.ChangeState("despawn"); + } + + public void ChangeRotation() + { + _rotationDirection = -_rotationDirection; + } + + public void SetTailIsMoving(bool isMoving) + { + _tailComeOut = true; + _tailIsMoving = isMoving; + } + + private void UpdateHidden() + { + // player entered the room? + if (_fieldRectangle.Contains(MapManager.ObjLink.BodyRectangle)) + { + Game1.GameManager.StartDialogPath("slime_eel"); + _aiComponent.ChangeState("spawn"); + } + } + + private void UpdateSpawn() + { + _spawnCounter += Game1.DeltaTime; + var spawnTime = 900; + var endTime = 5500 + spawnTime * 4; + + if(_spawnState == SpawnState.Shake || _spawnState == SpawnState.FloorBreak) + { + // @TODO: sound effect; gets louder over time + _shakeSoundCounter -= Game1.DeltaTime; + if (_shakeSoundCounter < 0) + { + _shakeSoundCounter += 150; + Game1.GameManager.PlaySoundEffect("D378-61-3E", true); + } + } + + if (_spawnState == SpawnState.Init && _spawnCounter > 1000) + { + _spawnState = SpawnState.Shake; + Game1.GameManager.ShakeScreen(endTime, 1, 2, 6.5f, 4.5f); + } + else if (_spawnState == SpawnState.Shake && _spawnCounter > 2000) + { + _spawnState = SpawnState.FloorBreak; + + for (var i = 0; i < 4; i++) + _sprite[4 + i].IsVisible = false; + } + else if (_spawnState == SpawnState.FloorBreak && _spawnCounter > 3000) + { + _spawnState = SpawnState.FloorGone; + + for (var i = 0; i < 4; i++) + _sprite[i].IsVisible = false; + _isVisible = true; + + SpawnStonesCenter(); + SpawnHoles(); + } + else if (_spawnState == SpawnState.FloorGone && _spawnCounter > 5500) + { + _spawnState = SpawnState.Wall0; + _sprite[16].IsVisible = false; + _slimeEel.SpawnAttack(0); + + SpawnStonesWall((int)_centerPosition.X - 32, (int)_centerPosition.Y - 56, 1); + } + else if (_spawnState == SpawnState.Wall0 && _spawnCounter > 6000) + { + _spawnState = SpawnState.ShakeEnd; + + } + else if (_spawnState == SpawnState.ShakeEnd && _spawnCounter > 5500 + spawnTime) + { + _spawnState = SpawnState.Wall1; + _sprite[17].IsVisible = false; + _slimeEel.SpawnAttack(1); + + SpawnStonesWall((int)_centerPosition.X + 32, (int)_centerPosition.Y - 56, 1); + } + else if (_spawnState == SpawnState.Wall1 && _spawnCounter > 5500 + spawnTime * 2) + { + _spawnState = SpawnState.Wall2; + _sprite[18].IsVisible = false; + _slimeEel.SpawnAttack(2); + + SpawnStonesWall((int)_centerPosition.X - 32, (int)_centerPosition.Y + 48, -1); + } + else if (_spawnState == SpawnState.Wall2 && _spawnCounter > 5500 + spawnTime * 3) + { + _spawnState = SpawnState.Wall3; + _sprite[19].IsVisible = false; + _slimeEel.SpawnAttack(3); + + SpawnStonesWall((int)_centerPosition.X + 32, (int)_centerPosition.Y + 48, -1); + } + else if (_spawnState == SpawnState.Wall3 && _spawnCounter > endTime) + { + _aiComponent.ChangeState("idle"); + _slimeEel.ToSpawned(); + } + + if (_isVisible) + { + // move the tail out of the hole + _tailState += Game1.TimeMultiplier * 0.025f; + if (_tailState > 1) + _tailState = 1; + + // move the tail left/right + _rotation = -MathF.Sin((_spawnCounter - 3000) / (endTime - 3000) * MathF.PI * 7) * 0.35f; + } + + UpdateTail(); + } + + private void SpawnStonesCenter() + { + SpawnStoneLine((int)_centerPosition.X - 10, (int)_centerPosition.Y - 12, -1); + SpawnStoneLine((int)_centerPosition.X - 4, (int)_centerPosition.Y - 12, -0.25f); + SpawnStoneLine((int)_centerPosition.X + 4, (int)_centerPosition.Y - 12, 0.25f); + SpawnStoneLine((int)_centerPosition.X + 10, (int)_centerPosition.Y - 12, 1f); + } + + private void SpawnStoneLine(int posX, int posY, float dir) + { + var randomOffset0 = Game1.RandomNumber.Next(80, 120) / 100f; + var randomOffset1 = Game1.RandomNumber.Next(80, 120) / 100f; + var randomOffset2 = Game1.RandomNumber.Next(80, 120) / 100f; + + var stone0 = new ObjSmallStone(Map, posX, posY, 0, new Vector3(dir * 0.35f, -0.25f, 1.25f) * randomOffset0, true); + var stone1 = new ObjSmallStone(Map, posX, posY + 6, 0, new Vector3(dir * 0.35f, 0.0f, 1.25f) * randomOffset1, true); + var stone2 = new ObjSmallStone(Map, posX, posY + 12, 0, new Vector3(dir * 0.35f, 0.25f, 1.25f) * randomOffset2, true); + + Map.Objects.SpawnObject(stone0); + Map.Objects.SpawnObject(stone1); + Map.Objects.SpawnObject(stone2); + } + + private void SpawnStonesWall(int posX, int posY, int dir) + { + Game1.GameManager.PlaySoundEffect("D378-12-0C"); + + var randomOffset0 = Game1.RandomNumber.Next(90, 110) / 100f; + var randomOffset1 = Game1.RandomNumber.Next(90, 110) / 100f; + var randomOffset2 = Game1.RandomNumber.Next(90, 110) / 100f; + var randomOffset3 = Game1.RandomNumber.Next(90, 110) / 100f; + + var stone0 = new ObjSmallStone(Map, posX - 5, posY + 2 * dir, 0, new Vector3(-0.15f, 0.95f * dir, 0.85f) * randomOffset0, true); + var stone1 = new ObjSmallStone(Map, posX - 7, posY, 0, new Vector3(-0.45f, 0.75f * dir, 0.85f) * randomOffset1, true); + var stone2 = new ObjSmallStone(Map, posX + 5, posY + 2 * dir, 0, new Vector3(0.15f, 0.95f * dir, 0.85f) * randomOffset2, true); + var stone3 = new ObjSmallStone(Map, posX + 7, posY, 0, new Vector3(0.45f, 0.75f * dir, 0.85f) * randomOffset3, true); + + Map.Objects.SpawnObject(stone0); + Map.Objects.SpawnObject(stone1); + Map.Objects.SpawnObject(stone2); + Map.Objects.SpawnObject(stone3); + } + + private void SpawnHoles() + { + for (var i = 0; i < 4; i++) + { + var hole = new ObjHole(Map, + (int)_centerPosition.X - 16 + (i % 2) * 16, + (int)_centerPosition.Y - 16 + (i / 2) * 16, 16, 16, Rectangle.Empty, 0, 0, 0); + Map.Objects.SpawnObject(hole); + } + } + + private void UpdateDespawn() + { + _tailState -= Game1.TimeMultiplier * 0.025f; + if (_tailState <= 0) + { + _tailState = 0; + _isVisible = false; + } + + UpdateTail(); + } + + private void UpdateIdle() + { + if (_tailIsMoving) + _rotation += Game1.TimeMultiplier * _rotationSpeed * _rotationDirection; + + if (_tailComeOut) + { + _tailState += Game1.TimeMultiplier * 0.025f; + if (_tailState > 1) + _tailState = 1; + } + + UpdateTail(); + } + + private void UpdateTail() + { + var tailLength = _tailState * 47; + + var parts = (int)(tailLength / 10) + 1; + if (!_isVisible) + parts = 0; + + _tailIndex = 5 - parts; + + for (var i = 0; i < 5 - parts; i++) + _tailParts[i].SetActive(false); + + var lastPosition = Vector2.Zero; + for (var i = 0; i < parts; i++) + { + var index = 5 - parts + i; + _tailParts[index].SetActive(true); + + // rotate the tip farther in the rotation direction + var dist = ((tailLength - (parts - 1 - i) * 10) / 47f); + var mult = dist * dist; + var rotation = _rotation - MathF.Sin(MathF.PI + _rotation * 2) * 0.75f * mult; + var newPosition = new Vector2(MathF.Sin(rotation), -MathF.Cos(rotation)) * (tailLength - (parts - 1 - i) * 10); + + if (i > 0) + { + // make sure that the distance between the parts is 10 + var direction = newPosition - lastPosition; + direction.Normalize(); + newPosition = lastPosition + direction * 10; + } + + lastPosition = newPosition; + _tailParts[index].EntityPosition.Set(_centerPosition + newPosition); + } + } + + private void Draw(SpriteBatch spriteBatch) + { + for (var i = 0; i < _sprite.Length; i++) + _sprite[i].Draw(spriteBatch); + + // we cant let the object have its own draw method because we could not set the draw order + if (_isVisible) + for (var i = _tailIndex; i < _tailParts.Length; i++) + _tailParts[i].Sprite.Draw(spriteBatch); + } + + private void SpawnHeart() + { + // spawn big heart + Map.Objects.SpawnObject(new ObjItem(Map, + (int)_centerPosition.X - 8, (int)_centerPosition.Y - 32, "j", "d5_nHeart", "heartMeterFull", null)); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossSlimeEelTail.cs b/InGame/GameObjects/Bosses/BossSlimeEelTail.cs new file mode 100644 index 0000000..71d3715 --- /dev/null +++ b/InGame/GameObjects/Bosses/BossSlimeEelTail.cs @@ -0,0 +1,42 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + class BossSlimeEelTail : GameObject + { + public CSprite Sprite; + + private readonly DamageFieldComponent _damageFieldComponent; + + public BossSlimeEelTail() : base("slime eel") { } + + public BossSlimeEelTail(Map.Map map, Vector2 position, int spriteIndex, HittableComponent.HitTemplate onHit) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(position.X, position.Y, 0); + EntitySize = new Rectangle(-8, -8, 16, 16); + + Sprite = new CSprite("eel_tail_" + spriteIndex, EntityPosition, spriteIndex == 1 ? new Vector2(-7) : new Vector2(-8)); + + var damageCollider = new CBox(EntityPosition, -6, -6, 12, 12, 2); + + AddComponent(DamageFieldComponent.Index, _damageFieldComponent = new DamageFieldComponent(damageCollider, HitType.Enemy, 2)); + + if (onHit != null) + { + var hittableCollider = new CBox(EntityPosition, -6, -6, 12, 12, 8); + AddComponent(HittableComponent.Index, new HittableComponent(hittableCollider, onHit)); + } + } + + public void SetActive(bool state) + { + _damageFieldComponent.IsActive = state; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossSlimeEye.cs b/InGame/GameObjects/Bosses/BossSlimeEye.cs new file mode 100644 index 0000000..c7610d5 --- /dev/null +++ b/InGame/GameObjects/Bosses/BossSlimeEye.cs @@ -0,0 +1,271 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Enemies; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + class BossSlimeEye : GameObject + { + private readonly EnemyGreenZol[] _zols = new EnemyGreenZol[2]; + + private readonly CSprite _sprite; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _damageState; + private readonly Animator _animator; + private readonly BodyDrawShadowComponent _shadowComponent; + + private readonly Vector2 _startPosition; + + private readonly string _enterKey; + private readonly string _triggerKey; + private readonly string _saveKey; + + private float _damageCounter; + private float _lastStartDistance; + private float _moveDistance; + + private int _fallHeight = 128; + + public BossSlimeEye() : base("slime_eye") { } + + public BossSlimeEye(Map.Map map, int posX, int posY, string enterKey, string triggerKey, string saveKey) : base(map) + { + if (!string.IsNullOrWhiteSpace(saveKey) && Game1.GameManager.SaveManager.GetString(saveKey) == "1") + { + IsDead = true; + return; + } + + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 16, posY + 16, _fallHeight); + EntitySize = new Rectangle(-32, -32, 64, 32); + + _startPosition = EntityPosition.Position; + + _enterKey = enterKey; + _triggerKey = triggerKey; + _saveKey = saveKey; + + _animator = AnimatorSaveLoad.LoadAnimator("Nightmares/nightmare eye"); + _animator.Play("idle"); + + _sprite = new CSprite(EntityPosition); + _sprite.Color = Color.Transparent; + + var animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + var fieldRectangle = map.GetField(posX, posY, 16); + + _body = new BodyComponent(EntityPosition, -21, -24, 42, 24, 8) + { + FieldRectangle = fieldRectangle, + Bounciness = 0.25f, + Drag = 0.85f, + IgnoresZ = true, + IsGrounded = false + }; + + var hittableRectangle = new CBox(EntityPosition, -8, -16, 16, 16, 8); + var damageCollider = new CBox(EntityPosition, -21, -24, 42, 24, 8); + + var stateWaiting = new AiState(); + var stateSlimes = new AiState(); + stateSlimes.Trigger.Add(new AiTriggerRandomTime(TickSpawn, 1000, 1500)); + var stateFalling = new AiState(UpdateFalling); + var stateSpawning = new AiState(); + var stateStopped = new AiState(UpdateStopped); + stateStopped.Trigger.Add(new AiTriggerCountdown(1000, null, ToMoving)); + var stateMoving = new AiState(UpdateMoving); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("waiting", stateWaiting); + _aiComponent.States.Add("slimes", stateSlimes); + _aiComponent.States.Add("falling", stateFalling); + _aiComponent.States.Add("spawning", stateSpawning); + _aiComponent.States.Add("stopped", stateStopped); + _aiComponent.States.Add("moving", stateMoving); + _damageState = new AiDamageState(this, _body, _aiComponent, _sprite, 2, false); + + _aiComponent.ChangeState("waiting"); + + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 4)); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(_body.BodyBox, Values.CollisionTypes.Enemy)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableRectangle, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, _shadowComponent = new BodyDrawShadowComponent(_body, _sprite) + { + ShadowWidth = 42, + ShadowHeight = 12, + OffsetY = -1, + Height = Map.ShadowHeight * 1.25f, + IsActive = false + }); + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + } + + private void OnKeyChange() + { + if (!string.IsNullOrEmpty(_enterKey) && + Game1.GameManager.SaveManager.GetString(_enterKey) == "1" && + _aiComponent.CurrentStateId == "waiting") + { + Game1.GameManager.StartDialogPath("d3_boss"); + _aiComponent.ChangeState("slimes"); + } + + if (!string.IsNullOrEmpty(_triggerKey) && + Game1.GameManager.SaveManager.GetString(_triggerKey) == "1" && + _aiComponent.CurrentStateId == "slimes") + { + ToFalling(); + } + } + + private void TickSpawn() + { + for (var i = 0; i < _zols.Length; i++) + { + if (_zols[i] == null || _zols[i].Map == null) + { + var posX = Game1.RandomNumber.Next(0, 8); + var posY = Game1.RandomNumber.Next(0, 6); + // clamp the position to not land on a lamp + if (posY == 0 || posY == 5) + posX = Math.Clamp(posX, 1, 6); + + var position = new Vector2( + _body.FieldRectangle.X + posX * 16, + _body.FieldRectangle.Y + posY * 16); + + _zols[i] = new EnemyGreenZol(Map, (int)position.X, (int)position.Y, 100, true); + Map.Objects.SpawnObject(_zols[i]); + + return; + } + } + } + + private void ToFalling() + { + _aiComponent.ChangeState("falling"); + _body.IgnoresZ = false; + _shadowComponent.IsActive = true; + } + + private void UpdateFalling() + { + _sprite.Color = Color.White * + MathF.Min((_fallHeight - EntityPosition.Z) / 15f, 1); + + if (_body.IsGrounded) + { + Game1.GameManager.PlaySoundEffect("D378-12-0C"); + Game1.GameManager.ShakeScreen(500, 2, 4, 2.5f, 5.5f); + + MapManager.ObjLink.GroundStun(); + _aiComponent.ChangeState("stopped"); + } + } + + private void UpdateStopped() + { + UpdateAnimation(); + } + + private void ToMoving() + { + _aiComponent.ChangeState("moving"); + + var direction = _startPosition - EntityPosition.Position; + var radius = MathF.Atan2(direction.Y, direction.X) + Game1.RandomNumber.Next(-25, 25) / 100f; + _body.VelocityTarget = new Vector2(MathF.Cos(radius), MathF.Sin(radius)) * 0.1f; + + _moveDistance = Game1.RandomNumber.Next(0, 40) / 10f; + } + + private void UpdateMoving() + { + // move + var direction = _startPosition - EntityPosition.Position; + var distance = direction.Length(); + + if (_lastStartDistance < distance && distance > _moveDistance) + { + _body.VelocityTarget = Vector2.Zero; + _aiComponent.ChangeState("stopped"); + } + + _lastStartDistance = distance; + + UpdateAnimation(); + } + + private void UpdateAnimation() + { + _damageCounter -= Game1.DeltaTime; + if (_damageCounter < 0) + _damageCounter = 0; + if (_damageCounter > 6000) + _damageCounter = 6000; + + var strAnimation = "idle"; + if (0 < _damageCounter && _damageCounter <= 1400) + strAnimation = "split_0"; + else if (1400 < _damageCounter && _damageCounter <= 2800) + strAnimation = "split_1"; + else if (2800 < _damageCounter && _damageCounter <= 4200) + strAnimation = "split_2"; + else if (4200 < _damageCounter) + strAnimation = "split_3"; + + if (_animator.CurrentAnimation.Id != strAnimation) + _animator.Play(strAnimation); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_damageState.DamageTrigger.CurrentTime > 0) + return Values.HitCollision.None; + + Game1.GameManager.PlaySoundEffect("D370-07-07"); + + _damageState.SetDamageState(); + + // break apart + if (_damageCounter > 4200 && damageType == HitType.PegasusBootsSword) + { + var slimeHalfLeft = new BossSlimeEyeHalf(Map, new Vector2(EntityPosition.X - 18, EntityPosition.Y), "left", _saveKey); + var slimeHalfRight = new BossSlimeEyeHalf(Map, new Vector2(EntityPosition.X + 18, EntityPosition.Y), "right", _saveKey); + + Map.Objects.SpawnObject(slimeHalfLeft); + Map.Objects.SpawnObject(slimeHalfRight); + + Map.Objects.DeleteObjects.Add(this); + + return Values.HitCollision.RepellingParticle; + } + + _damageCounter += 1400; + + return Values.HitCollision.RepellingParticle; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Bosses/BossSlimeEyeHalf.cs b/InGame/GameObjects/Bosses/BossSlimeEyeHalf.cs new file mode 100644 index 0000000..038d866 --- /dev/null +++ b/InGame/GameObjects/Bosses/BossSlimeEyeHalf.cs @@ -0,0 +1,283 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + class BossSlimeEyeHalf : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _damageState; + private readonly Animator _animator; + private readonly PushableComponent _pushableComponent; + private readonly BodyDrawShadowComponent _shadowComponent; + private readonly CSprite _sprite; + + private Rectangle _fieldRectangle; + + private readonly string _saveKey; + private readonly string _halfKey; + + private const int Lives = 4; + private int _jumpHeight = 100; + + private bool _highJump; + private bool _wasHit; + private bool _doubleJump; + + public BossSlimeEyeHalf(Map.Map map, Vector2 position, string animationName, string saveKey) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(position.X, position.Y, 0); + EntitySize = new Rectangle(-16, -32, 32, 32); + + _saveKey = saveKey; + _halfKey = _saveKey + "half"; + + Game1.GameManager.SaveManager.SetString(_halfKey, "0"); + + _animator = AnimatorSaveLoad.LoadAnimator("Nightmares/nightmare eye"); + _animator.Play(animationName); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _fieldRectangle = map.GetField((int)position.X, (int)position.Y, 16); + + _body = new BodyComponent(EntityPosition, -12, -24, 24, 22, 8) + { + Bounciness = 0.25f, + Gravity = -0.15f, + Drag = 0.85f, + DragAir = 0.98f, + IgnoreHeight = true + }; + + var hittableRectangle = new CBox(EntityPosition, -14, -24, 0, 28, 22, 8, true); + var damageCollider = new CBox(EntityPosition, -14, -24, 28, 22, 8); + + var stateInit = new AiState(); + stateInit.Trigger.Add(new AiTriggerCountdown(50, null, InitJump)); // 166 + var stateWaiting = new AiState(UpdateWaiting); + stateWaiting.Trigger.Add(new AiTriggerRandomTime(ToJumping, 750, 1250)); + var stateJumping = new AiState(UpdateJumping); + var stateHighJumping = new AiState(); + stateHighJumping.Trigger.Add(new AiTriggerCountdown(300, UpdateHighJump, () => UpdateHighJump(0f))); + var stateHighJumpingWait = new AiState(); + stateHighJumpingWait.Trigger.Add(new AiTriggerRandomTime(EndHighjump, 500, 1000)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("init", stateInit); + _aiComponent.States.Add("waiting", stateWaiting); + _aiComponent.States.Add("jumping", stateJumping); + _aiComponent.States.Add("highJump", stateHighJumping); + _aiComponent.States.Add("highJumpWaiting", stateHighJumpingWait); + _damageState = new AiDamageState(this, _body, _aiComponent, _sprite, Lives, false) { BossHitSound = true }; + _damageState.AddBossDamageState(OnDeath); + + _aiComponent.ChangeState("init"); + + _pushableComponent = new PushableComponent(_body.BodyBox, OnPush); + AddComponent(PushableComponent.Index, _pushableComponent); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 4)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableRectangle, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, _shadowComponent = new BodyDrawShadowComponent(_body, _sprite) + { + ShadowWidth = 26, + ShadowHeight = 8, + OffsetY = -2, + Height = Map.ShadowHeight * 1.25f + }); + + _damageState.SetDamageState(); + } + + private void InitJump() + { + _aiComponent.ChangeState("jumping"); + + var direction = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + if (direction != Vector2.Zero) + direction.Normalize(); + + _body.Velocity = new Vector3(direction * 1.5f, 2.5f); + } + + private void UpdateWaiting() + { + // start with the high jump? + if (_wasHit && _body.Velocity.Length() < 0.25f) + ToHighjump(); + + UpdateAnimation(); + } + + private void ToJumping() + { + if (_wasHit) + return; + + _aiComponent.ChangeState("jumping"); + + // random direction + var direction = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + + float radius; + + // random direction + var toPlayer = false; + if (Game1.RandomNumber.Next(0, 4) < 3 && !_doubleJump) + { + radius = (Game1.RandomNumber.Next(0, 100) / 100f) * MathF.PI * 2; + } + else + { + toPlayer = true; + _doubleJump = false; + radius = MathF.Atan2(direction.Y, direction.X); + } + + // 50% chance to jump twice towards the player + _doubleJump = Game1.RandomNumber.Next(0, 2) == 0; + + var speed = (Game1.RandomNumber.Next(toPlayer ? 100 : 150, toPlayer ? 200 : 250) / 100f); + var jumpDirection = new Vector2(MathF.Cos(radius), MathF.Sin(radius)) * speed; + _body.Velocity = new Vector3(jumpDirection.X, jumpDirection.Y, 2); + } + + private void UpdateJumping() + { + _sprite.Color = Color.White * MathF.Min((_jumpHeight - EntityPosition.Z) / 15f, 1); + + if (_body.IsGrounded) + { + _body.Velocity = Vector3.Zero; + _aiComponent.ChangeState("waiting"); + _pushableComponent.IsActive = true; + + // came down from a high jump? -> shake the screen + if (_highJump) + { + _wasHit = false; + _highJump = false; + + MapManager.ObjLink.GroundStun(); + + Game1.GameManager.PlaySoundEffect("D360-11-0B"); + Game1.GameManager.ShakeScreen(250, 1, 2, 2.5f, 5.5f); + } + } + + UpdateAnimation(); + } + + private void ToHighjump() + { + _aiComponent.ChangeState("highJump"); + _body.Velocity = Vector3.Zero; + _body.IgnoresZ = true; + _highJump = true; + } + + private void UpdateHighJump(double time) + { + EntityPosition.Z = (1 - MathF.Sin(((float)time / 300) * MathF.PI / 2)) * _jumpHeight; + _sprite.Color = Color.White * MathF.Min((float)time / 50f, 1); + _shadowComponent.Transparency = MathF.Min((float)time / 50f, 1); + + if (time == 0) + _aiComponent.ChangeState("highJumpWaiting"); + + UpdateAnimation(); + } + + private void EndHighjump() + { + _aiComponent.ChangeState("jumping"); + + // clamp the position to land inside the room + var newPosition = MapManager.ObjLink.EntityPosition.Position; + newPosition.X = MathHelper.Clamp(newPosition.X, + _fieldRectangle.X + _body.Width / 2, _fieldRectangle.Right - _body.Width / 2); + newPosition.Y = MathHelper.Clamp(newPosition.Y + 8, + _fieldRectangle.Y - _body.OffsetY, + _fieldRectangle.Bottom - _body.OffsetY - _body.Height); + + EntityPosition.Set(newPosition); + + _body.Velocity.Z = 0; + _body.IgnoresZ = false; + + _shadowComponent.Transparency = 1; + } + + private void UpdateAnimation() + { + _animator.Play(_body.IsGrounded ? "half_floor" : "half_jump"); + } + + private void OnDeath() + { + if (!string.IsNullOrEmpty(_saveKey)) + { + var key = Game1.GameManager.SaveManager.GetString(_halfKey); + if (key != "1") + Game1.GameManager.SaveManager.SetString(_halfKey, "1"); + // killed both parts? + else + { + Game1.GameManager.PlaySoundEffect("D378-26-1A"); + Game1.GameManager.SetMusic(-1, 2); + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + // spawn big heart + Map.Objects.SpawnObject(new ObjItem(Map, + (int)EntityPosition.X - 8, (int)EntityPosition.Y - 24, "j", "d3_heartMeter", "heartMeterFull", null)); + } + } + + Map.Objects.DeleteObjects.Add(this); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_damageState.IsInDamageState()) + return Values.HitCollision.None; + + _damageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + + _body.Velocity.X = direction.X * 5f; + _body.Velocity.Y = direction.Y * 5f; + + _wasHit = true; + + return Values.HitCollision.Enemy; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type != PushableComponent.PushType.Impact) + return false; + + _wasHit = true; + + _body.Velocity.X = direction.X * 1.5f; + _body.Velocity.Y = direction.Y * 1.5f; + + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Dungeon/Obj2DMode.cs b/InGame/GameObjects/Dungeon/Obj2DMode.cs new file mode 100644 index 0000000..ea31c02 --- /dev/null +++ b/InGame/GameObjects/Dungeon/Obj2DMode.cs @@ -0,0 +1,22 @@ +using ProjectZ.InGame.GameObjects.Base; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + public class Obj2DMode : GameObject + { + public Obj2DMode() : base("editor 2d mode") { } + + public Obj2DMode(Map.Map map, int posX, int posY) : base(map) + { + // @HACK: value gets set while adding the object to the ObjectList + + // set the map to be a 2d map + // maybe this should be inside the none existent map settings? + // this will probably lead to bugs when other objects expect this to be set in the constructor + // Game1.GameManager.MapManager.NextMap + //map.Is2dMap = true; + + IsDead = true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Dungeon/ObjBall.cs b/InGame/GameObjects/Dungeon/ObjBall.cs new file mode 100644 index 0000000..7688e2d --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjBall.cs @@ -0,0 +1,259 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + internal class ObjBall : GameObject + { + private readonly DamageFieldComponent _damageField; + private readonly AiComponent _aiComponent; + private readonly AiTriggerSwitch _repelSwitch; + private readonly DrawCSpriteComponent _drawComponent; + private readonly BodyDrawShadowComponent _shadowComponent; + private readonly BodyComponent _body; + private readonly CBox _damageBox; + + private readonly Vector2 _spawnPosition; + + private readonly string _saveStringPosX; + private readonly string _saveStringPosY; + + private bool _hitEnemies; + private bool _absorbed; + private bool _hasMoved; + + public ObjBall() : base("ball") { } + + public ObjBall(Map.Map map, int posX, int posY, string saveKey) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -32, 16, 32); + + _saveStringPosX = saveKey + "_posX"; + _saveStringPosY = saveKey + "_posY"; + + _spawnPosition = EntityPosition.Position; + + // load the position of the ball if it was already picked up + LoadPosition(); + + // this is the same size as the player so that it can not get thrown into the wall + _body = new BodyComponent(EntityPosition, -4, -10, 8, 10, 14) + { + CollisionTypes = Values.CollisionTypes.Normal | Values.CollisionTypes.NPCWall, + CollisionTypesIgnore = Values.CollisionTypes.ThrowIgnore, + MoveCollision = Collision, + DragAir = 1.0f, + Gravity = -0.125f, + Bounciness = 0.6f, + HoleAbsorb = OnHoleAbsorb, + //MaxJumpHeight = 3, // make sure that we can not throw the ball over a barrier + }; + + var cSprite = new CSprite("ball", EntityPosition, new Vector2(-7, -15)); + + var stateIdle = new AiState(UpdateIdle); + var stateAbsorb = new AiState(); + stateAbsorb.Trigger.Add(new AiTriggerCountdown(100, null, EndAbsorb)); + var stateWaiting = new AiState(); + stateWaiting.Trigger.Add(new AiTriggerCountdown(650, null, EndWait)); + + _aiComponent = new AiComponent(); + _aiComponent.Trigger.Add(_repelSwitch = new AiTriggerSwitch(250)); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("absorb", stateAbsorb); + _aiComponent.States.Add("wait", stateWaiting); + _aiComponent.ChangeState("idle"); + + var bodyBox = new CBox(EntityPosition, -7, -12, 14, 12, 14); + _damageBox = new CBox(EntityPosition, -7, -14, 0, 14, 14, 14, true); + + AddComponent(BodyComponent.Index, _body); + AddComponent(CarriableComponent.Index, new CarriableComponent( + new CRectangle(EntityPosition, new Rectangle(-7, -14, 14, 14)), CarryInit, CarryUpdate, CarryThrow)); + AddComponent(PushableComponent.Index, new PushableComponent(bodyBox, OnPush)); + AddComponent(HittableComponent.Index, new HittableComponent(bodyBox, OnHit)); + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(_damageBox, HitType.ThrownObject, 2) { IsActive = false }); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, _drawComponent = new DrawCSpriteComponent(cSprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, _shadowComponent = new BodyDrawShadowComponent(_body, cSprite)); + } + + private void UpdateIdle() + { + // save the position when the ball stops moving + if (_body.IsGrounded && _body.Velocity == Vector3.Zero && _hasMoved) + { + // not sure where else this could be done; ideally there would be a despawn function an object could use + // but this should work fine + SavePosition(); + } + + _hasMoved = _body.Velocity != Vector3.Zero; + } + + private void OnHoleAbsorb() + { + if (_absorbed) + return; + + _absorbed = true; + _aiComponent.ChangeState("absorb"); + } + + private void EndAbsorb() + { + // play sound effect + Game1.GameManager.PlaySoundEffect("D360-24-18"); + + var fallAnimation = new ObjAnimator(Map, 0, 0, Values.LayerBottom, "Particles/fall", "idle", true); + fallAnimation.EntityPosition.Set(new Vector2( + _body.Position.X + _body.OffsetX + _body.Width / 2.0f - 5, + _body.Position.Y + _body.OffsetY + _body.Height / 2.0f - 5)); + Map.Objects.SpawnObject(fallAnimation); + + ToWait(); + + // reset the ball to the initial position + _body.Velocity.Z = -0.5f; + EntityPosition.Set(new Vector3(_spawnPosition.X, _spawnPosition.Y, 32)); + + SavePosition(); + } + + private void ToWait() + { + _aiComponent.ChangeState("wait"); + _drawComponent.IsActive = false; + _shadowComponent.IsActive = false; + _body.IsActive = false; + } + + private void EndWait() + { + _absorbed = false; + _drawComponent.IsActive = true; + _shadowComponent.IsActive = true; + _body.IsActive = true; + } + + private void Update() + { + if (_hitEnemies) + { + var collision = Map.Objects.Hit(this, EntityPosition.Position, _damageBox.Box, HitType.ThrownObject, 2, false); + if (collision != Values.HitCollision.None) + { + _body.Velocity.X = -_body.Velocity.X * 0.45f; + _body.Velocity.Y = -_body.Velocity.Y * 0.45f; + } + } + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + // do not get hit by itself + if (originObject == this) + return Values.HitCollision.None; + + if (_repelSwitch.State) + { + _repelSwitch.Reset(); + _body.Velocity.X = direction.X * 0.5f; + _body.Velocity.Y = direction.Y * 0.5f; + return Values.HitCollision.RepellingParticle; + } + + return Values.HitCollision.None; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType pushType) + { + if (pushType == PushableComponent.PushType.Impact) + return true; + + return false; + } + + private Vector3 CarryInit() + { + // the ball was picked up + _body.IsActive = false; + + return new Vector3(EntityPosition.X, EntityPosition.Y, EntityPosition.Z); + } + + private bool CarryUpdate(Vector3 newPosition) + { + EntityPosition.Set(new Vector3(newPosition.X, newPosition.Y, newPosition.Z)); + return true; + } + + private void CarryThrow(Vector2 velocity) + { + Release(); + _body.Velocity = new Vector3(velocity * 0.825f, 0.5f); + _body.Level = MapStates.GetLevel(MapManager.ObjLink._body.CurrentFieldState); + _body.DragAir = 1.0f; + _hitEnemies = true; + } + + private void Release() + { + _body.JumpStartHeight = 0; + _body.IsGrounded = false; + _body.IsActive = true; + } + + private void Collision(Values.BodyCollision direction) + { + if ((direction & Values.BodyCollision.Floor) != 0) + { + // stop hitting the player/boss when the ball touches the ground + _damageField.IsActive = false; + _hitEnemies = false; + _body.Level = 0; + _body.DragAir *= 0.965f; + Game1.GameManager.PlaySoundEffect("D378-23-17"); + } + + if ((direction & Values.BodyCollision.Horizontal) != 0) + { + Game1.GameManager.PlaySoundEffect("D360-07-07"); + _body.Velocity.X = -_body.Velocity.X * 0.45f; + } + if ((direction & Values.BodyCollision.Vertical) != 0) + { + Game1.GameManager.PlaySoundEffect("D360-07-07"); + _body.Velocity.Y = -_body.Velocity.Y * 0.45f; + } + } + + private void LoadPosition() + { + if (string.IsNullOrEmpty(_saveStringPosX)) + return; + + var posX = Game1.GameManager.SaveManager.GetInt(_saveStringPosX, (int)EntityPosition.X); + var posY = Game1.GameManager.SaveManager.GetInt(_saveStringPosY, (int)EntityPosition.Y); + + EntityPosition.Set(new Vector2(posX, posY)); + } + + private void SavePosition() + { + if (string.IsNullOrEmpty(_saveStringPosX)) + return; + + Game1.GameManager.SaveManager.SetInt(_saveStringPosX, (int)EntityPosition.X); + Game1.GameManager.SaveManager.SetInt(_saveStringPosY, (int)EntityPosition.Y); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Dungeon/ObjBreakingFloor.cs b/InGame/GameObjects/Dungeon/ObjBreakingFloor.cs new file mode 100644 index 0000000..9783d94 --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjBreakingFloor.cs @@ -0,0 +1,107 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + // TODO: this needs some kind of effect while standing on + internal class ObjBreakingFloor : GameObject + { + private readonly DrawSpriteComponent _drawComponent; + private readonly ObjHole _objHole; + + private readonly Box _collisionBox; + + private const int BreakTime = 750; + private float _breakCounter; + + private const int RespawnTime = 15000; + private float _respawnCounter; + + private bool _isActive; + + public ObjBreakingFloor(Map.Map map, int posX, int posY, string spriteId) : base(map, spriteId) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + var margin = 4; + _collisionBox = new Box(posX, posY + margin, 0, 16, 16 - margin * 2, 1); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, _drawComponent = new DrawSpriteComponent(spriteId, EntityPosition, Vector2.Zero, Values.LayerBottom)); + + _objHole = new ObjHole(Map, (int)EntityPosition.X, (int)EntityPosition.Y, 16, 14, Rectangle.Empty, 0, 1, 0); + _objHole.IsActive = false; + Map.Objects.SpawnObject(_objHole); + } + + private void Update() + { + if (!_isActive) + { + // respawn the floor after some time + _respawnCounter -= Game1.DeltaTime; + if (_respawnCounter <= 0) + Activate(); + + return; + } + + // is the player standing on the floor tile? + if (MapManager.ObjLink._body.BodyBox.Box.Intersects(_collisionBox)) + { + if (MapManager.ObjLink.CurrentState != ObjLink.State.Idle && + MapManager.ObjLink.CurrentState != ObjLink.State.Stunned) + return; + + _breakCounter += Game1.DeltaTime; + + // reset the time while hitting; in dungeon 8 there is a lot of breaking floor with enemies ontop that would be otherwise really hard to clear + if (MapManager.ObjLink.CurrentState == ObjLink.State.Attacking) + _breakCounter = 0; + + // spawn the hole and delete itself + if (_breakCounter >= BreakTime) + { + Game1.GameManager.PlaySoundEffect("D378-43-2B"); + Deactivate(); + } + } + else + { + // reset the time + _breakCounter -= Game1.DeltaTime * 1.5f; + if (_breakCounter < 0) + _breakCounter = 0; + } + } + + private void Activate() + { + _breakCounter = 0; + + _isActive = true; + _drawComponent.IsActive = true; + + // activate the hole + _objHole.IsActive = false; + } + + private void Deactivate() + { + _respawnCounter = RespawnTime; + + _isActive = false; + _drawComponent.IsActive = false; + + // activate the hole + _objHole.IsActive = true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Dungeon/ObjButtonOrder.cs b/InGame/GameObjects/Dungeon/ObjButtonOrder.cs new file mode 100644 index 0000000..fbf72e0 --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjButtonOrder.cs @@ -0,0 +1,114 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + internal class ObjButtonOrder : GameObject + { + private readonly CSprite _sprite; + private readonly Rectangle _effectSourceRectangle = new Rectangle(66, 258, 12, 12); + private readonly Box _collisionBox; + + private readonly string _strStateKey; + private readonly string _strKey; + private readonly int _index; + + private float _effectCounter; + private bool _isActive; + private bool _wasColliding; + + public ObjButtonOrder(Map.Map map, int posX, int posY, int index, string strStateKey, string strKey, bool drawSprite) : base(map, "button") + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + _index = index; + _strStateKey = strStateKey; + _strKey = strKey; + + var animator = AnimatorSaveLoad.LoadAnimator("Particles/buttonOrder"); + animator.Play("idle"); + + if (drawSprite) + { + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(animator, _sprite, new Vector2(8, 8)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + } + + _collisionBox = new Box(posX + 4, posY + 4, 0, 8, 8, 1); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBottom, EntityPosition)); + } + + private void Update() + { + if (_effectCounter > 0) + _effectCounter -= Game1.DeltaTime; + else + _effectCounter = 0; + + var isColliding = MapManager.ObjLink._body.BodyBox.Box.Intersects(_collisionBox); + if (isColliding && !_wasColliding) + { + if (_isActive) + { + _effectCounter = 375; + + // activate the next field + Game1.GameManager.SaveManager.SetString(_strStateKey, (_index + 1).ToString()); + + if (!string.IsNullOrEmpty(_strKey)) + Game1.GameManager.SaveManager.SetString(_strKey, "1"); + + Game1.GameManager.PlaySoundEffect("D360-19-13"); + } + else + { + if (!string.IsNullOrEmpty(_strStateKey)) + Game1.GameManager.SaveManager.SetString(_strStateKey, "0"); + } + } + _wasColliding = isColliding; + } + + private void Draw(SpriteBatch spriteBatch) + { + if (_isActive && _sprite != null) + _sprite.Draw(spriteBatch); + + // effect gets played after pressing the button + if (_effectCounter > 0) + { + var radian = (_effectCounter / 300) * MathF.PI; + var offset = new Vector2(-MathF.Sin(radian), MathF.Cos(radian)); + + var pos0 = new Vector2(EntityPosition.X + 8 - 6, EntityPosition.Y + 8 - 6) + offset * 14; + spriteBatch.Draw(Resources.SprItem, pos0, _effectSourceRectangle, Color.White); + + var pos1 = new Vector2(EntityPosition.X + 8 - 6, EntityPosition.Y + 8 - 6) - offset * 14; + spriteBatch.Draw(Resources.SprItem, pos1, _effectSourceRectangle, Color.White); + } + } + + private void KeyChanged() + { + if (!string.IsNullOrEmpty(_strStateKey)) + { + var state = Game1.GameManager.SaveManager.GetString(_strStateKey); + _isActive = state == _index.ToString(); + } + + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Dungeon/ObjColorJumpTile.cs b/InGame/GameObjects/Dungeon/ObjColorJumpTile.cs new file mode 100644 index 0000000..e082454 --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjColorJumpTile.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Enemies; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + internal class ObjColorJumpTile : GameObject + { + private readonly List _collidingObjects = new List(); + private readonly DictAtlasEntry[] _sprites = new DictAtlasEntry[3]; + + private readonly CSprite _sprite; + private readonly ObjHole _objHole; + + private bool _restoreMode; + private float _restoreCounter; + + private int _currentState; + private readonly int _startState; + + private Rectangle _collisionRectangle; + private Rectangle _fieldRectangle; + + public ObjColorJumpTile() : base("color_tile_0") { } + + public ObjColorJumpTile(Map.Map map, int posX, int posY, int state) : base(map) + { + Tags = Values.GameObjectTag.None; + + _sprites[0] = Resources.GetSprite("color_tile_0"); + _sprites[1] = Resources.GetSprite("color_tile_1"); + _sprites[2] = Resources.GetSprite("color_tile_2"); + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + _startState = Math.Clamp(state, 0, 2); + _currentState = _startState; + _collisionRectangle = new Rectangle(posX, posY, Values.TileSize, Values.TileSize); + + _fieldRectangle = map.GetField(posX, posY); + + _sprite = new CSprite(_sprites[_currentState], EntityPosition, Vector2.Zero); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + var drawComponent = new DrawCSpriteComponent(_sprite, Values.LayerBottom); + AddComponent(DrawComponent.Index, drawComponent); + + _restoreCounter = Game1.RandomNumber.Next(500, 1500); + + // spawn hole; delete jump object + _objHole = new ObjHole(Map, (int)EntityPosition.X, (int)EntityPosition.Y, 16, 14, Rectangle.Empty, 0, 1, 0) { IsActive = false }; + Map.Objects.SpawnObject(_objHole); + } + + private void Update() + { + // when the player leaves the room the tiles will get restored to there original state + if (_currentState != _startState && !_fieldRectangle.Contains(MapManager.ObjLink.EntityPosition.Position)) + { + _restoreMode = true; + } + + if (_restoreMode) + { + _restoreCounter -= Game1.DeltaTime; + + if (_restoreCounter <= 0) + { + _restoreCounter = Game1.RandomNumber.Next(500, 1500); + OffsetState(-1); + + if (_currentState == _startState) + _restoreMode = false; + } + } + + if (_currentState == 3) + return; + + _collidingObjects.Clear(); + Map.Objects.GetComponentList(_collidingObjects, + _collisionRectangle.X, _collisionRectangle.Y, _collisionRectangle.Width, _collisionRectangle.Height, BodyComponent.Mask); + + foreach (var collidingObject in _collidingObjects) + { + // is the player standing on the tile -> jump + if (collidingObject is ObjLink link && + _collisionRectangle.Contains(link._body.BodyBox.Box.Center) && link._body.IsGrounded) + { + link.StartJump(); + OffsetState(1); + } + // could be changed to work with all bodies; but things like bombs are not affected by the tile + else if (collidingObject is EnemyBonePutter bonePutter && + collidingObject.Components[BodyComponent.Index] is BodyComponent bodyComponent) + { + if (bonePutter.StartJump() && + _collisionRectangle.Contains(bodyComponent.BodyBox.Box.Center)) + { + OffsetState(1); + } + } + } + + } + + private void OffsetState(int offset) + { + _currentState += offset; + _currentState = MathHelper.Clamp(_currentState, _startState, 3); + + // set the sprite + if (_currentState < 3) + _sprite.SetSprite(_sprites[_currentState]); + + _sprite.IsVisible = _currentState != 3; + + // activate/deactivate the hole if the tile is gone + _objHole.IsActive = _currentState == 3; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Dungeon/ObjDestroyableBarrier.cs b/InGame/GameObjects/Dungeon/ObjDestroyableBarrier.cs new file mode 100644 index 0000000..82d4c59 --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjDestroyableBarrier.cs @@ -0,0 +1,117 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + internal class ObjDestroyableBarrier : GameObject + { + public readonly string SaveKey; + private readonly string _pushString; + private readonly bool _playSound; + + public ObjDestroyableBarrier(Map.Map map, int posX, int posY, Rectangle sourceRectangle, string saveId, int rotation, bool playSound, string pushString) : base(map) + { + EditorIconSource = sourceRectangle; + SprEditorImage = Resources.SprObjects; + + EntityPosition = new CPosition( + posX + sourceRectangle.Width / 2f, + posY + sourceRectangle.Height / 2f, 0); + EntitySize = new Rectangle(-sourceRectangle.Width / 2, -sourceRectangle.Height / 2, sourceRectangle.Width, sourceRectangle.Height); + + // don't spawn the wall if it was already destroyed + if (!string.IsNullOrEmpty(saveId) && + Game1.GameManager.SaveManager.GetString(saveId) == "1") + { + IsDead = true; + return; + } + + SaveKey = saveId; + _playSound = playSound; + _pushString = pushString; + + var box = new CBox(EntityPosition.X + EntitySize.X, EntityPosition.Y + EntitySize.Y, 0, sourceRectangle.Width, sourceRectangle.Height, 16); + var sprite = new CSprite(Resources.SprObjects, EntityPosition, EditorIconSource, new Vector2(0, 0)); + sprite.Center = new Vector2(sourceRectangle.Width / 2f, sourceRectangle.Height / 2f); + sprite.Rotation = rotation * MathF.PI / 2f; + + if (!string.IsNullOrEmpty(saveId)) + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + if (!string.IsNullOrEmpty(_pushString)) + AddComponent(PushableComponent.Index, new PushableComponent(box, OnPush)); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(box, Values.CollisionTypes.Normal | Values.CollisionTypes.Destroyable)); + AddComponent(HittableComponent.Index, new HittableComponent(box, OnHit)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerBottom)); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType pushType) + { + Game1.GameManager.StartDialogPath(_pushString); + return false; + } + + private void OnKeyChange() + { + if (Game1.GameManager.SaveManager.GetString(SaveKey) == "1") + { + SpawnParticleStones(); + Map.Objects.DeleteObjects.Add(this); + } + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + // gets destroyed by a bomb + if (damageType == HitType.Bomb) + { + Map.Objects.DeleteObjects.Add(this); + + if (_playSound) + Game1.GameManager.PlaySoundEffect("D360-02-02"); + + Game1.GameManager.PlaySoundEffect("D378-09-09"); + + if (!string.IsNullOrEmpty(SaveKey)) + Game1.GameManager.SaveManager.SetString(SaveKey, "1"); + + SpawnParticleStones(); + + return Values.HitCollision.Blocking; + } + + return Values.HitCollision.None; + } + + private void SpawnParticleStones() + { + var rndMin = 15; + var rndMax = 25; + + var vector0 = new Vector3(-1, -1, 0) * Game1.RandomNumber.Next(rndMin, rndMax) / 100f; + var vector1 = new Vector3(-1, 0, 0) * Game1.RandomNumber.Next(rndMin, rndMax) / 100f; + var vector2 = new Vector3(1, -1, 0) * Game1.RandomNumber.Next(rndMin, rndMax) / 100f; + var vector3 = new Vector3(1, 0, 0) * Game1.RandomNumber.Next(rndMin, rndMax) / 100f; + + vector0.Z = 1.25f; + vector1.Z = 1.25f; + vector2.Z = 1.25f; + vector3.Z = 1.25f; + + var stone0 = new ObjSmallStone(Map, (int)EntityPosition.X - 2, (int)EntityPosition.Y - 6, 0, vector0, true); + var stone1 = new ObjSmallStone(Map, (int)EntityPosition.X - 2, (int)EntityPosition.Y - 1, 0, vector1, true); + var stone2 = new ObjSmallStone(Map, (int)EntityPosition.X + 3, (int)EntityPosition.Y - 6, 0, vector2, false); + var stone3 = new ObjSmallStone(Map, (int)EntityPosition.X + 3, (int)EntityPosition.Y - 1, 0, vector3, false); + + Map.Objects.SpawnObject(stone0); + Map.Objects.SpawnObject(stone1); + Map.Objects.SpawnObject(stone2); + Map.Objects.SpawnObject(stone3); + } + } +} diff --git a/InGame/GameObjects/Dungeon/ObjDungeon.cs b/InGame/GameObjects/Dungeon/ObjDungeon.cs new file mode 100644 index 0000000..3ebb9b4 --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjDungeon.cs @@ -0,0 +1,33 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + internal class ObjDungeon : GameObject + { + public ObjDungeon() : base("editor dungeon") { } + + public ObjDungeon(Map.Map map, int posX, int posY, string dungeonName, bool updatePosition, int dungeonLevel) : base(map) + { + if (!string.IsNullOrEmpty(dungeonName)) + Game1.GameManager.SetDungeon(dungeonName, dungeonLevel); + + // this is used in side rooms of a dungeon + // normally this are the 2d rooms + if (updatePosition) + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + private void Update() + { + var playerPosition = new Point( + (int)(MapManager.ObjLink.PosX - Map.MapOffsetX * 16) / 160, + (int)(MapManager.ObjLink.PosY - Map.MapOffsetY * 16) / 128); + + // update the player position on the dungeon map + Game1.GameManager.DungeonUpdatePlayerPosition(playerPosition); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Dungeon/ObjDungeonBarrier.cs b/InGame/GameObjects/Dungeon/ObjDungeonBarrier.cs new file mode 100644 index 0000000..ceb23c2 --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjDungeonBarrier.cs @@ -0,0 +1,147 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + internal class ObjDungeonBarrier : GameObject + { + private readonly DrawComponent _drawComponent; + private readonly List _collidingObjects = new List(); + + private readonly DictAtlasEntry _dictBarrier; + private readonly DictAtlasEntry _dictBarrierBack; + + private readonly CBox _bodyBox; + + private readonly string _key; + private readonly bool _negate; + + private const int StateTimer = 200; + private float _stateCounter; + private float _transitionPercentage; + private float _transitionState; + + private bool _isUp; + + public ObjDungeonBarrier(Map.Map map, int posX, int posY, string strKey, bool negate, int type) : base(map) + { + type = MathHelper.Clamp(type, 0, 3); + + _dictBarrier = Resources.GetSprite("barrier_" + type); + _dictBarrierBack = Resources.GetSprite("barrier_bottom_" + type); + + SprEditorImage = _dictBarrier.Texture; + EditorIconSource = _dictBarrier.ScaledRectangle; + EditorIconScale = _dictBarrier.Scale; + + EntityPosition = new CPosition(posX + 2.5f, posY + 5, 0); + EntitySize = new Rectangle(0, -5, 11, 14); + + _key = strKey; + _negate = negate; + + var collisionComponent = new BoxCollisionComponent( + _bodyBox = new CBox(EntityPosition, 0, -1, 11, 8, 4), Values.CollisionTypes.Normal); + + AddComponent(CollisionComponent.Index, collisionComponent); + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawShadowComponent.Index, new DrawShadowComponent(DrawShadow)); + AddComponent(DrawComponent.Index, _drawComponent = new DrawComponent(Draw, Values.LayerBottom, EntityPosition)); + + KeyChanged(); + if (_isUp) + _stateCounter = StateTimer; + } + + private void KeyChanged() + { + if (!string.IsNullOrWhiteSpace(_key)) + { + _isUp = _negate != (Game1.GameManager.SaveManager.GetString(_key, "0") == "1"); + if (_isUp) + _drawComponent.Layer = Values.LayerPlayer; + } + } + + private void Update() + { + if (!_isUp && _stateCounter > 0) + { + _stateCounter -= Game1.DeltaTime; + + if (_stateCounter < 0) + { + _stateCounter = 0; + _drawComponent.Layer = Values.LayerBottom; + } + } + else if (_isUp && _stateCounter < StateTimer) + { + _stateCounter += Game1.DeltaTime; + + if (_stateCounter > StateTimer) + _stateCounter = StateTimer; + } + + _transitionPercentage = MathF.Sin((_stateCounter / StateTimer) * MathF.PI - MathF.PI / 2) * 0.5f + 0.5f; + _transitionState = _transitionPercentage * 4; + + if (EntityPosition.Z != _transitionState - 4) + { + var lastBox = _bodyBox.Box; + + EntityPosition.Z = _transitionState - 4; + EntityPosition.NotifyListeners(); + + // check for colliding bodies and push them forward + _collidingObjects.Clear(); + Map.Objects.GetComponentList(_collidingObjects, + (int)EntityPosition.Position.X, (int)EntityPosition.Position.Y - 1, 11, 8, BodyComponent.Mask); + + foreach (var collidingObject in _collidingObjects) + { + var body = (BodyComponent)collidingObject.Components[BodyComponent.Index]; + + if (body.BodyBox.Box.Intersects(_bodyBox.Box)) + { + if (!body.BodyBox.Box.Intersects(lastBox)) + { + body.Position.Z = EntityPosition.Z + _bodyBox.Box.Depth; + body.Position.NotifyListeners(); + } + } + } + } + } + + private void Draw(SpriteBatch spriteBatch) + { + // draw the bottom part + DrawHelper.DrawNormalized(spriteBatch, _dictBarrierBack, new Vector2(EntityPosition.X, EntityPosition.Y - 1), Color.White); + + // draw the barrier + if (_transitionState != 0) + { + var rectangle = _dictBarrier.ScaledRectangle; + rectangle.Height = (int)((_dictBarrier.SourceRectangle.Height - 4 + _transitionState) / _dictBarrier.Scale); + DrawHelper.DrawNormalized(spriteBatch, _dictBarrier.Texture, + new Vector2(EntityPosition.X, EntityPosition.Y - 1 - _transitionState), rectangle, Color.White); + } + } + + private void DrawShadow(SpriteBatch spriteBatch) + { + DrawHelper.DrawShadow(_dictBarrier.Texture, new Vector2(EntityPosition.X, EntityPosition.Y - 6), + _dictBarrier.ScaledRectangle, _dictBarrier.SourceRectangle.Width, _dictBarrier.SourceRectangle.Height, false, + Map.ShadowHeight, Map.ShadowRotation, Color.White * _transitionPercentage); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Dungeon/ObjDungeonBlackRoom.cs b/InGame/GameObjects/Dungeon/ObjDungeonBlackRoom.cs new file mode 100644 index 0000000..39b2299 --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjDungeonBlackRoom.cs @@ -0,0 +1,92 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + internal class ObjDungeonBlackRoom : GameObject + { + private readonly Rectangle _roomRectangle; + private readonly Rectangle _roomRectangleSmall; + private readonly string _saveId; + + private RectangleF _collisionRectangle; + + private float _changeCount; + private float _percentage; + + private int _changeTime = 66; + + private bool _isTransitioning; + + public ObjDungeonBlackRoom(Map.Map map, int posX, int posY, string saveId, int width, int height) : base(map) + { + SprEditorImage = Resources.SprWhite; + EditorIconSource = new Rectangle(0, 0, 16, 16); + EditorColor = Color.Red * 0.75f; + + _saveId = saveId; + + if (!string.IsNullOrEmpty(_saveId) && Game1.GameManager.SaveManager.GetString(saveId) == "1") + { + IsDead = true; + return; + } + + _roomRectangle = new Rectangle(posX, posY, width, height); + _roomRectangleSmall = new Rectangle(posX + 14, posY + 14, width - 28, height - 28); + + _collisionRectangle = new RectangleF(posX - 16, posY - 16, width + 32, height + 32); + _changeCount = _changeTime; + + // room can also get uncovered by setting a key + if (!string.IsNullOrEmpty(_saveId)) + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(LightDrawComponent.Index, new LightDrawComponent(DrawLight) { Layer = Values.LightLayer2 }); + AddComponent(BlurDrawComponent.Index, new BlurDrawComponent(DrawBlur)); + } + + private void OnKeyChange() + { + var keyState = Game1.GameManager.SaveManager.GetString(_saveId); + if (keyState == "1") + _isTransitioning = true; + } + + private void Update() + { + if (!_isTransitioning && _collisionRectangle.Intersects(MapManager.ObjLink.BodyRectangle)) + _isTransitioning = true; + + if (_isTransitioning) + { + _changeCount -= Game1.DeltaTime; + if (_changeCount < 0) + { + Map.Objects.DeleteObjects.Add(this); + + if (!string.IsNullOrEmpty(_saveId)) + Game1.GameManager.SaveManager.SetString(_saveId, "1"); + } + } + + _percentage = _changeCount / _changeTime; + } + + private void DrawLight(SpriteBatch spriteBatch) + { + spriteBatch.Draw(Resources.SprWhite, _roomRectangleSmall, Color.Black * _percentage); + } + + private void DrawBlur(SpriteBatch spriteBatch) + { + spriteBatch.Draw(Resources.SprWhite, _roomRectangle, Color.Black * _percentage); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Dungeon/ObjDungeonBlacker.cs b/InGame/GameObjects/Dungeon/ObjDungeonBlacker.cs new file mode 100644 index 0000000..1287633 --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjDungeonBlacker.cs @@ -0,0 +1,22 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + internal class ObjDungeonBlacker : GameObject + { + public ObjDungeonBlacker() : base("editor dungeon blacker") + { + EditorColor = Color.DarkRed * 0.75f; + } + + public ObjDungeonBlacker(Map.Map map, int posX, int posY, int colorR, int colorG, int colorB, int colorA) : base(map) + { + map.UseLight = true; + map.LightColor = new Color(colorR, colorG, colorB) * (colorA / 255f); + + IsDead = true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Dungeon/ObjDungeonColorSwitch.cs b/InGame/GameObjects/Dungeon/ObjDungeonColorSwitch.cs new file mode 100644 index 0000000..fbba27f --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjDungeonColorSwitch.cs @@ -0,0 +1,204 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + internal class ObjDungeonColorSwitch : GameObject + { + private readonly List _neighborSwitches = new List(); + private readonly Color[] _colors = { new Color(25, 132, 255), new Color(255, 8, 42), new Color(254, 123, 8) }; + private readonly CSprite _sprite; + private readonly Animator _animator; + + private readonly string _strKey; + private readonly string _strKeyMoved; + + private readonly int _stateCount; + private int _stateIndex; + + private readonly int _positionIndex; + private readonly int _neighbors; + + private bool _moving; + private bool _colorChanged; + private bool _resetKey; + private bool _finished; + + public ObjDungeonColorSwitch() : base("dungeon_color_head") { } + + public ObjDungeonColorSwitch(Map.Map map, int posX, int posY, string strKey, int stateCount, int stateIndex, int position, int neighbors) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 14, 0); + EntitySize = new Rectangle(-8, -14, 16, 16); + + _strKey = strKey; + _stateCount = stateCount; + _stateIndex = stateIndex; + + _positionIndex = 0x01 << position; + _neighbors = neighbors; + + _strKeyMoved = _strKey + "_moved"; + + var hittableBox = new CBox(posX, posY + 2, 0, 16, 14, 16); + var collisionBox = new CBox(posX + 1, posY + 5, 0, 14, 10, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Objects/dungeon color switch"); + _animator.Play("idle"); + + _sprite = new CSprite(EntityPosition); + + var activated = !string.IsNullOrEmpty(strKey) && Game1.GameManager.SaveManager.GetString(strKey) == "1"; + if (activated) + { + _stateIndex = 0; + } + else + { + if (!string.IsNullOrEmpty(strKey)) + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + } + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(collisionBox, Values.CollisionTypes.Normal)); + AddComponent(BaseAnimationComponent.Index, new AnimationComponent(_animator, _sprite, new Vector2(0, 2))); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(_sprite)); + + Game1.GameManager.SaveManager.SetInt(_strKeyMoved, -1); + } + + public override void Init() + { + var fieldRectangle = Map.GetField((int)EntityPosition.X, (int)EntityPosition.Y); + Map.Objects.GetObjectsOfType(_neighborSwitches, typeof(ObjDungeonColorSwitch), + fieldRectangle.X, fieldRectangle.Y, fieldRectangle.Width, fieldRectangle.Height); + } + + public bool IsBlue() + { + return !_moving && _stateIndex == 0; + } + + private void OnKeyChange() + { + var keyState = Game1.GameManager.SaveManager.GetInt(_strKeyMoved, -1); + if (keyState >= 0) + { + if (keyState == _positionIndex) + { + // make sure to reset the key; this should happen one frame after the move started + _resetKey = true; + StartMoving(); + } + else if ((keyState & _neighbors) != 0) + { + StartMoving(); + } + } + + var keyValue = Game1.GameManager.SaveManager.GetString(_strKey, "0"); + if (keyValue == "1") + _finished = true; + } + + private bool CheckNeighbors() + { + foreach (var gameObject in _neighborSwitches) + { + if (gameObject is ObjDungeonColorSwitch neighborSwitch && !neighborSwitch.IsBlue()) + return false; + } + + return true; + } + + private void StartMoving() + { + if (_moving) + IncreaseIndex(); + + Game1.GameManager.PlaySoundEffect("D360-03-03"); + + _moving = true; + _colorChanged = false; + _animator.Play("move"); + } + + private void IncreaseIndex() + { + _stateIndex = (_stateIndex + 1) % _stateCount; + + } + + private void Update() + { + if (_resetKey) + { + _resetKey = false; + Game1.GameManager.SaveManager.SetInt(_strKeyMoved, -1); + } + + if (_moving) + { + // change the color at the second frame + if (!_colorChanged && _animator.CurrentFrameIndex >= 1) + { + _colorChanged = true; + IncreaseIndex(); + } + + // finished moving? + if (!_animator.IsPlaying) + { + StopMoving(); + } + } + } + + private void StopMoving() + { + _moving = false; + _animator.Play("idle"); + + // check if all switches are set to blue => set the strKey to 1 + if (CheckNeighbors()) + { + _finished = true; + if (!string.IsNullOrEmpty(_strKey) && Game1.GameManager.SaveManager.GetString(_strKey) != "1") + Game1.GameManager.SaveManager.SetString(_strKey, "1"); + } + } + + private void Draw(SpriteBatch spriteBatch) + { + _sprite.Draw(spriteBatch); + + // the colored part is 16 scaled pixels below + var sourceRectangle = _sprite.SourceRectangle; + _sprite.SourceRectangle.Y += (int)(16 / _sprite.Scale); + _sprite.Color = _colors[_stateIndex]; + + _sprite.Draw(spriteBatch); + + _sprite.Color = Color.White; + _sprite.SourceRectangle = sourceRectangle; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_moving || _finished) + return Values.HitCollision.None; + + Game1.GameManager.SaveManager.SetInt(_strKeyMoved, _positionIndex); + + return Values.HitCollision.Enemy; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Dungeon/ObjDungeonDoor.cs b/InGame/GameObjects/Dungeon/ObjDungeonDoor.cs new file mode 100644 index 0000000..a5c531a --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjDungeonDoor.cs @@ -0,0 +1,172 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + internal class ObjDungeonDoor : GameObject + { + private enum DoorStates { Opening, Closing, Open, Closed } + private DoorStates _currentState; + + private readonly BoxCollisionComponent _collisionComponent; + private readonly Rectangle _sourceRectangle; + private readonly CSprite _sprite; + + private readonly string _strKey; + private readonly string _strPushKey; + private readonly string _pushItem; + + private float _doorState; + private bool _wasUpdated; + + public ObjDungeonDoor() : base("dungeon_door") { } + + public ObjDungeonDoor(Map.Map map, int posX, int posY, int mode, string strKey, int direction, string strPushKey) : base(map) + { + _sourceRectangle = Resources.SourceRectangle("dungeon_door"); + + _strKey = strKey; + _strPushKey = strPushKey; + + if (string.IsNullOrEmpty(_strKey)) + { + IsDead = true; + return; + } + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + _collisionComponent = new BoxCollisionComponent(new CBox(posX, posY, 0, 16, 16, 16), Values.CollisionTypes.Normal); + _sprite = new CSprite(Resources.SprObjects, EntityPosition, Rectangle.Empty, new Vector2(8, 8)); + _sprite.Center = new Vector2(8, 8); + _sprite.Rotation = (float)(Math.PI / 2 * (direction + 1)); + + if (!string.IsNullOrEmpty(_strKey)) + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + AddComponent(CollisionComponent.Index, _collisionComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerBottom)); + + _sourceRectangle.X += mode * 16; + + if (mode == 1) + _pushItem = "smallkey"; + else if (mode == 3) + _pushItem = "nightmarekey"; + + if (mode == 1 || mode == 3) + { + var pushBox = new CBox(EntityPosition, 0, 0, 16, 16, 8); + AddComponent(PushableComponent.Index, new PushableComponent(pushBox, OnPush) { InertiaTime = 100 }); + } + + _sprite.SourceRectangle = _sourceRectangle; + } + + private void Update() + { + _wasUpdated = true; + + if (_currentState == DoorStates.Opening) + { + _doorState -= Game1.TimeMultiplier * 0.05f; + + if (_doorState <= 0.5f) + _collisionComponent.IsActive = false; + + if (_doorState <= 0) + { + _doorState = 0; + _currentState = DoorStates.Open; + } + } + else if (_currentState == DoorStates.Closing) + { + _doorState += Game1.TimeMultiplier * 0.1f; + if (_doorState >= 1) + { + _doorState = 1; + _currentState = DoorStates.Closed; + } + } + + _sprite.SourceRectangle.Height = (int)Math.Round(16 * _doorState); + _sprite.SourceRectangle.Y = _sourceRectangle.Y + 16 - _sprite.SourceRectangle.Height; + + _sprite.SpriteEffect = SpriteEffects.FlipHorizontally; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact || _currentState != DoorStates.Closed) + return false; + + // remove one key + if (!Game1.GameManager.RemoveItem(_pushItem, 1)) + { + // start a dialog if the player does not have the required item + Game1.GameManager.StartDialogPath("door_" + _pushItem); + return false; + } + + // only play the sound effect when the player uses a key to open the door + Game1.GameManager.PlaySoundEffect("D378-04-04", false); + + if (!string.IsNullOrEmpty(_strPushKey)) + Game1.GameManager.SaveManager.SetString(_strPushKey, "1"); + + return true; + } + + private void Open() + { + _currentState = DoorStates.Opening; + } + + private void Close() + { + _currentState = DoorStates.Closing; + _collisionComponent.IsActive = true; + + Game1.GameManager.PlaySoundEffect("D378-16-10", false); + } + + private void KeyChanged() + { + // open/close the door if it is not already in the right state + // 1: open, 0: closed + var value = Game1.GameManager.SaveManager.GetString(_strKey); + var openDoor = value != null && value != "0"; + + if (_wasUpdated) + { + if (_currentState != DoorStates.Open && openDoor) + Open(); + else if (_currentState != DoorStates.Closed && _currentState != DoorStates.Closing && !openDoor) + Close(); + } + else + { + // set the door to open or closed + if (openDoor) + { + _currentState = DoorStates.Open; + _collisionComponent.IsActive = false; + _doorState = 0; + } + else + { + _currentState = DoorStates.Closed; + _collisionComponent.IsActive = true; + _doorState = 1; + } + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Dungeon/ObjDungeonEntrance.cs b/InGame/GameObjects/Dungeon/ObjDungeonEntrance.cs new file mode 100644 index 0000000..7d72818 --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjDungeonEntrance.cs @@ -0,0 +1,92 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + internal class ObjDungeonEntrance : GameObject + { + private readonly BoxCollisionComponent _collisionComponent; + private readonly CSprite _sprite; + + private readonly string _strKey; + private float _counter; + private int _openSpeed = 40; + private bool _opening; + private bool _isOpen; + + public ObjDungeonEntrance(Map.Map map, int posX, int posY, string spriteName, string strKey) : base(map) + { + var sprite = Resources.GetSprite(spriteName); + if (sprite == null) + { + IsDead = true; + return; + } + + SprEditorImage = sprite.Texture; + EditorIconSource = sprite.ScaledRectangle; + + _strKey = strKey; + EntityPosition = new CPosition(posX, posY, 0); + + // do not spawn the entrance if it is already open + if (!string.IsNullOrEmpty(_strKey) && Game1.GameManager.SaveManager.GetString(_strKey) == "1") + { + IsDead = true; + return; + } + + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + AddComponent(CollisionComponent.Index, _collisionComponent = + new BoxCollisionComponent(new CBox(posX, posY, 0, 16, 16, 16), Values.CollisionTypes.Normal)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + _sprite = new CSprite(sprite.Texture, EntityPosition, sprite.ScaledRectangle, Vector2.Zero); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerBottom)); + } + + private void Update() + { + if (!_opening) + return; + + _counter -= Game1.DeltaTime; + + if (_counter > 0) + return; + + _counter += _openSpeed; + + if (_sprite.SourceRectangle.Height > 0) + { + _sprite.SourceRectangle.Y++; + _sprite.SourceRectangle.Height--; + + if(_sprite.SourceRectangle.Height == 8) + Game1.GameManager.PlaySoundEffect("D360-35-23", false, 1, 0, true); + } + else + { + _opening = false; + _isOpen = true; + _collisionComponent.IsActive = false; + } + } + + private void Open() + { + if (_isOpen) + return; + + _opening = true; + } + + private void OnKeyChange() + { + if (!string.IsNullOrEmpty(_strKey) && Game1.GameManager.SaveManager.GetString(_strKey) == "1") + Open(); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Dungeon/ObjDungeonFairy.cs b/InGame/GameObjects/Dungeon/ObjDungeonFairy.cs new file mode 100644 index 0000000..d74352a --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjDungeonFairy.cs @@ -0,0 +1,217 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + internal class ObjDungeonFairy : GameObject + { + private readonly GameItem _carriedItem; + private readonly Rectangle _carriedItemSourceRectangle; + + private readonly CSprite _sprite; + private readonly CBox _collectionBox; + private Vector2 _direction; + + private float _currentRotation; + private float _directionChange; + + private float _currentSpeed; + private float _lastSpeed; + private float _speedGoal; + + private float _flyCounter; + + private int _flyTime; + + private const int MinSpeed = 10; + private const int MaxSpeed = 75; + + // the fairy is not collectable directly + private float _collectionCooldown = 500; + + private const float FadeOutTime = 100; + private float _collectionCounter = FadeOutTime; + + private float _targetHeight = 16; + // the butterfly will stay around this distance from the start point + private float _positionZ; + private int _startDistance; + private bool _collected; + private bool _itemMode; + + public ObjDungeonFairy() : base("fairy") { } + + public ObjDungeonFairy(Map.Map map, int posX, int posY, int posZ, string carriedItem = null) : base(map) + { + EntityPosition = new CPosition(posX, posY, posZ); + EntitySize = new Rectangle(-4, -30, 8, 30); + + _positionZ = posZ; + + var body = new BodyComponent(EntityPosition, -4, -8, 8, 8, 8) + { + IgnoresZ = true + }; + + if (!string.IsNullOrEmpty(carriedItem)) + { + _carriedItem = Game1.GameManager.ItemManager[carriedItem]; + + if (_carriedItem.SourceRectangle.HasValue) + _carriedItemSourceRectangle = _carriedItem.SourceRectangle.Value; + else + { + var baseItem = Game1.GameManager.ItemManager[_carriedItem.Name]; + _carriedItemSourceRectangle = baseItem.SourceRectangle.Value; + } + + _targetHeight += 12; + _itemMode = true; + _collectionCounter = 750; + } + + // start by flying away from the player + _startDistance = Game1.RandomNumber.Next(25, 50); + var playerDirection = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + _currentRotation = MathF.Atan2(playerDirection.Y, playerDirection.X); + _flyTime = 500; + _flyCounter = _flyTime; + + _currentSpeed = Game1.RandomNumber.Next(MaxSpeed / 2, MaxSpeed) / 100f; + _lastSpeed = _currentSpeed; + _speedGoal = Game1.RandomNumber.Next(MaxSpeed / 2, MaxSpeed) / 100f; + + _sprite = new CSprite("fairy", EntityPosition, new Vector2(-4, -13)); + + _collectionBox = new CBox(EntityPosition, -4, -10, _itemMode ? -16 : 0, 8, 10, 8, !_itemMode); + + AddComponent(BodyComponent.Index, body); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(body, _sprite)); + } + + private void Update() + { + if (!_collected) + UpdateFlying(); + else + UpdateCollected(); + } + + private void UpdateFlying() + { + if (_collectionCooldown > 0) + _collectionCooldown -= Game1.DeltaTime; + + _flyCounter -= Game1.DeltaTime; + + // ascent + if (_positionZ < _targetHeight) + _positionZ += Game1.TimeMultiplier * 0.25f; + else + _positionZ = _targetHeight; + + if (_flyCounter < 0) + { + _flyTime = Game1.RandomNumber.Next(500, 1000); + _flyCounter += _flyTime; + + // set a new speed goal + _lastSpeed = _speedGoal; + _speedGoal = Game1.RandomNumber.Next(MinSpeed, MaxSpeed) / 100f; + + var randomDirection = ((Game1.RandomNumber.Next(0, 20) - 10) / 6f) * ((float)Math.PI / (60 * (_flyCounter / 1000f))); + + // direction back to the base + var startDifference = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + var targetRotation = Math.Atan2(startDifference.Y, startDifference.X); + var rotationDifference = (float)targetRotation - _currentRotation; + while (rotationDifference < 0) + rotationDifference += (float)Math.PI * 2; + rotationDifference = rotationDifference % (float)(Math.PI * 2); + rotationDifference -= (float)Math.PI; + var newRotation = rotationDifference / (60 * (_flyCounter / 1000f)); + + // calculate the new rotation direction of the fairy + // the farther away it is from the start position the more likely it is to rotate to face the start position + _directionChange = MathHelper.Lerp(randomDirection, newRotation, MathHelper.Clamp(startDifference.Length() / _startDistance, 0, 1)); + } + + // update the speed + _currentSpeed = MathHelper.Lerp(_speedGoal, _lastSpeed, _flyCounter / _flyTime); + + // update direction + _currentRotation += _directionChange * Game1.TimeMultiplier; + _currentRotation = _currentRotation % (float)(Math.PI * 2); + _direction = new Vector2((float)Math.Cos(_currentRotation), (float)Math.Sin(_currentRotation)) * _currentSpeed; + EntityPosition.Move(_direction); + + EntityPosition.Z = _positionZ + (float)Math.Sin(Game1.TotalGameTime / 200) * 1.5f; + _sprite.SpriteEffect = _direction.X < 0 ? SpriteEffects.FlipHorizontally : SpriteEffects.None; + + // collision with the player + if (_collectionCooldown < 0 && MapManager.ObjLink.PlayerRectangle.Intersects(_collectionBox.Box.Rectangle())) + CollectFairy(); + } + + private void CollectFairy() + { + if (!_itemMode) + { + // heal the player + Game1.GameManager.HealPlayer(4 * 6); + ItemDrawHelper.EnableHeartAnimationSound(); + } + else + { + // collect the item the fairy was carrying + var cItem = new GameItemCollected(_carriedItem.Name) + { + Count = _carriedItem.Count + }; + + MapManager.ObjLink.PickUpItem(cItem, true); + } + + Game1.GameManager.PlaySoundEffect("D370-01-01"); + _collected = true; + } + + private void UpdateCollected() + { + _collectionCounter -= Game1.DeltaTime; + + if (_collectionCounter < 0) + { + IsActive = false; + Map.Objects.DeleteObjects.Add(this); + } + else + { + _sprite.Color = Color.White * MathHelper.Clamp(_collectionCounter / FadeOutTime, 0, 1); + EntityPosition.Move(_direction); + if (_itemMode) + EntityPosition.Z += Game1.TimeMultiplier * 0.25f; + } + } + + private void Draw(SpriteBatch spriteBatch) + { + _sprite.Draw(spriteBatch); + + // draw the item if the fairy is carrying one + if (_carriedItem != null && !_collected) + { + ItemDrawHelper.DrawItem(spriteBatch, _carriedItem, new Vector2( + EntityPosition.X - _carriedItemSourceRectangle.Width / 2, EntityPosition.Y - EntityPosition.Z - 1), Color.White, 1, true); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Dungeon/ObjDungeonHorseHead.cs b/InGame/GameObjects/Dungeon/ObjDungeonHorseHead.cs new file mode 100644 index 0000000..092a0bb --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjDungeonHorseHead.cs @@ -0,0 +1,245 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + internal class ObjDungeonHorseHead : GameObject + { + private readonly BodyComponent _body; + private readonly CSprite _cSprite; + + // field that the horse head can not leave + private readonly Rectangle _fieldRectangle; + + private readonly DictAtlasEntry _spriteHeadUp; + private readonly DictAtlasEntry _spriteHeadDown; + + private readonly string _strKey; + + private int _throwDirection; + private int _bounceCount; + + private int _direction; + private bool _wasThrown; + private bool _isUp; + private bool _wasUp; + private bool _chessBounces; + + public ObjDungeonHorseHead() : base("horse_head_up") { } + + public ObjDungeonHorseHead(Map.Map map, int posX, int posY, string strKey, int direction) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 13, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _strKey = strKey; + _direction = direction; + + _fieldRectangle = map.GetField(posX, posY, 15); + + // this is the same size as the player so that it can not get thrown into the wall + _body = new BodyComponent(EntityPosition, -5, -10, 10, 10, 14) + { + CollisionTypes = Values.CollisionTypes.Normal | Values.CollisionTypes.NPCWall, + MoveCollision = Collision, + DragAir = 0.95f, + Gravity = -0.125f, + FieldRectangle = map.GetField(posX, posY, 16) + }; + + _spriteHeadUp = Resources.GetSprite("horse_head_up"); + _spriteHeadDown = Resources.GetSprite("horse_head_down"); + + _cSprite = new CSprite(_spriteHeadDown, EntityPosition, new Vector2(-8, -13)); + + AddComponent(BodyComponent.Index, _body); + AddComponent(CarriableComponent.Index, new CarriableComponent( + new CRectangle(EntityPosition, new Rectangle(-7, -14, 14, 14)), CarryInit, CarryUpdate, CarryThrow)); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, OnHit)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_cSprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _cSprite)); + + DecrementUpState(); + UpdateSprite(); + } + + private void IncrementUpState() + { + if (string.IsNullOrEmpty(_strKey)) + return; + + // _strKey will get set to 1 after two horse heads stand up + var currentState = Game1.GameManager.SaveManager.GetString(_strKey); + if (currentState != "x") + Game1.GameManager.SaveManager.SetString(_strKey, "x"); + else + Game1.GameManager.SaveManager.SetString(_strKey, "1"); + } + + private void DecrementUpState() + { + if (string.IsNullOrEmpty(_strKey)) + return; + + var currentState = Game1.GameManager.SaveManager.GetString(_strKey); + if (currentState == "x") + Game1.GameManager.SaveManager.SetString(_strKey, "0"); + } + + private void UpdateSprite() + { + var newSprite = _wasThrown || _isUp ? _spriteHeadUp : _spriteHeadDown; + _cSprite.SetSprite(newSprite); + _cSprite.DrawOffset.X = -newSprite.SourceRectangle.Width / 2; + + _cSprite.SpriteEffect = SpriteEffects.None; + + if (_direction == 1 || _direction == 2) + _cSprite.SpriteEffect = SpriteEffects.FlipVertically; + if (_direction >= 2) + _cSprite.SpriteEffect |= SpriteEffects.FlipHorizontally; + } + + private void Update() + { + UpdateSprite(); + } + + private Vector3 CarryInit() + { + // the ball was picked up + _body.IsActive = false; + + return new Vector3(EntityPosition.X, EntityPosition.Y, EntityPosition.Z); + } + + private bool CarryUpdate(Vector3 newPosition) + { + // if the player tries to move the head out of the field it will fall down + if (!_fieldRectangle.Contains(new Vector2(newPosition.X, newPosition.Y))) + return false; + + EntityPosition.Set(new Vector3(newPosition.X, newPosition.Y, newPosition.Z + 3)); + return true; + } + + private void CarryThrow(Vector2 velocity) + { + _throwDirection = AnimationHelper.GetDirection(velocity); + + if (velocity.Length() > 0) + { + _wasThrown = true; + _chessBounces = true; + _direction = Game1.RandomNumber.Next(1, 3); + _isUp = false; + } + + _body.Velocity = new Vector3(velocity.X, velocity.Y, 0) * 1.0f; + + Release(); + } + + private void Release() + { + _bounceCount = 0; + _body.JumpStartHeight = 0; + _body.IsGrounded = false; + _body.IsActive = true; + + // we change the bounciness to make sure that we only bounce 2 times + _body.Bounciness = _chessBounces ? 0.725f : 0.0f; + } + + private void Collision(Values.BodyCollision direction) + { + if ((direction & Values.BodyCollision.Floor) != 0 && _chessBounces) + { + _wasThrown = false; + _bounceCount++; + + _direction = AnimationHelper.OffsetDirection(_direction, _throwDirection > 2 ? 1 : -1); + + // jump to the left or right after the second bounce + var velocityDirection = _throwDirection; + if (_bounceCount == 3) + { + _chessBounces = false; + _body.Bounciness = 0; + velocityDirection = + AnimationHelper.OffsetDirection(velocityDirection, Game1.RandomNumber.Next(0, 2) * 2 - 1); + + // 50% chance that the horse head will stand up after the throw + if (Game1.RandomNumber.Next(0, 4) <= 1 || _wasUp) + { + _body.Velocity = Vector3.Zero; + + // not in the og game; maybe find a better sound + Game1.GameManager.PlaySoundEffect("D370-14-0E"); + + if (!_wasUp) + IncrementUpState(); + + _wasUp = true; + _isUp = true; + // make sure that the head is standing up + if (_direction == 1) + _direction = 0; + if (_direction == 2) + _direction = 3; + } + else + { + Game1.GameManager.PlaySoundEffect("D360-29-1D"); + } + } + + if (_bounceCount <= 3) + { + var velocity = AnimationHelper.DirectionOffset[velocityDirection]; + _body.Velocity.X = velocity.X * 1.25f; + _body.Velocity.Y = velocity.Y * 1.25f; + } + } + + // make sure that the throw direction gets changed so the next bounce will not go towards the wall + if ((direction & (Values.BodyCollision.Horizontal | Values.BodyCollision.Vertical)) != 0) + _throwDirection = AnimationHelper.OffsetDirection(_throwDirection, 2); + + if ((direction & Values.BodyCollision.Horizontal) != 0) + _body.Velocity.X = -_body.Velocity.X * 0.65f; + if ((direction & Values.BodyCollision.Vertical) != 0) + _body.Velocity.Y = -_body.Velocity.Y * 0.65f; + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + if (_body.Velocity.Length() < 0.1f) + { + _body.Velocity.X = direction.X * 0.25f; + _body.Velocity.Y = direction.Y * 0.25f; + } + + return Values.HitCollision.RepellingParticle; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType pushType) + { + if (pushType == PushableComponent.PushType.Impact) + { + _body.Velocity.X = direction.X * 0.25f; + _body.Velocity.Y = direction.Y * 0.25f; + return true; + } + + return false; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Dungeon/ObjDungeonOneWay.cs b/InGame/GameObjects/Dungeon/ObjDungeonOneWay.cs new file mode 100644 index 0000000..f55c51a --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjDungeonOneWay.cs @@ -0,0 +1,96 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; +using ProjectZ.InGame.GameObjects.Bosses; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + internal class ObjDungeonOneWay : GameObject + { + private readonly ObjAnimator _animatorTop; + private readonly ObjAnimator _animatorBottom; + + private Vector2 _startPosition; + private Vector2 _endPosition; + + private bool _isRotation; + + public ObjDungeonOneWay() : base("dungeonOneWay") { } + + public ObjDungeonOneWay(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + + _animatorTop = new Things.ObjAnimator(map, posX, posY, Values.LayerBottom, "Objects/dOneWay", "idle2", false); + Map.Objects.SpawnObject(_animatorTop); + + _animatorBottom = new Things.ObjAnimator(map, posX, posY + 16, Values.LayerBottom, "Objects/dOneWay", "idle", false); + Map.Objects.SpawnObject(_animatorBottom); + + var pushBox = new CBox(posX + 6, posY + 16, 0, 4, 16, 16); + AddComponent(PushableComponent.Index, new PushableComponent(pushBox, OnPush) { InertiaTime = 50 }); + + var collisionBox = new CBox(posX, posY, 0, 16, 32, 16); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(collisionBox, Values.CollisionTypes.Normal)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type != PushableComponent.PushType.Continues || MapManager.ObjLink.Direction != 1) + return false; + + StartRotation(); + return true; + } + + private void Update() + { + if (!_isRotation) + return; + + MapManager.ObjLink.CanWalk = false; + + if (_animatorBottom.Animator.CurrentFrameIndex < 4) + { + var frameTime = _animatorBottom.Animator.GetAnimationTime(0, _animatorBottom.Animator.CurrentFrameIndex) + + _animatorBottom.Animator.FrameCounter; + var maxTime = _animatorBottom.Animator.GetAnimationTime(0, 4); + + var state = (float)frameTime / maxTime; + var currentPosition = Vector2.Lerp(_startPosition, _endPosition, state); + MapManager.ObjLink.SetPosition(currentPosition); + } + + if (_animatorBottom.Animator.CurrentFrameIndex >= 4) + { + _isRotation = false; + MapManager.ObjLink.SetPosition(_endPosition); + MapManager.ObjLink.IsVisible = true; + } + } + + private void StartRotation() + { + // hide the player + MapManager.ObjLink.IsVisible = false; + + Game1.GameManager.PlaySoundEffect("D360-12-0C"); + + _isRotation = true; + + // the player will be moved between these two points while transitioning to the other side + _startPosition = new Vector2(MapManager.ObjLink.EntityPosition.X, MapManager.ObjLink.EntityPosition.Y); + _endPosition = new Vector2( + EntityPosition.X + 8, + EntityPosition.Y - MapManager.ObjLink._body.OffsetY - MapManager.ObjLink._body.Height); + + _animatorTop.Animator.Play("rotate2"); + _animatorBottom.Animator.Play("rotate"); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Dungeon/ObjDungeonOwl.cs b/InGame/GameObjects/Dungeon/ObjDungeonOwl.cs new file mode 100644 index 0000000..090a31d --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjDungeonOwl.cs @@ -0,0 +1,40 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + internal class ObjDungeonOwl : GameObject + { + private readonly string _signText; + + public ObjDungeonOwl() : base("dungeon_owl") { } + + public ObjDungeonOwl(Map.Map map, int posX, int posY, string signText) : base(map) + { + var sourceRectangle = Resources.SourceRectangle("dungeon_owl"); + + EntityPosition = new CPosition(posX, posY + 16, 0); + EntitySize = new Rectangle(0, -16, 16, 16); + + _signText = signText; + + var interactBox = new CBox(posX, posY, 0, 16, 16, 16); + + AddComponent(InteractComponent.Index, new InteractComponent(interactBox, OnInteract)); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(interactBox, Values.CollisionTypes.Normal)); + AddComponent(DrawComponent.Index, new DrawSpriteComponent( + Resources.SprObjects, EntityPosition, sourceRectangle, new Vector2(0, -16), Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowSpriteComponent( + Resources.SprObjects, EntityPosition, sourceRectangle, new Vector2(0, -16))); + } + + private bool OnInteract() + { + Game1.GameManager.StartDialogPath(_signText); + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Dungeon/ObjDungeonPillar.cs b/InGame/GameObjects/Dungeon/ObjDungeonPillar.cs new file mode 100644 index 0000000..7004ef7 --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjDungeonPillar.cs @@ -0,0 +1,141 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + class ObjDungeonPillar : GameObject + { + private readonly BoxCollisionComponent _collisionComponent; + private readonly AiComponent _aiComponent; + + private readonly CSprite[] _sprites = new CSprite[5]; + private readonly string[] _spriteIds = { "pillar_bottom", "pillar_middle", "pillar_middle", "pillar_middle", "pillar_top" }; + + private string _saveKey; + + private int _pillarIndex = 5; + private float _fallCount; + private float _particleCounter; + private float _stoneCounter; + + private Vector2 _basePosition; + + public ObjDungeonPillar() : base("pillar_bottom") { } + + public ObjDungeonPillar(Map.Map map, int posX, int posY, string saveKey) : base(map) + { + _saveKey = saveKey; + if (!string.IsNullOrEmpty(_saveKey)) + { + var strKeyState = Game1.GameManager.SaveManager.GetString(_saveKey); + if (strKeyState != null && strKeyState == "1") + { + IsDead = true; + return; + } + } + + for (var i = 0; i < 5; i++) + _sprites[i] = new CSprite(_spriteIds[i], new CPosition(posX, posY - i * 16, 0), Vector2.Zero); + + _basePosition = new Vector2(posX, posY); + + EntityPosition = new CPosition(posX + 8, posY + 14, 0); + EntitySize = new Rectangle(-8, -78, 16, 80); + + var stateIdle = new AiState(); + var stateShaking = new AiState { Init = InitShake }; + stateShaking.Trigger.Add(new AiTriggerCountdown(1300, null, () => _aiComponent.ChangeState("falling"))); + var stateFalling = new AiState(UpdateFalling); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("shaking", stateShaking); + _aiComponent.States.Add("falling", stateFalling); + _aiComponent.ChangeState("idle"); + + var collisionBox = new CBox(posX + 1, posY + 4, 0, 14, 12, 16); + var hitBox = new CBox(posX, posY - 8, 0, 16, 24, 16); + + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(HittableComponent.Index, new HittableComponent(hitBox, OnHit)); + AddComponent(CollisionComponent.Index, _collisionComponent = new BoxCollisionComponent(collisionBox, Values.CollisionTypes.Normal)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + } + + private void InitShake() + { + Game1.GameManager.ShakeScreen(1300 + 5 * 500, 3, 2, 5, 2.5f); + + Game1.GameManager.PlaySoundEffect("D360-11-0B"); + Game1.GameManager.PlaySoundEffect("D378-37-25"); + } + + private void UpdateFalling() + { + _fallCount += Game1.DeltaTime; + _particleCounter += Game1.DeltaTime; + _stoneCounter -= Game1.DeltaTime; + + if (_fallCount > 500) + { + _fallCount -= 500; + _pillarIndex--; + + // remove the pillar? + if (_pillarIndex <= 0) + { + // we set the key here so that the collapse sequence will be shown after the pillar is gone + // this can lead to situations where the player changes the map while the pillar is collapsing and the state will not get saved + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + Map.Objects.DeleteObjects.Add(this); + } + } + + if (_stoneCounter < 0) + { + _stoneCounter = 850; + + var stonePosX = (int)_basePosition.X + Game1.RandomNumber.Next(0, 48) - 24; + var stonePosY = (int)_basePosition.Y + Game1.RandomNumber.Next(0, 48) - 24; + Map.Objects.SpawnObject(new ObjSmallStone(Map, stonePosX, stonePosY, 64, new Vector3(0, 0, 0), true)); + } + + // spawn particles + if (_particleCounter > 100) + { + _particleCounter -= 100; + + var positionX = (int)_basePosition.X + Game1.RandomNumber.Next(0, 28) - 14; + var positionY = (int)_basePosition.Y + Game1.RandomNumber.Next(0, 8) - 2; + Map.Objects.SpawnObject(new ObjAnimator(Map, positionX, positionY, Values.LayerTop, "Particles/spawn", "run", true)); + } + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + if (originObject.GetType() == typeof(ObjBall) && _aiComponent.CurrentStateId == "idle") + { + _aiComponent.ChangeState("shaking"); + return Values.HitCollision.Blocking; + } + + return Values.HitCollision.None; + } + + private void Draw(SpriteBatch spriteBatch) + { + for (var i = 0; i < _pillarIndex; i++) + { + _sprites[5 - _pillarIndex + i].Position.Set(new Vector2(_basePosition.X, _basePosition.Y - i * 16)); + _sprites[5 - _pillarIndex + i].Draw(spriteBatch); + } + } + } +} diff --git a/InGame/GameObjects/Dungeon/ObjDungeonSixEntry.cs b/InGame/GameObjects/Dungeon/ObjDungeonSixEntry.cs new file mode 100644 index 0000000..f86a352 --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjDungeonSixEntry.cs @@ -0,0 +1,140 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Things; +using ProjectZ.InGame.Map; +using System.Collections.Generic; +using ProjectZ.InGame.GameObjects.Things; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + internal class ObjDungeonSixEntry : GameObject + { + private List _objectList; + + private readonly CSprite _sprite; + private readonly string _strKey; + + private bool _opening; + private bool _isOpen; + private bool _init; + + private float _openCounter; + + private bool _spawnParticles; + private float _particleCounter; + + public ObjDungeonSixEntry() : base("dungeonSixEntry") { } + + public ObjDungeonSixEntry(Map.Map map, int posX, int posY, string strKey) : base(map) + { + // do not spawn the entrance if it is already open + if (!string.IsNullOrEmpty(strKey) && Game1.GameManager.SaveManager.GetString(strKey) == "1") + { + _isOpen = true; + } + + _strKey = strKey; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 80, 64); + + _sprite = new CSprite("dungeonSixEntry", EntityPosition, Vector2.Zero) { IsVisible = _isOpen }; + + if (!_isOpen) + { + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerBottom)); + } + + private void Update() + { + if (!_init) + { + _init = true; + // deactivate the objects at the position of the entry + _objectList = Map.Objects.GetObjects((int)EntityPosition.X, (int)EntityPosition.Y + 16, 80, 48); + SetObjectState(false); + } + + if (!_opening) + return; + + MapManager.ObjLink.FreezePlayer(); + + _openCounter += Game1.DeltaTime; + + if (_spawnParticles) + { + _particleCounter += Game1.DeltaTime; + if (_particleCounter > 75) + { + _particleCounter -= 75; + var posX = (int)EntityPosition.X + Game1.RandomNumber.Next(0, 64); + var posY = (int)EntityPosition.Y + _sprite.SourceRectangle.Height - 12 + Game1.RandomNumber.Next(0, 8); + Map.Objects.SpawnObject(new ObjAnimator(Map, posX, posY, Values.LayerPlayer, "Particles/spawn", "run", true)); + } + } + + if (_openCounter > 2000) + { + _openCounter -= 750; + _spawnParticles = true; + + if (_sprite.SourceRectangle.Height < 64) + { + EntityPosition.Set(new Vector2(EntityPosition.X, EntityPosition.Y - 8)); + _sprite.SourceRectangle.Height += 8; + + Game1.GameManager.PlaySoundEffect("D360-47-2F"); + + if (_sprite.SourceRectangle.Height == 64) + { + _spawnParticles = false; + Game1.GameManager.PlaySoundEffect("D360-02-02"); + } + } + else + { + _opening = false; + _isOpen = true; + Game1.GameManager.SetMusic(-1, 2); + } + } + } + + private void SetObjectState(bool isActive) + { + for (var i = 0; i < _objectList.Count; i++) + _objectList[i].IsActive = isActive; + } + + private void Open() + { + if (_opening || _isOpen) + return; + + Game1.GbsPlayer.Stop(); + + SetObjectState(true); + + _opening = true; + + _sprite.IsVisible = true; + _sprite.SourceRectangle.Height = 32; + + EntityPosition.Set(new Vector2(EntityPosition.X, EntityPosition.Y + 32)); + + Game1.GameManager.ShakeScreen(4250, 2, 1, 5.0f, 2.25f); + } + + private void OnKeyChange() + { + if (!string.IsNullOrEmpty(_strKey) && Game1.GameManager.SaveManager.GetString(_strKey) == "1") + Open(); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Dungeon/ObjDungeonSwitch.cs b/InGame/GameObjects/Dungeon/ObjDungeonSwitch.cs new file mode 100644 index 0000000..8b36440 --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjDungeonSwitch.cs @@ -0,0 +1,71 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + internal class ObjDungeonSwitch : GameObject + { + private readonly CSprite _sprite; + private readonly string _key; + + private const float ColorChangeTime = (8 / 60f) * 1000; + private float _colorCounter; + private float _hitCooldown; + + public ObjDungeonSwitch() : base("dungeon_switch") { } + + public ObjDungeonSwitch(Map.Map map, int posX, int posY, string key) : base(map) + { + EntityPosition = new CPosition(posX, posY + 16, 0); + EntitySize = new Rectangle(0, -16, 16, 17); + + _key = key; + + var hittableBox = new CBox(posX, posY + 4, 0, 16, 13, 16); + var collisionBox = new CBox(posX + 1, posY + 5, 0, 14, 11, 16); + _sprite = new CSprite("dungeon_switch", EntityPosition, new Vector2(0, -16)); + + if (!string.IsNullOrEmpty(_key)) + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(collisionBox, Values.CollisionTypes.Normal)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerPlayer)); + } + + private void Update() + { + if (_hitCooldown > 0) + _hitCooldown -= Game1.DeltaTime; + + // switch to an orange color after a hit + if (_colorCounter > 0) + { + _colorCounter -= Game1.DeltaTime; + _sprite.SpriteShader = Resources.DamageSpriteShader0; + } + else + _sprite.SpriteShader = null; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_hitCooldown > 0) + return Values.HitCollision.Blocking; + + _hitCooldown = 250; + _colorCounter = ColorChangeTime; + + Game1.GameManager.PlaySoundEffect("D360-03-03"); + Game1.GameManager.PlaySoundEffect("D370-14-0E"); + + // toggle the key + var lastState = Game1.GameManager.SaveManager.GetString(_key, "0"); + Game1.GameManager.SaveManager.SetString(_key, (lastState == "0" ? "1" : "0")); + + return Values.HitCollision.Blocking; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Dungeon/ObjDungeonTeleporter.cs b/InGame/GameObjects/Dungeon/ObjDungeonTeleporter.cs new file mode 100644 index 0000000..a5390bb --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjDungeonTeleporter.cs @@ -0,0 +1,165 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + public class ObjDungeonTeleporter : GameObject + { + public Vector2 TeleportPosition; + + private readonly Animator _centerAnimator; + private readonly AnimationComponent _animationComponent; + private readonly CSprite _sprite; + private readonly Rectangle _pointRectangle; + private readonly Vector2[] _pointPositions = new Vector2[4]; + private readonly Point _origin; + + private readonly string _teleportMap; + private readonly string _teleporterId; + + private float _rotateCount; + private bool _lockTeleporter; + private bool _isColliding; + + public ObjDungeonTeleporter() : base("teleporter_middle") { } + + public ObjDungeonTeleporter(Map.Map map, int posX, int posY, string teleportMap, string teleporterId) : base(map) + { + _pointRectangle = Resources.SourceRectangle("teleporter_outer"); + var sourceRectangle = Resources.SourceRectangle("teleporter_middle"); + + EntityPosition = new CPosition(posX + 8, posY + 8, 0); + EntitySize = new Rectangle(-8, -8, 16, 16); + + TeleportPosition = new Vector2(EntityPosition.X, EntityPosition.Y + MapManager.ObjLink.CollisionBoxSize.Y / 2f); + + _teleportMap = teleportMap; + _teleporterId = teleporterId; + + _origin = new Point(posX + 8, posY + 8); + + _centerAnimator = AnimatorSaveLoad.LoadAnimator("Objects/dTeleporter"); + _centerAnimator.Play("idle"); + + _sprite = new CSprite(EntityPosition); + _animationComponent = new AnimationComponent(_centerAnimator, _sprite, Vector2.Zero); + + // has the player just teleported to this teleporter? + if (teleporterId != null && MapManager.ObjLink.NextMapPositionId == teleporterId) + { + PlacePlayer(); + Lock(); + } + + AddComponent(BaseAnimationComponent.Index, _animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBottom, EntityPosition)); + AddComponent(LightDrawComponent.Index, new LightDrawComponent(DrawLight) { Layer = Values.LightLayer1 }); + + UpdatePositions(); + } + + public void Lock() + { + _isColliding = true; + _lockTeleporter = true; + } + + private void Update() + { + // is the player close enough? + var distance = TeleportPosition - MapManager.ObjLink.EntityPosition.Position; + if (distance.Length() < 2.5f) + OnCollision(); + + _rotateCount -= Game1.DeltaTime; + UpdatePositions(); + + if (!_isColliding) + _lockTeleporter = false; + + _isColliding = false; + } + + private void OnCollision() + { + _isColliding = true; + + if (_lockTeleporter || MapManager.ObjLink.EntityPosition.Z > 1) + return; + + Game1.GameManager.PlaySoundEffect("D360-28-1C"); + + // teleport into a new map? + if (!string.IsNullOrEmpty(_teleportMap) && Map.MapName != _teleportMap) + { + MapManager.ObjLink.SetPosition(TeleportPosition); + MapManager.ObjLink.StartTeleportation(_teleportMap, _teleporterId); + + _lockTeleporter = true; + return; + } + + var teleporterList = Map.Objects.GetObjectsOfType(typeof(ObjDungeonTeleporter)); + + foreach (var entity in teleporterList) + { + var teleporter = ((ObjDungeonTeleporter)entity); + if (teleporter != this && teleporter._teleporterId == _teleporterId) + { + MapManager.ObjLink.SetPosition(TeleportPosition); + MapManager.ObjLink.StartTeleportation(teleporter); + + _lockTeleporter = true; + break; + } + } + } + + private void UpdatePositions() + { + var radiants = _rotateCount / 150f; + + // rotate around the field + for (var i = 0; i < 4; i++) + { + _pointPositions[i] = new Vector2( + _origin.X + (float)(7 * Math.Sin(radiants + Math.PI / 2 * i) - 2), + _origin.Y + (float)(7 * Math.Cos(radiants + Math.PI / 2 * i)) - 2); + } + } + + private void PlacePlayer() + { + //MapManager.ObjLink.SaveMap = Map.MapName; + //MapManager.ObjLink.SavePosition = TeleportPosition; + //MapManager.ObjLink.SaveDirection = 3; + + MapManager.ObjLink.NextMapPositionStart = TeleportPosition; + MapManager.ObjLink.NextMapPositionEnd = TeleportPosition; + MapManager.ObjLink.TransitionInWalking = false; + MapManager.ObjLink.DirectionEntry = 3; + } + + private void Draw(SpriteBatch spriteBatch) + { + _sprite.Draw(spriteBatch); + + // draw the circles around + for (var i = 0; i < _pointPositions.Length; i++) + spriteBatch.Draw(Resources.SprObjects, _pointPositions[i], _pointRectangle, Color.White); + } + + private void DrawLight(SpriteBatch spriteBatch) + { + DrawHelper.DrawLight(spriteBatch, new Rectangle((int)EntityPosition.X - 32, (int)EntityPosition.Y - 32, 64, 64), new Color(255, 175, 175) * 1.00f); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Dungeon/ObjGraveTrigger.cs b/InGame/GameObjects/Dungeon/ObjGraveTrigger.cs new file mode 100644 index 0000000..0851829 --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjGraveTrigger.cs @@ -0,0 +1,83 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + class ObjGraveTrigger : GameObject + { + private readonly int[] _correctDirection = { 3, 0, 1, 2, 1 }; + private readonly string _triggerKey; + + private int _currentState; + + // object to set a key if the gravestones get moved in the right order in the right direction + public ObjGraveTrigger() : base("editor grave trigger") { } + + public ObjGraveTrigger(Map.Map map, int posX, int posY, string triggerKey) : base(map) + { + Tags = Values.GameObjectTag.None; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + _triggerKey = triggerKey; + + if (string.IsNullOrEmpty(_triggerKey)) + { + IsDead = true; + return; + } + + Game1.GameManager.SaveManager.SetString(_triggerKey, "0"); + + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + } + + private void OnKeyChange() + { + var reset = true; + + for (var i = 0; i < 5; i++) + { + var strKey = Game1.GameManager.SaveManager.GetString("ow_grave_" + i + "_dir"); + + // key is set? + if (!string.IsNullOrEmpty(strKey) && strKey != "-1") + { + reset = false; + var correctDirection = _correctDirection[i].ToString() == strKey; + + // player moved the next gravestone in the correct direction + if (correctDirection) + { + if (_currentState == i) + { + _currentState++; + if (_currentState == 5) + { + Game1.GameManager.SaveManager.SetString(_triggerKey, "1"); + + // remove the object + Map.Objects.DeleteObjects.Add(this); + } + } + } + else + { + // not the correct gravestone moved or in the wrong direction + _currentState = 5; + } + } + } + + // was reset? + if (reset) + { + _currentState = 0; + } + } + } +} diff --git a/InGame/GameObjects/Dungeon/ObjKillTrigger.cs b/InGame/GameObjects/Dungeon/ObjKillTrigger.cs new file mode 100644 index 0000000..8a954e8 --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjKillTrigger.cs @@ -0,0 +1,76 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Enemies; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + class ObjKillTrigger : GameObject + { + private readonly List _enemyList = new List(); + private readonly Rectangle _triggerField; + private readonly string _triggerKey; + private int _currentState; + + public ObjKillTrigger() : base("editor kill trigger") { } + + public ObjKillTrigger(Map.Map map, int posX, int posY, string triggerKey) : base(map) + { + Tags = Values.GameObjectTag.None; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + _triggerKey = triggerKey; + _triggerField = map.GetField(posX, posY); + + if (_triggerKey == null) + { + IsDead = true; + return; + } + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + private void Update() + { + // get the enemies the object should watch over + Map.Objects.GetGameObjectsWithTag(_enemyList, Values.GameObjectTag.Enemy, + _triggerField.X, _triggerField.Y, _triggerField.Width, _triggerField.Height); + + var enemy0Alive = false; + var enemy1Alive = false; + var enemy2Alive = false; + + // check which enemies are alive + foreach (var gameObject in _enemyList) + { + if (gameObject is EnemyPolsVoice) + enemy0Alive = true; + if (gameObject is EnemyKeese) + enemy1Alive = true; + if (gameObject is EnemyShroudedStalfos) + enemy2Alive = true; + } + + if (_currentState == 0 && !enemy0Alive && enemy1Alive && enemy2Alive) + _currentState = 1; + if (_currentState == 1 && !enemy0Alive && !enemy1Alive && enemy2Alive) + _currentState = 2; + if (_currentState == 2 && !enemy0Alive && !enemy1Alive && !enemy2Alive) + _currentState = 3; + + if (_currentState < 3) + return; + + Game1.GameManager.SaveManager.SetString(_triggerKey, "1"); + + // remove the object + Map.Objects.DeleteObjects.Add(this); + } + } +} diff --git a/InGame/GameObjects/Dungeon/ObjRoomDarkener.cs b/InGame/GameObjects/Dungeon/ObjRoomDarkener.cs new file mode 100644 index 0000000..34295b5 --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjRoomDarkener.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + internal class ObjRoomDarkener : GameObject + { + private readonly DictAtlasEntry _sprite; + private readonly List _lamps = new List(); + private readonly Rectangle _roomRectangle; + + private readonly float _dark; + private readonly float _bright; + + private float _state; + + public ObjRoomDarkener() : base("editor room darkener") { } + + public ObjRoomDarkener(Map.Map map, int posX, int posY, float dark, float bright) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(-16, -16, Values.FieldWidth + 32, Values.FieldHeight + 32); + + _roomRectangle = new Rectangle(posX, posY, Values.FieldWidth, Values.FieldHeight); + + _dark = dark; + _bright = bright; + + _sprite = Resources.GetSprite("room blur"); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(LightDrawComponent.Index, new LightDrawComponent(DrawLight) { Layer = Values.LightLayer2 }); + } + + public override void Init() + { + // get all the lamps in the area + Map.Objects.GetGameObjectsWithTag(_lamps, Values.GameObjectTag.Lamp, + _roomRectangle.X, _roomRectangle.Y, _roomRectangle.Width, _roomRectangle.Height); + + if (_lamps.Count == 0) + { + _state = _dark; + RemoveComponent(UpdateComponent.Index); + } + else + UpdateLampState(true); + } + + private void Update() + { + UpdateLampState(false); + } + + private void UpdateLampState(bool instantTransition) + { + var onCount = 0; + + foreach (var gameObject in _lamps) + { + if (gameObject is ObjLamp lamp) + { + if (lamp.IsOn()) + onCount++; + } + } + + // blend from _bright to _dark depending on how many lamps in the room are on + var targetState = MathHelper.Lerp(_dark, _bright, onCount / (float)_lamps.Count); + + if (instantTransition) + _state = targetState; + else + { + // smoothly transition to the target state + var amount = Math.Clamp(0.025f / Math.Abs(targetState - _state) * Game1.TimeMultiplier, 0, 1); + _state = MathHelper.Lerp(_state, targetState, amount); + } + + } + + private void DrawLight(SpriteBatch spriteBatch) + { + DrawHelper.DrawNormalized(spriteBatch, _sprite, EntityPosition.Position, Color.Black * _state); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Dungeon/ObjTower.cs b/InGame/GameObjects/Dungeon/ObjTower.cs new file mode 100644 index 0000000..356542f --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjTower.cs @@ -0,0 +1,141 @@ +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Things; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Map; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + internal class ObjTower : GameObject + { + private readonly Animator _animatorTop0; + private readonly Animator _animatorTop1; + private readonly Animator _animatorTop2; + private readonly Animator _animatorBottom; + + private readonly string _strKey; + + private bool _opening; + private bool _opened; + private bool _isRotating; + + private float _shakeCounter; + private bool _shakeScreen; + + public ObjTower() : base("tower") { } + + public ObjTower(Map.Map map, int posX, int posY, string strKey) : base(map) + { + EntityPosition = new CPosition(posX - 16, posY - 16, 0); + EntitySize = new Rectangle(0, 0, 80, 80); + + _strKey = strKey; + + _animatorTop0 = SaveLoad.AnimatorSaveLoad.LoadAnimator("Objects/d7 tower"); + _animatorTop0.Play("idle"); + _animatorTop0.Pause(); + + _animatorTop1 = SaveLoad.AnimatorSaveLoad.LoadAnimator("Objects/d7 tower top 1"); + _animatorTop1.Play("idle"); + _animatorTop1.Pause(); + + _animatorTop2 = SaveLoad.AnimatorSaveLoad.LoadAnimator("Objects/d7 tower top 2"); + _animatorTop2.Play("idle"); + + _animatorBottom = SaveLoad.AnimatorSaveLoad.LoadAnimator("Objects/d7 tower bottom"); + _animatorBottom.Play("idle"); + _animatorBottom.Pause(); + + var opened = !string.IsNullOrEmpty(strKey) && Game1.GameManager.SaveManager.GetString(strKey) == "1"; + + if (!opened) + { + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(new CBox(posX + 8, posY + 48, 0, 16, 16, 16), Values.CollisionTypes.Normal)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + else + { + _animatorBottom.Play("opened"); + } + + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBottom, EntityPosition)); + } + + private void Open() + { + if (_opening || _opened) + return; + + _animatorTop0.Continue(); + _animatorTop1.Continue(); + _animatorBottom.Continue(); + + _opening = true; + + Game1.GameManager.PlaySoundEffect("D378-04-04"); + Game1.GameManager.StopMusic(); + } + + private void OnKeyChange() + { + if (!string.IsNullOrEmpty(_strKey)) + { + var keyState = Game1.GameManager.SaveManager.GetString(_strKey); + if (keyState == "1") + Open(); + } + } + + private void Update() + { + if (!_opening || _opened) + return; + + MapManager.ObjLink.FreezePlayer(); + + _animatorTop0.Update(); + _animatorTop1.Update(); + _animatorBottom.Update(); + + _shakeCounter += Game1.DeltaTime; + + if (!_shakeScreen && _shakeCounter > 2000) + { + _shakeScreen = true; + Game1.GameManager.ShakeScreen(2750, 1, 0, 5, 5); + Game1.GameManager.PlaySoundEffect("D378-29-1D"); + } + + if (_opening && !_animatorTop0.IsPlaying) + { + if (!_isRotating) + { + _isRotating = true; + _animatorTop0.Play("rotate"); + _animatorTop1.Play("rotate"); + _animatorBottom.Play("rotate"); + Game1.GameManager.PlaySoundEffect("D360-46-2E"); + } + else if (_isRotating) + { + _opened = true; + Game1.GameManager.PlaySoundEffect("D360-02-02"); + Game1.GameManager.PlayMusic(); + + RemoveComponent(CollisionComponent.Index); + } + } + } + + private void Draw(SpriteBatch spriteBatch) + { + _animatorTop0.Draw(spriteBatch, new Vector2(EntityPosition.X, EntityPosition.Y), Color.White); + _animatorTop1.Draw(spriteBatch, new Vector2(EntityPosition.X, EntityPosition.Y), Color.White); + _animatorTop2.Draw(spriteBatch, new Vector2(EntityPosition.X + 16, EntityPosition.Y - 96), Color.White); + _animatorBottom.Draw(spriteBatch, new Vector2(EntityPosition.X, EntityPosition.Y), Color.White); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Dungeon/ObjTowerBackground.cs b/InGame/GameObjects/Dungeon/ObjTowerBackground.cs new file mode 100644 index 0000000..2143414 --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjTowerBackground.cs @@ -0,0 +1,69 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + public class ObjTowerBackground : GameObject + { + private readonly DictAtlasEntry _clouds; + private readonly Color _colorSky; + private readonly Color _colorCloud; + private readonly Vector2 _spawnPosition; + + private float _cloudOffset; + + public ObjTowerBackground() : base("final_cloud") { } + + public ObjTowerBackground(Map.Map map, int posX, int posY) : base(map) + { + _spawnPosition = new Vector2(posX, posY); + + _clouds = Resources.GetSprite("tower_clouds"); + _colorSky = new Color(106, 98, 253); + _colorCloud = new Color(254, 254, 254); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBackground, new CPosition(posX, posY, 0))); + } + + private void Update() + { + // move the clouds + _cloudOffset += (0.75f + MathF.Sin(_cloudOffset) * 0.25f) * 0.0125f * Game1.TimeMultiplier; + } + + private void Draw(SpriteBatch spriteBatch) + { + var cameraRectangle = MapManager.Camera.GetCameraRectangle(); + + // draw the cloud background + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + (int)(cameraRectangle.X / MapManager.Camera.Scale - MapManager.Camera.Scale), + (int)(_spawnPosition.Y + 80), + (int)(cameraRectangle.Width / MapManager.Camera.Scale + MapManager.Camera.Scale * 2), + (int)(Map.MapHeight * Values.TileSize - (int)(_spawnPosition.Y + 80))), _colorCloud); + + // draw the sky background + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + (int)(cameraRectangle.X / MapManager.Camera.Scale - MapManager.Camera.Scale), + (int)(cameraRectangle.Y / MapManager.Camera.Scale - MapManager.Camera.Scale), + (int)(cameraRectangle.Width / MapManager.Camera.Scale + MapManager.Camera.Scale * 2), + (int)(_spawnPosition.Y + 48) - (int)(cameraRectangle.Y / MapManager.Camera.Scale - MapManager.Camera.Scale)), _colorSky); + + // draw the clouds + var leftCloud = (int)Math.Floor((cameraRectangle.X / MapManager.Camera.Scale) / _clouds.SourceRectangle.Width) - 1; + var rightCloud = (int)Math.Ceiling((cameraRectangle.Right / MapManager.Camera.Scale) / _clouds.SourceRectangle.Width); + for (var i = leftCloud; i < rightCloud; i++) + //if (i != 0) + DrawHelper.DrawNormalized(spriteBatch, _clouds, new Vector2(_spawnPosition.X + _clouds.SourceRectangle.Width * i + _cloudOffset % _clouds.SourceRectangle.Width, _spawnPosition.Y + 48), Color.White); + + } + } +} diff --git a/InGame/GameObjects/Dungeon/ObjWallKnight.cs b/InGame/GameObjects/Dungeon/ObjWallKnight.cs new file mode 100644 index 0000000..e71ac3c --- /dev/null +++ b/InGame/GameObjects/Dungeon/ObjWallKnight.cs @@ -0,0 +1,53 @@ +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Things; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Enemies; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + internal class ObjWallKnight : GameObject + { + private readonly EnemyDarknut _knight; + + public ObjWallKnight() : base("wallKnight") { } + + public ObjWallKnight(Map.Map map, int posX, int posY, bool spawnGoldLeaf) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + var rectangle = new CBox(posX, posY, 0, 16, 16, 16); + var sprite = new CSprite("wallKnight", EntityPosition); + + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(rectangle, Values.CollisionTypes.Normal)); + AddComponent(HittableComponent.Index, new HittableComponent(rectangle, OnHit)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerBottom)); + + _knight = new EnemyDarknut(map, posX, posY + 10) + { + SpawnGoldLeaf = spawnGoldLeaf, + IsActive = false + }; + map.Objects.SpawnObject(_knight); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + // gets destroyed by a bomb + if (damageType == HitType.Bomb) + { + Game1.GameManager.PlaySoundEffect("D378-09-09"); + + _knight.WallSpawn(); + + Map.Objects.DeleteObjects.Add(this); + + return Values.HitCollision.Blocking; + } + + return Values.HitCollision.None; + } + } +} diff --git a/InGame/GameObjects/Enemies/EnemyAnglerFry.cs b/InGame/GameObjects/Enemies/EnemyAnglerFry.cs new file mode 100644 index 0000000..85d6954 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyAnglerFry.cs @@ -0,0 +1,110 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyAnglerFry : GameObject + { + private readonly BodyComponent _body; + private readonly AiDamageState _damageState; + private readonly AiComponent _aiComponent; + private readonly CSprite _sprite; + + private const float MovementSpeed = 0.5f; + private const int SpawnTime = 100; + + private float _swimCounter; + + public EnemyAnglerFry() : base("anglerFry") { } + + public EnemyAnglerFry(Map.Map map, int posX, int posY, int dir) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + var animator = AnimatorSaveLoad.LoadAnimator("Enemies/angler fry"); + animator.Play("move_" + dir); + + _sprite = new CSprite(EntityPosition); + _sprite.Color = Color.Transparent; + var animationComponent = new AnimationComponent(animator, _sprite, new Vector2(-8, -16)); + + _body = new BodyComponent(EntityPosition, -8, -16, 16, 16, 8) + { + CollisionTypes = Values.CollisionTypes.None, + DragAir = 0.8f, + DragWater = 0.8f, + IgnoresZ = true, + SplashEffect = false + }; + + var triggerCount = new AiTriggerCountdown(SpawnTime, TickSpawn, () => TickSpawn(1)); + var stateMoving = new AiState(UpdateMoving); + var stateDespawning = new AiState(); + stateDespawning.Trigger.Add(new AiTriggerCountdown(SpawnTime, TickDespawn, () => TickDespawn(1))); + + _aiComponent = new AiComponent(); + _aiComponent.Trigger.Add(triggerCount); + _aiComponent.States.Add("moving", stateMoving); + _aiComponent.States.Add("despawning", stateDespawning); + _damageState = new AiDamageState(this, _body, _aiComponent, _sprite, 1) + { SpawnItems = false, HitMultiplierX = 6, HitMultiplierY = 6 }; + _aiComponent.ChangeState("moving"); + + var hittableBox = new CBox(EntityPosition, -8, -14, 0, 16, 14, 8); + var damageBox = new CBox(EntityPosition, -7, -12, 0, 14, 12, 4); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(AnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(_sprite)); + + triggerCount.OnInit(); + _body.VelocityTarget.X = dir * MovementSpeed; + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + if (_damageState.OnHit(originObject, direction, type, damage, pieceOfPower) != Values.HitCollision.None) + { + _body.UpdateFieldState = false; + _body.VelocityTarget = Vector2.Zero; + } + + return Values.HitCollision.Repelling; + } + + private void TickSpawn(double time) + { + _sprite.Color = Color.White * (float)((SpawnTime - time) / SpawnTime); + } + + private void UpdateMoving() + { + // start despawning + if (EntityPosition.X < -8 || Map.MapWidth * 16 + 8 < EntityPosition.X) + _aiComponent.ChangeState("despawning"); + + _swimCounter += Game1.DeltaTime; + _body.VelocityTarget.Y = MathF.Sin(_swimCounter / 300f) * 0.25f; + } + + private void TickDespawn(double time) + { + _sprite.Color = Color.White * (float)(time / SpawnTime); + if (time <= 0) + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyAntiFairy.cs b/InGame/GameObjects/Enemies/EnemyAntiFairy.cs new file mode 100644 index 0000000..83bb9f2 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyAntiFairy.cs @@ -0,0 +1,104 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using ProjectZ.InGame.GameObjects.Dungeon; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyAntiFairy : GameObject + { + private readonly BodyComponent _body; + private readonly AiDamageState _aiDamageState; + + private readonly Color _lightColor = new Color(255, 255, 255); + + public EnemyAntiFairy() : base("antiFairy") { } + + public EnemyAntiFairy(Map.Map map, int posX, int posY) : base(map) + { + // not used for the enemy trigger + Tags = Values.GameObjectTag.Damage; + + EntityPosition = new CPosition(posX + 8, posY + 8, 0); + EntitySize = new Rectangle(-32, -32, 64, 64); + + var animator = AnimatorSaveLoad.LoadAnimator("Enemies/anti-fairy"); + animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(animator, sprite, new Vector2(-8, -8)); + + _body = new BodyComponent(EntityPosition, -6, -6, 12, 12, 8) + { + IgnoreHeight = true, + IgnoreHoles = true, + FieldRectangle = map.GetField(posX, posY), + MoveCollision = OnCollision, + CollisionTypes = + Values.CollisionTypes.Normal | + Values.CollisionTypes.Hole | + Values.CollisionTypes.NPCWall + }; + _body.VelocityTarget = new Vector2(-1, 1) * (3 / 4.0f); + + var aiComponent = new AiComponent(); + aiComponent.States.Add("idle", new AiState()); + aiComponent.ChangeState("idle"); + + _aiDamageState = new AiDamageState(this, _body, aiComponent, sprite, 1, false) + { + IgnoreZeroDamage = true, + FlameOffset = new Point(0, 2), + OnDeath = OnDeath + }; + + var hittableBox = new CBox(EntityPosition, -8, -8, 0, 16, 16, 8); + var damageBox = new CBox(EntityPosition, -7, -7, 0, 14, 14, 4); + + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(AiComponent.Index, aiComponent); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer) { WaterOutline = false }); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + AddComponent(LightDrawComponent.Index, new LightDrawComponent(DrawLight)); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + if (type == HitType.Boomerang || type == HitType.MagicPowder) + return _aiDamageState.OnHit(originObject, direction, type, damage, pieceOfPower); + + return Values.HitCollision.Blocking; + } + + private void OnCollision(Values.BodyCollision collider) + { + if ((collider & Values.BodyCollision.Horizontal) != 0) + _body.VelocityTarget.X = -_body.VelocityTarget.X; + if ((collider & Values.BodyCollision.Vertical) != 0) + _body.VelocityTarget.Y = -_body.VelocityTarget.Y; + } + + private void DrawLight(SpriteBatch spriteBatch) + { + DrawHelper.DrawLight(spriteBatch, new Rectangle((int)EntityPosition.X - 25, (int)EntityPosition.Y - 25, 50, 50), _lightColor * 0.5f); + } + + private void OnDeath(bool pieceOfPower) + { + // spawn fairy? ~50% cance + // not sure how this is calculated in the original game + if (Game1.RandomNumber.Next(0, 100) < 50) + Map.Objects.SpawnObject(new ObjDungeonFairy(Map, (int)EntityPosition.X, (int)EntityPosition.Y + 4, 0)); + + _aiDamageState.BaseOnDeath(pieceOfPower); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyAntiKirby.cs b/InGame/GameObjects/Enemies/EnemyAntiKirby.cs new file mode 100644 index 0000000..9d63017 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyAntiKirby.cs @@ -0,0 +1,330 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyAntiKirby : GameObject + { + private readonly Animator _animator; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _damageState; + private readonly DamageFieldComponent _damageField; + + private readonly ObjAnimator _suckParticles; + + private Vector2 _walkDirection; + + private int _direction; + private bool _hasPlayerTrapped; + private bool _endMove; + private bool _bounceSound; + + public EnemyAntiKirby() : base("anti kirby") { } + + public EnemyAntiKirby(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntityPosition.AddPositionListener(typeof(EnemyLikeLike), UpdatePosition); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/anti kirby"); + _animator.Play("idle_0"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -7, -12, 14, 12, 8) + { + CollisionTypes = Values.CollisionTypes.Normal | + Values.CollisionTypes.Enemy | + Values.CollisionTypes.NPCWall, + FieldRectangle = map.GetField(posX, posY), + Drag = 0.85f, + Bounciness = 0.3f, + AbsorbPercentage = 0.8f, + Gravity = -0.125f, + MaxJumpHeight = 3, + }; + + var stateIdle = new AiState(UpdateIdle) { Init = InitIdle }; + stateIdle.Trigger.Add(new AiTriggerRandomTime(EndIdle, 500, 850)); + var stateMove = new AiState(UpdateMoving) { Init = InitMoving }; + stateMove.Trigger.Add(new AiTriggerRandomTime(EndMove, 500, 850)); + var stateSuck = new AiState(UpdateSuck) { Init = InitSuck }; + stateSuck.Trigger.Add(new AiTriggerCountdown(4300, null, EndSuck)); + var stateTrap = new AiState(UpdateTrap) { Init = InitTrap }; + stateTrap.Trigger.Add(new AiTriggerCountdown(2000, null, EndTrap)); + var stateSpit = new AiState { Init = InitSpit }; + stateSpit.Trigger.Add(new AiTriggerCountdown(250, null, EndSpit)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("move", stateMove); + _aiComponent.States.Add("suck", stateSuck); + _aiComponent.States.Add("trap", stateTrap); + _aiComponent.States.Add("spit", stateSpit); + new AiFallState(_aiComponent, _body); + _damageState = new AiDamageState(this, _body, _aiComponent, sprite, 8, true, false) + { + HitMultiplierX = 2.5f, + HitMultiplierY = 2.5f, + }; + _damageState.OnDeath = OnDeath; + + var hittableBox = new CBox(EntityPosition, -7, -13, 0, 14, 13, 8, true); + var damageBox = new CBox(EntityPosition, -6, -12, 12, 12, 2); + + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageBox, HitType.Enemy, 4)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite) { ShadowWidth = 10 }); + + // suck animator + _suckParticles = new ObjAnimator(map, + (int)EntityPosition.X, (int)EntityPosition.Y, Values.LayerPlayer, "Enemies/anti kirby suck", "", false); + _suckParticles.EntityPosition.SetParent(EntityPosition, Vector2.Zero); + map.Objects.SpawnObject(_suckParticles); + + _aiComponent.ChangeState("idle"); + } + + private void InitSuck() + { + _damageField.IsActive = false; + _body.IgnoresZ = true; + + // look in the direction of the player + _direction = EntityPosition.X > MapManager.ObjLink.EntityPosition.X ? 0 : 1; + + _animator.Play("suck_" + _direction); + + // suck animation particles + _suckParticles.AnimationComponent.SpriteOffset = new Vector2(_direction == 0 ? -15 : 15, 2); + _suckParticles.Animator.Play("suck_" + _direction); + } + + private void UpdateSuck() + { + Game1.GameManager.PlaySoundEffect("D378-59-3B", false, 0.75f, 0, false, 100); + + if (EntityPosition.Z < 12) + { + EntityPosition.Z += Game1.TimeMultiplier * 0.25f; + if (EntityPosition.Z > 12) + EntityPosition.Z = 12; + } + + // suck in the player + var playerDirection = new Vector2(EntityPosition.X, EntityPosition.Y - EntityPosition.Z + 4) - MapManager.ObjLink.EntityPosition.Position; + var playerDir = EntityPosition.X > MapManager.ObjLink.EntityPosition.X ? 0 : 1; + + // trap the player if he is close enough + if (playerDirection.Length() < 4) + { + ToTrap(); + } + else if (playerDirection.Length() < 48 && playerDir == _direction) + { + playerDirection.Normalize(); + MapManager.ObjLink._body.Velocity.X = 0.5f * playerDirection.X; + MapManager.ObjLink._body.Velocity.Y = 0.5f * playerDirection.Y; + MapManager.ObjLink._body.DisableVelocityTargetMultiplier = true; + } + } + + private void EndSuck() + { + _damageField.IsActive = true; + _body.IgnoresZ = false; + _aiComponent.ChangeState("idle"); + + StopSuckSound(); + } + + private void StopSuckSound() + { + Game1.GameManager.StopSoundEffect("D378-59-3B"); + } + + private void ToTrap() + { + MapManager.ObjLink.TrapPlayer(true); + MapManager.ObjLink.SetPosition(EntityPosition.Position); + + _aiComponent.ChangeState("trap"); + _hasPlayerTrapped = true; + + StopSuckSound(); + } + + private void InitTrap() + { + _bounceSound = false; + _body.IgnoresZ = false; + _suckParticles.Animator.Play("hidden"); + _animator.Play("full_" + _direction); + } + + private void UpdateTrap() + { + if (!_body.WasGrounded && _body.IsGrounded && !_bounceSound) + { + _bounceSound = true; + Game1.GameManager.PlaySoundEffect("D360-09-09"); + } + } + + private void EndTrap() + { + _hasPlayerTrapped = false; + + MapManager.ObjLink.SetPosition(EntityPosition.Position); + MapManager.ObjLink.FreeTrappedPlayer(); + MapManager.ObjLink.CurrentState = ObjLink.State.Jumping; + MapManager.ObjLink._body.Velocity = new Vector3(_direction == 0 ? -1.5f : 1.5f, 0, 1.25f); + + _aiComponent.ChangeState("spit"); + Game1.GameManager.PlaySoundEffect("D360-08-08"); + Game1.GameManager.InflictDamage(2); + } + + private void InitSpit() + { + _animator.Play("suck_" + _direction); + } + + private void EndSpit() + { + _aiComponent.ChangeState("idle"); + } + + private void InitIdle() + { + _animator.Play("idle_" + _direction); + _suckParticles.Animator.Play("hidden"); + } + + private void UpdateIdle() + { + // jump on the spot + if (_body.IsGrounded) + _body.Velocity.Z = 0.9f; + } + + private void EndIdle() + { + _aiComponent.ChangeState("move"); + } + + private void InitMoving() + { + _endMove = false; + + var rotation = Game1.RandomNumber.Next(0, 628) / 100f; + _walkDirection.X = MathF.Sin(rotation); + _walkDirection.Y = MathF.Cos(rotation); + + _direction = _walkDirection.X < 0 ? 0 : 1; + _animator.Play("idle_" + _direction); + } + + private void UpdateMoving() + { + // jump + if (_body.IsGrounded) + { + if (_endMove) + { + var playerDirection = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + var playerDir = EntityPosition.X > MapManager.ObjLink.EntityPosition.X ? 0 : 1; + + if (Math.Abs(playerDirection.Y) < 32 && Math.Abs(playerDirection.X) < 48 && playerDir == _direction) + _aiComponent.ChangeState("suck"); + else + _aiComponent.ChangeState("idle"); + } + else + { + _body.Velocity = new Vector3(_walkDirection.X, _walkDirection.Y, 0.9f); + } + } + } + + private void EndMove() + { + _damageField.IsActive = true; + _endMove = true; + } + + private void UpdatePosition(CPosition newPosition) + { + if (_hasPlayerTrapped) + MapManager.ObjLink.SetPosition(newPosition.Position); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_aiComponent.CurrentStateId == "move") + _aiComponent.ChangeState("idle"); + + if ((damageType & HitType.Sword) != 0 || + damageType == HitType.Bow || + damageType == HitType.Hookshot || + damageType == HitType.MagicPowder) + damage = 0; + + // 4 hits + if (damageType == HitType.Boomerang) + damage = 2; + + if (damageType == HitType.Bomb || + damageType == HitType.MagicRod) + damage = 4; + + if (damage != 0 && _hasPlayerTrapped) + EndTrap(); + + return _damageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + } + + private void OnDeath(bool pieceOfPower) + { + StopSuckSound(); + + _damageState.BaseOnDeath(pieceOfPower); + + // remove the suck animation particles + Map.Objects.DeleteObjects.Add(_suckParticles); + + // free the player + if (_hasPlayerTrapped) + MapManager.ObjLink.FreeTrappedPlayer(); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (_hasPlayerTrapped) + return false; + + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction * 1.5f, _body.Velocity.Z); + + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyArmMimic.cs b/InGame/GameObjects/Enemies/EnemyArmMimic.cs new file mode 100644 index 0000000..6597a73 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyArmMimic.cs @@ -0,0 +1,151 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyArmMimic : GameObject + { + private readonly BodyComponent _body; + private readonly Animator _animator; + private readonly AiDamageState _aiDamageState; + private readonly AiTriggerTimer _repelTimer; + private readonly AiStunnedState _aiStunnedState; + + private Vector2 _lastPosition; + private int _direction; + private bool _wasColliding; + + public EnemyArmMimic() : base("armMimic") { } + + public EnemyArmMimic(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/arm mimic"); + + var sprite = new CSprite(EntityPosition); + var animatorComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -16)); + + _body = new BodyComponent(EntityPosition, -5, -10, 10, 10, 8) + { + AvoidTypes = Values.CollisionTypes.Hole | Values.CollisionTypes.NPCWall, + IsSlider = true, + MaxSlideDistance = 4.0f + }; + + var stateUpdate = new AiState(Update); + + var aiComponent = new AiComponent(); + aiComponent.Trigger.Add(_repelTimer = new AiTriggerTimer(500)); + + aiComponent.States.Add("idle", stateUpdate); + new AiFallState(aiComponent, _body, null, null, 300); + _aiDamageState = new AiDamageState(this, _body, aiComponent, sprite, 2); + _aiStunnedState = new AiStunnedState(aiComponent, animatorComponent, 3300, 900); + + aiComponent.ChangeState("idle"); + + var hittableBox = new CBox(EntityPosition, -6, -15, 2, 12, 15, 8); + var damageBox = new CBox(EntityPosition, -6, -12, 2, 12, 12, 4); + var pushableBox = new CBox(EntityPosition, -5, -14, 2, 10, 14, 4); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(hittableBox, HitType.Enemy, 12)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(AiComponent.Index, aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animatorComponent); + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite)); + } + + private void Update() + { + var moved = false; + var playerDistance = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + + // move when near the player + if (playerDistance.Length() < 80) + { + if (_wasColliding) + { + var direction = -MapManager.ObjLink.LastMoveVector; + var diff = (MapManager.ObjLink.EntityPosition.Position - _lastPosition) / Game1.TimeMultiplier; + + // this will stop the enemy if the player is walking into an obstacle + direction = new Vector2( + Math.Min(Math.Abs(direction.X), Math.Abs(diff.X)) * Math.Sign(direction.X), + Math.Min(Math.Abs(direction.Y), Math.Abs(diff.Y)) * Math.Sign(direction.Y)); + + _body.VelocityTarget = direction * 0.75f; + + if (direction.Length() > 0.01f) + { + moved = true; + _direction = AnimationHelper.GetDirection(direction); + + if (_animator.CurrentAnimation.Id != "walk_" + _direction) + _animator.Play("walk_" + _direction); + else + _animator.Continue(); + } + } + + _wasColliding = true; + _lastPosition = MapManager.ObjLink.EntityPosition.Position; + } + else + { + _wasColliding = false; + _body.VelocityTarget = Vector2.Zero; + } + + if (!moved) + _animator.Pause(); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X * 1.75f, direction.Y * 1.75f, _body.Velocity.Z); + + return true; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (!_repelTimer.State) + return Values.HitCollision.None; + _repelTimer.Reset(); + + // stun state + if (damageType == HitType.Hookshot || damageType == HitType.Boomerang) + { + _body.VelocityTarget = Vector2.Zero; + _body.Velocity.X += direction.X * 4.0f; + _body.Velocity.Y += direction.Y * 4.0f; + + _aiStunnedState.StartStun(); + _animator.Pause(); + + return Values.HitCollision.Enemy; + } + + // damaged not from the front; piece of power or while using pegasus boots + if (damageType != HitType.PegasusBootsSword && damageType != HitType.SwordShot && (damageType & HitType.SwordSpin) == 0 && !pieceOfPower) + damage = 0; + + return _aiDamageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyArmos.cs b/InGame/GameObjects/Enemies/EnemyArmos.cs new file mode 100644 index 0000000..514561b --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyArmos.cs @@ -0,0 +1,185 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyArmos : GameObject + { + private readonly Animator _animator; + private readonly AnimationComponent _animationComponent; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly DamageFieldComponent _damageField; + private readonly BodyCollisionComponent _bodyCollision; + private readonly AiDamageState _aiDamageState; + private readonly AiStunnedState _sunnedState; + private readonly AiTriggerRandomTime _walkCounter; + + private readonly string _animationPrefix; + + private float _moveSpeed = 0.5f; + private float _counter; + private int _direction; + private bool _collided; + + public EnemyArmos() : base("armos") { } + + public EnemyArmos(Map.Map map, int posX, int posY, bool darkArmos) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 17); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/armos"); + _animationPrefix = darkArmos ? "_dark" : ""; + + var sprite = new CSprite(EntityPosition); + _animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -16)); + + _body = new BodyComponent(EntityPosition, -7, -12, 14, 12, 8) + { + MoveCollision = OnCollision, + CollisionTypes = Values.CollisionTypes.Normal | + Values.CollisionTypes.Enemy, + AvoidTypes = Values.CollisionTypes.Hole | Values.CollisionTypes.NPCWall, + FieldRectangle = map.GetField(posX, posY), + Bounciness = 0.25f, + Drag = 0.8f + }; + + var stateIdle = new AiState { Init = InitIdle }; + var stateAwaking = new AiState(UpdateAwaking) { Init = InitAwaking }; + var stateWalking = new AiState { Init = InitWalking }; + stateWalking.Trigger.Add(_walkCounter = new AiTriggerRandomTime(ChangeDirection, 1000, 1500)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("awaking", stateAwaking); + _aiComponent.States.Add("walking", stateWalking); + new AiFallState(_aiComponent, _body, null, null); + new AiDeepWaterState(_body); + _sunnedState = new AiStunnedState(_aiComponent, _animationComponent, 3300, 900) { ShakeOffset = 1, SilentStateChange = false, ReturnState = "walking" }; + _aiDamageState = new AiDamageState(this, _body, _aiComponent, sprite, 2) { SpawnItem = "arrow_1" }; + + _aiComponent.ChangeState("idle"); + + var hittableBox = new CBox(EntityPosition, -7, -15, 14, 15, 8); + var damageBox = new CBox(EntityPosition, -8, -13, 0, 16, 13, 4); + + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageBox, HitType.Enemy, 8) { IsActive = false }); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(CollisionComponent.Index, _bodyCollision = new BodyCollisionComponent(_body, Values.CollisionTypes.Enemy)); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(BaseAnimationComponent.Index, _animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_aiDamageState.IsInDamageState()) + return Values.HitCollision.None; + + if (_aiComponent.CurrentStateId == "idle" || _aiComponent.CurrentStateId == "awaking") + return Values.HitCollision.RepellingParticle; + + if (damageType == HitType.MagicRod || damageType == HitType.MagicPowder) + return Values.HitCollision.Blocking; + + if (damageType == HitType.Bomb || damageType == HitType.Bow) + return _aiDamageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + + if (damageType == HitType.Boomerang) + return _aiDamageState.OnHit(gameObject, direction, damageType, 1, pieceOfPower); + + if (damageType == HitType.Hookshot) + { + _body.VelocityTarget = Vector2.Zero; + _damageField.IsActive = false; + _animator.Pause(); + _sunnedState.StartStun(); + } + + _aiDamageState.HitKnockBack(gameObject, direction, damageType, pieceOfPower, false); + + Game1.GameManager.PlaySoundEffect("D360-09-09"); + + if (pieceOfPower) + Game1.GameManager.PlaySoundEffect("D370-17-11"); + + return Values.HitCollision.Blocking; + } + + private void InitIdle() + { + _body.VelocityTarget = Vector2.Zero; + _animator.Play("idle" + _animationPrefix); + } + + private void InitAwaking() + { + _animator.Play("awaking" + _animationPrefix); + } + + private void UpdateAwaking() + { + // wobble + _counter += Game1.DeltaTime; + _animationComponent.SpriteOffset.X = -8 + 1 * MathF.Sin(MathF.PI * ((_counter / 1000) * (60 / 4f))); + + if (!_animator.IsPlaying) + { + _animationComponent.SpriteOffset.X = -8; + _aiComponent.ChangeState("walking"); + } + + _animationComponent.UpdateSprite(); + } + + private void InitWalking() + { + ChangeDirection(); + _animator.Play("walking" + _animationPrefix); + _damageField.IsActive = true; + _bodyCollision.IsActive = false; + _collided = false; + } + + private void ChangeDirection() + { + // random new direction + _direction = Game1.RandomNumber.Next(0, 8); + var radius = (float)Math.PI * (_direction / 4f); + _body.VelocityTarget = new Vector2((float)Math.Sin(radius), (float)Math.Cos(radius)) * _moveSpeed; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X, direction.Y, _body.Velocity.Z); + else if (_aiComponent.CurrentStateId == "idle") + _aiComponent.ChangeState("awaking"); + + return true; + } + + private void OnCollision(Values.BodyCollision direction) + { + // cut the time we walk into the wall + if (!_collided) + { + _walkCounter.CurrentTime /= 2; + _collided = true; + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyBeamos.cs b/InGame/GameObjects/Enemies/EnemyBeamos.cs new file mode 100644 index 0000000..79c1bfb --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyBeamos.cs @@ -0,0 +1,228 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyBeamos : GameObject + { + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly AiTriggerSwitch _shootCooldown; + private readonly CSprite _sprite; + + private readonly Rectangle _fieldRectangle; + + private Vector2 _shootDirection; + private Vector2 _shootOrigin; + + private float _shootCounter; + private float _beamosRotation; + + private int _shootsFired; + + public EnemyBeamos() : base("beamos") { } + + public EnemyBeamos(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Trap; + + EntityPosition = new CPosition(posX + 8, posY + 14, 0); + EntitySize = new Rectangle(-8, -14, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/beamos"); + _animator.Play("idle"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + var body = new BodyComponent(EntityPosition, -7, -12, 14, 14, 8); + + _fieldRectangle = Map.GetField(posX, posY); + + var stateIdle = new AiState(UpdateIdle); + stateIdle.Trigger.Add(_shootCooldown = new AiTriggerSwitch(1000)); + var statePreShoot = new AiState(); + statePreShoot.Trigger.Add(new AiTriggerCountdown(16000 / 60, TickPreShoot, PreShootEnd)); + var stateShoot = new AiState(UpdateShoot); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("preShoot", statePreShoot); + _aiComponent.States.Add("shoot", stateShoot); + _aiComponent.ChangeState("idle"); + + var hittableBox = new CBox(EntityPosition, -5, -12, 0, 10, 14, 8); + var damageBox = new CBox(EntityPosition, -5, -12, 0, 10, 14, 4); + + AddComponent(BodyComponent.Index, body); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 1)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(PushableComponent.Index, new PushableComponent(damageBox, OnPush)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerPlayer)); + } + + private Vector2 GetOrigin() + { + return new Vector2(EntityPosition.X, EntityPosition.Y - 8) + + new Vector2(-MathF.Cos(_beamosRotation), -MathF.Sin(_beamosRotation)) * 4; + } + + private void UpdateIdle() + { + if (!_shootCooldown.State) + return; + + // get the direction of the beamos from the current animation frame (8 frames for a full rotation) + var animationFrame = _animator.CurrentFrameIndex; + _beamosRotation = animationFrame * (MathF.PI * 2) / 8f; + _shootOrigin = new Vector2(EntityPosition.X, EntityPosition.Y - 8) + + new Vector2(-MathF.Cos(_beamosRotation), -MathF.Sin(_beamosRotation)) * 4; + + var playerPosition = MapManager.ObjLink.EntityPosition.Position; + var targetPosition = new Vector2(playerPosition.X, playerPosition.Y - 6); + var playerDirection = targetPosition - _shootOrigin; + + // if we normalize a zero vector we crash + // it is really unlikely (probably impossible) but we need to be careful + if (playerDirection != Vector2.Zero && + (playerDirection.Length() < 72 || _fieldRectangle.Contains(MapManager.ObjLink.EntityPosition.Position))) + { + playerDirection.Normalize(); + + // there is probably a nicer way to calculate the difference between two angles + var playerRotation = MathF.Atan2(-playerDirection.Y, -playerDirection.X); + if (playerRotation < 0) + playerRotation += MathF.PI * 2; + + var rotationDistance = MathF.Abs(_beamosRotation - playerRotation); + if (rotationDistance > MathF.PI) + rotationDistance = MathF.PI - rotationDistance % MathF.PI; + + // start shooting if the beamos is looking at the player + // we do not divide by 8 because we offset the shoot origin and do not get 8 perfect angles + if (rotationDistance < MathF.PI / 7.5f) + { + _shootDirection = playerDirection; + + if (!CheckForCollision(_shootOrigin, targetPosition)) + ToPreShoot(); + } + } + } + + private bool CheckForCollision(Vector2 startPosition, Vector2 endPosition) + { + var direction = endPosition - startPosition; + var distance = direction.Length(); + direction.Normalize(); + + var currentPosition = startPosition; + var steps = 15; + + while (true) + { + steps--; + + var modX = currentPosition.X % Values.TileSize; + var modY = currentPosition.Y % Values.TileSize; + + // move to the next tile edge on the x or y axis + // could probably be written in a nicer way + var stepX = Math.Abs((((int)(currentPosition.X / Values.TileSize) + + (modX == 0 ? Math.Sign(direction.X) : direction.X < 0 ? 0 : 1)) * Values.TileSize - currentPosition.X) / direction.X); + var stepY = Math.Abs((((int)(currentPosition.Y / Values.TileSize) + + (modY == 0 ? Math.Sign(direction.Y) : direction.Y < 0 ? 0 : 1)) * Values.TileSize - currentPosition.Y) / direction.Y); + + currentPosition += direction * (stepX < stepY ? stepX : stepY); + + // reached the end position without encountering anything? + var traveledDistance = (startPosition - currentPosition).Length(); + if (distance < traveledDistance || steps < 0) + return false; + + // check for a colliding box on the line of sight + var outBox = Box.Empty; + var tileX = (int)((currentPosition.X + (direction.X < 0 ? -1 : 1)) / Values.TileSize) * Values.TileSize; + var tileY = (int)((currentPosition.Y + (direction.Y < 0 ? -1 : 1)) / Values.TileSize) * Values.TileSize; + if (Map.Objects.Collision(new Box(tileX, tileY, 2, 16, 16, 4), Box.Empty, Values.CollisionTypes.Normal, 0, 1, ref outBox)) + return true; + } + } + + private void TickPreShoot(double count) + { + _sprite.SpriteShader = count % (8000 / 60f) >= (4000 / 60f) ? Resources.DamageSpriteShader0 : null; + } + + private void PreShootEnd() + { + Game1.GameManager.PlaySoundEffect("D378-08-08"); + _aiComponent.ChangeState("shoot"); + } + + private void ToPreShoot() + { + _shootCounter = 0; + _shootsFired = 0; + + _animator.Pause(); + _aiComponent.ChangeState("preShoot"); + } + + private void UpdateShoot() + { + // 16 projectiles + // ~4 pixels/frame + // 60 projectiles/second + _shootCounter += Game1.DeltaTime; + + // spawn projectiles + // this is a little complicated because the game can run at different framerates + var projectileInterval = 1 / 60f * 1000; + while (_shootCounter > projectileInterval * _shootsFired) + { + _shootOrigin = GetOrigin(); + // we calculate the position of the first projectile + var spawnPosition = _shootOrigin + _shootDirection * (4 + _shootCounter / 1000f * 60 * 4); + // now we go back in the opposite direction to find the exact position of the current projectile + spawnPosition -= _shootDirection * _shootsFired * 4; + + // spawn the projectile + var newProjectile = new EnemyBeamosProjectile(Map, spawnPosition, _shootDirection * 4, _shootsFired == 0); + Map.Objects.SpawnObject(newProjectile); + + _shootsFired++; + + if (_shootsFired >= 16) + { + _animator.Continue(); + _aiComponent.ChangeState("idle"); + _shootCooldown.Reset(); + } + } + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType pushType) + { + if (pushType == PushableComponent.PushType.Impact) + return true; + + return false; + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + return Values.HitCollision.RepellingParticle; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyBeamosProjectile.cs b/InGame/GameObjects/Enemies/EnemyBeamosProjectile.cs new file mode 100644 index 0000000..18f3ae7 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyBeamosProjectile.cs @@ -0,0 +1,88 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Things; +using static ProjectZ.InGame.GameObjects.Base.Components.PushableComponent; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyBeamosProjectile : GameObject + { + private readonly DamageFieldComponent _damageField; + private readonly BodyComponent _body; + + private bool _isFirstProjectile; + + public EnemyBeamosProjectile(Map.Map map, Vector2 position, Vector2 velocityTarget, bool isFirstProjectile) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(position.X, position.Y, 0); + EntitySize = new Rectangle(-3, -3, 6, 6); + + _isFirstProjectile = isFirstProjectile; + + var sprite = new CSprite("beamos projectile", EntityPosition, new Vector2(-2, -2)); + + _body = new BodyComponent(EntityPosition, -1, -1, 2, 2, 8) + { + IgnoresZ = true, + IgnoreHoles = true, + // can go over some colliders + Level = 1, + // the reason for the simple movement is to not align the body + // with the colliding object and spawn the particle at an offset position + SimpleMovement = true, + VelocityTarget = velocityTarget, + MoveCollision = OnCollision, + CollisionTypes = Values.CollisionTypes.Normal + }; + + var damageCollider = new CBox(EntityPosition, -2, -2, 0, 4, 4, 4); + _damageField = new DamageFieldComponent(damageCollider, HitType.Enemy, 4) + { + OnDamage = OnDamage + }; + + AddComponent(PushableComponent.Index, new PushableComponent(damageCollider, OnPush)); + AddComponent(DamageFieldComponent.Index, _damageField); + AddComponent(BodyComponent.Index, _body); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerPlayer)); + } + + private bool OnPush(Vector2 direction, PushType pushType) + { + if (pushType == PushType.Impact) + DeleteProjectile(); + + return false; + } + + private bool OnDamage() + { + DeleteProjectile(); + + return _damageField.DamagePlayer(); + } + + private void OnCollision(Values.BodyCollision collision) + { + DeleteProjectile(); + } + + private void DeleteProjectile() + { + Map.Objects.DeleteObjects.Add(this); + + if (_isFirstProjectile) + { + // spawn particle + var animation = new ObjAnimator(Map, 0, 0, Values.LayerTop, "Particles/despawnParticle", "idle", true); + animation.EntityPosition.Set(EntityPosition.Position + _body.VelocityTarget * Game1.TimeMultiplier); + Map.Objects.SpawnObject(animation); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyBeetle.cs b/InGame/GameObjects/Enemies/EnemyBeetle.cs new file mode 100644 index 0000000..217e6ca --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyBeetle.cs @@ -0,0 +1,148 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyBeetle : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly AiFallState _aiFallState; + private readonly AiTriggerRandomTime _directionChangeCounter; + private readonly AiDamageState _damageState; + + private float _walkSpeed = 0.5f; + private int _direction; + + private bool _finishedSpawning; + + public EnemyBeetle() : base("beetle") { } + + public EnemyBeetle(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 14, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/beetle"); + _animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -11)); + + _body = new BodyComponent(EntityPosition, -5, -8, 10, 8, 8) + { + AbsorbPercentage = 0.9f, + CollisionTypes = + Values.CollisionTypes.Normal | + Values.CollisionTypes.Enemy | + Values.CollisionTypes.Player, + AvoidTypes = + Values.CollisionTypes.Hole | + Values.CollisionTypes.NPCWall, + HoleOnPull = OnHolePull, + AbsorbStop = 0, + FieldRectangle = map.GetField(posX, posY), + Bounciness = 0.25f, + Drag = 0.85f, + MoveCollision = OnMoveCollision + }; + + var stateMoving = new AiState(); + stateMoving.Trigger.Add(_directionChangeCounter = new AiTriggerRandomTime(ChangeDirection, 500, 750)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("moving", stateMoving); + + // AiFallState sets the HoleAbsorb function + _aiFallState = new AiFallState(_aiComponent, _body, OnHoleAbsorb, null); + _body.HoleAbsorb = OnHoleAbsorb; + + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + playerDirection.Normalize(); + _body.VelocityTarget = playerDirection * _walkSpeed; + + _aiComponent.ChangeState("moving"); + + var damageCollider = new CBox(EntityPosition, -6, -10, 0, 12, 10, 4); + _damageState = new AiDamageState(this, _body, _aiComponent, sprite, 1); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite) { Height = 1.0f, Rotation = 0.1f }); + } + + private void OnMoveCollision(Values.BodyCollision collision) + { + _directionChangeCounter.CurrentTime *= 0.5f; + _body.VelocityTarget = Vector2.Zero; + } + + private void OnHolePull(Vector2 direction, float percentage) + { + if (!_finishedSpawning) + { + _body.HoleAbsorption *= 0.25f; + _body.SpeedMultiply = 1.0f; + + if (percentage == 0) + { + _finishedSpawning = true; + ChangeDirection(); + } + } + } + + private void OnHoleAbsorb() + { + if (_finishedSpawning) + { + _animator.SpeedMultiplier = 2f; + _aiFallState.OnHoleAbsorb(); + } + else + { + _body.HoleAbsorption *= 0.25f; + _body.SpeedMultiply = 1.0f; + } + } + + private void ChangeDirection() + { + // random start position/state + _direction = Game1.RandomNumber.Next(0, 4); + _body.VelocityTarget = AnimationHelper.DirectionOffset[_direction] * _walkSpeed; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X * 1.75f, direction.Y * 1.75f, _body.Velocity.Z); + + _finishedSpawning = true; + + return true; + } + + public Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + // make sure to fall into the hole after getting burned while coming out + _finishedSpawning = true; + + return _damageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyBladeTrap.cs b/InGame/GameObjects/Enemies/EnemyBladeTrap.cs new file mode 100644 index 0000000..13794e2 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyBladeTrap.cs @@ -0,0 +1,131 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyBladeTrap : GameObject + { + private readonly AiComponent _aiComponent; + + private readonly RectangleF[] _collisionRectangles = new RectangleF[4]; + private readonly Vector2[] _directions = { new Vector2(-1, 0), new Vector2(1, 0), new Vector2(0, -1), new Vector2(0, 1) }; + private readonly int[] _maxPosition = new int[4]; + + private Vector2 _startPosition; + private float _movePosition; + private int _moveDir; + + public EnemyBladeTrap() : base("bladeTrap") { } + + public EnemyBladeTrap(Map.Map map, int posX, int posY, int left, int right, int top, int bottom) : base(map) + { + Tags = Values.GameObjectTag.Damage; + + EntityPosition = new CPosition(posX, posY, 0); + _startPosition = new Vector2(posX, posY); + + var animator = AnimatorSaveLoad.LoadAnimator("Enemies/bladetrap"); + animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(animator, sprite, new Vector2(0, 0)); + + var padding = 2; + var width = 16 + 2 * padding; + var height = 16 + 2 * padding; + + _maxPosition[0] = left * 16; + _maxPosition[1] = right * 16; + _maxPosition[2] = top * 16; + _maxPosition[3] = bottom * 16; + + _collisionRectangles[0] = new RectangleF(posX - left * 16 - 16, posY - padding, left * 16 + 16, height); + _collisionRectangles[1] = new RectangleF(posX + 16, posY - padding, right * 16 + 16, height); + _collisionRectangles[2] = new RectangleF(posX - padding, posY - top * 16 - 16, width, top * 16 + 16); + _collisionRectangles[3] = new RectangleF(posX - padding, posY + 16, width, bottom * 16 + 16); + + var stateWait = new AiState(); + stateWait.Trigger.Add(new AiTriggerCountdown(350, null, () => _aiComponent.ChangeState("back"))); + var stateCooldown = new AiState(); + stateCooldown.Trigger.Add(new AiTriggerCountdown(500, null, () => _aiComponent.ChangeState("idle"))); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", new AiState(UpdateIdle)); + _aiComponent.States.Add("snap", new AiState(UpdateSnap)); + _aiComponent.States.Add("wait", stateWait); + _aiComponent.States.Add("back", new AiState(UpdateMoveBack)); + _aiComponent.States.Add("cooldown", stateCooldown); + _aiComponent.ChangeState("idle"); + + var bodyBox = new CBox(EntityPosition, 2, 2, 0, 12, 12, 4); + AddComponent(PushableComponent.Index, new PushableComponent(bodyBox, OnPush) { RepelMultiplier = 1.5f }); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(bodyBox, HitType.Enemy, 4)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(HittableComponent.Index, new HittableComponent(bodyBox, OnHit)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerPlayer)); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + return true; + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + return Values.HitCollision.RepellingParticle; + } + + private void UpdateIdle() + { + // trigger trap + for (var i = 0; i < _directions.Length; i++) + if (_collisionRectangles[i].Intersects(MapManager.ObjLink.BodyRectangle)) + { + Game1.GameManager.PlaySoundEffect("D378-10-0A"); + _aiComponent.ChangeState("snap"); + _moveDir = i; + } + } + + private void UpdateSnap() + { + _movePosition += 2 * Game1.TimeMultiplier; + + // collision? + if (_movePosition >= _maxPosition[_moveDir]) + { + _movePosition = _maxPosition[_moveDir]; + _aiComponent.ChangeState("wait"); + Game1.GameManager.PlaySoundEffect("D360-07-07"); + } + + UpdatePosition(); + } + + private void UpdateMoveBack() + { + if (_movePosition > 0) + _movePosition -= 0.5f * Game1.TimeMultiplier; + else + { + _movePosition = 0; + _aiComponent.ChangeState("cooldown"); + } + + UpdatePosition(); + } + + private void UpdatePosition() + { + EntityPosition.Set(_startPosition + _directions[_moveDir] * _movePosition); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyBloober.cs b/InGame/GameObjects/Enemies/EnemyBloober.cs new file mode 100644 index 0000000..5ef2914 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyBloober.cs @@ -0,0 +1,128 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyBloober : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + + private readonly Vector2 _startPosition; + + public EnemyBloober() : base("bloober") { } + + public EnemyBloober(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _startPosition = EntityPosition.Position; + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/bloober"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -16)); + + _body = new BodyComponent(EntityPosition, -6, -13, 12, 10, 8) + { + MoveCollision = OnCollision, + AvoidTypes = Values.CollisionTypes.NPCWall, + CollisionTypes = Values.CollisionTypes.Normal, + Gravity2DWater = 0.035f, + DeepWaterOffset = -9 + }; + + var stateUp = new AiState(UpdateUp); + stateUp.Trigger.Add(new AiTriggerRandomTime(ToMoveDown, 650, 750)); + var stateDown = new AiState(UpdateDown); + stateDown.Trigger.Add(new AiTriggerRandomTime(ToMoveUp, 550, 650)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("moveUp", stateUp); + _aiComponent.States.Add("moveDown", stateDown); + var damageState = new AiDamageState(this, _body, _aiComponent, sprite, 1) { HitMultiplierX = 2.0f, HitMultiplierY = 2.0f, FlameOffset = new Point(0, 3) }; + + ToMoveUp(); + + var hittableBox = new CBox(EntityPosition, -7, -14, 0, 14, 12, 8); + var damageBox = new CBox(EntityPosition, -7, -14, 0, 14, 12, 4); + + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, damageState.OnHit)); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + } + + private void ToMoveUp() + { + var playerDistance = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + + // move towards the start position or the player depending on the distance to the player + if (playerDistance.Length() < 80) + MoveTowardPosition(MapManager.ObjLink.EntityPosition.Position, 0.45f); + else + MoveTowardPosition(_startPosition, 0.25f); + } + + private void MoveTowardPosition(Vector2 position, float speed) + { + // do not change to move up state if the player is below the enemy + if (EntityPosition.Y - 6 < position.Y && + (_body.LastVelocityCollision & Values.BodyCollision.Bottom) == 0) + { + _aiComponent.ChangeState("moveDown"); + return; + } + + _aiComponent.ChangeState("moveUp"); + _animator.Play("up"); + + // move towards the player + var dir = position.X < EntityPosition.X ? -1 : 1; + _body.VelocityTarget.X = dir * speed; + } + + private void UpdateUp() + { + _body.DisableVelocityTargetMultiplier = true; + + // swim up if in deep water + if (_body.CurrentFieldState.HasFlag(MapStates.FieldStates.DeepWater)) + _body.Velocity.Y = -0.65f; + else + { + ToMoveDown(); + } + } + + private void ToMoveDown() + { + _aiComponent.ChangeState("moveDown"); + _animator.Play("down"); + _body.Velocity.X = _body.VelocityTarget.X; + _body.VelocityTarget.X = 0; + } + + private void UpdateDown() + { + + } + + private void OnCollision(Values.BodyCollision collision) + { + + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyBomber.cs b/InGame/GameObjects/Enemies/EnemyBomber.cs new file mode 100644 index 0000000..7a2857d --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyBomber.cs @@ -0,0 +1,148 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyBomber : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly AiDamageState _damageState; + + private Vector2 _startPosition; + + private float _flyHeight = 14; + + public EnemyBomber() : base("bomber") { } + + public EnemyBomber(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, _flyHeight); + EntitySize = new Rectangle(-12, -32, 24, 32); + + _startPosition = EntityPosition.Position; + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/bomber"); + _animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-12, -16)); + + _body = new BodyComponent(EntityPosition, -8, -12, 16, 12, 8) + { + CollisionTypes = Values.CollisionTypes.None, + DragAir = 0.975f, + Gravity = -0.175f, + IgnoreHoles = true, + IgnoresZ = true, + }; + + var stateWaiting = new AiState() { Init = InitWaiting }; + stateWaiting.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("moving"), 500, 1000)); + var stateMoving = new AiState() { Init = InitMoving }; + stateMoving.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("waiting"), 500, 1000)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("waiting", stateWaiting); + _aiComponent.States.Add("moving", stateMoving); + _damageState = new AiDamageState(this, _body, _aiComponent, sprite, 2) { OnBurn = OnBurn }; + + _aiComponent.ChangeState("waiting"); + + var hittableBox = new CBox(EntityPosition, -7, -12, 0, 14, 12, 8, true); + var damageBox = new CBox(EntityPosition, -7, -12, 0, 14, 12, 4, true); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite) { ShadowWidth = 12, ShadowHeight = 4 }); + } + + private void OnBurn() + { + _animator.Pause(); + _body.IgnoresZ = false; + _body.DragAir = 0.9f; + _body.Bounciness = 0.5f; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + // can only be attacked with the sword while holding it + if ((damageType & HitType.Sword) != 0 && (damageType & HitType.SwordHold) == 0 && (damageType & HitType.SwordSpin) == 0) + { + _body.Velocity.X = direction.X * 5; + _body.Velocity.Y = direction.Y * 5; + + return Values.HitCollision.None; + } + + return _damageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + } + + private void InitWaiting() + { + _body.VelocityTarget = Vector2.Zero; + + var playerDistance = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + var distance = playerDistance.Length(); + + // bomb + if (distance < 80 && Game1.RandomNumber.Next(0, 4) != 4) + { + Vector2 throwDirection; + + if (distance < 64) + { + // throw towards the player + if (playerDistance != Vector2.Zero) + playerDistance.Normalize(); + throwDirection = playerDistance * (distance / 64) * 1.0f; + } + else + { + // throw into a random direction + var randomRadius = Game1.RandomNumber.Next(0, 620) / 100; + throwDirection = new Vector2((float)Math.Sin(randomRadius), (float)Math.Cos(randomRadius)) * 0.75f; + } + + // spawn a bomb + var bomb = new ObjBomb(Map, 0, 0, false, true); + bomb.EntityPosition.Set(new Vector3(EntityPosition.X, EntityPosition.Y, 20)); + bomb.Body.Velocity = new Vector3(throwDirection, 0); + bomb.Body.CollisionTypes = Values.CollisionTypes.None; + bomb.Body.Gravity = -0.1f; + bomb.Body.DragAir = 1.0f; + bomb.Body.Bounciness = 0.5f; + Map.Objects.SpawnObject(bomb); + } + } + + private void InitMoving() + { + // the farther away the enemy is from the origin the more likely it becomes that he will move towards the start position + var directionToStart = _startPosition - EntityPosition.Position; + var radiusToStart = Math.Atan2(directionToStart.Y, directionToStart.X); + + var maxDistance = 80.0f; + var randomDir = radiusToStart + (Math.PI - Game1.RandomNumber.Next(0, 628) / 100f) * + Math.Clamp(((maxDistance - directionToStart.Length()) / maxDistance), 0, 1); + + _body.VelocityTarget = new Vector2((float)Math.Cos(randomDir), (float)Math.Sin(randomDir)) * 0.5f; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyBombite.cs b/InGame/GameObjects/Enemies/EnemyBombite.cs new file mode 100644 index 0000000..1b01f59 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyBombite.cs @@ -0,0 +1,167 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using ProjectZ.Base; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyBombite : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly AiDamageState _damageState; + private readonly AiTriggerSwitch _damageCooldown; + private readonly CBox _pongCollider; + + private const float WalkSpeed = 0.5f; + + private int _direction; + + public EnemyBombite() : base("bombite") { } + + public EnemyBombite(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/bombite"); + _animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-7, -16)); + + _body = new BodyComponent(EntityPosition, -6, -12, 12, 11, 8) + { + MoveCollision = OnCollision, + AbsorbPercentage = 0.9f, + CollisionTypes = Values.CollisionTypes.Normal, + AvoidTypes = + Values.CollisionTypes.Hole | + Values.CollisionTypes.NPCWall, + FieldRectangle = map.GetField(posX, posY), + Bounciness = 0.25f, + Drag = 0.85f, + }; + + var stateIdle = new AiState(); + stateIdle.Trigger.Add(new AiTriggerRandomTime(ChangeDirection, 250, 500)); + var statePong = new AiState(UpdatePong); + statePong.Trigger.Add(new AiTriggerCountdown(1100, null, Explode)); + statePong.Trigger.Add(new AiTriggerCountdown(750, null, StartBlinking)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("pong", statePong); + new AiFallState(_aiComponent, _body, OnHoleAbsorb, null); + _damageState = new AiDamageState(this, _body, _aiComponent, sprite, 1, false); + + _aiComponent.Trigger.Add(_damageCooldown = new AiTriggerSwitch(250)); + + _aiComponent.ChangeState("idle"); + ChangeDirection(); + + var damageBox = new CBox(EntityPosition, -6, -13, 0, 12, 12, 4); + _pongCollider = new CBox(EntityPosition, -6, -12, 0, 12, 11, 8); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 4)); + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite) { Height = 1.0f, Rotation = 0.1f }); + } + + private void UpdatePong() + { + var hitReturn = Map.Objects.Hit(this, _pongCollider.Box.Center, _pongCollider.Box, HitType.Bomb, 2, false); + if (hitReturn == Values.HitCollision.Enemy) + Explode(); + } + + private void ChangeDirection() + { + _direction = Game1.RandomNumber.Next(0, 4); + _body.VelocityTarget = AnimationHelper.DirectionOffset[_direction] * WalkSpeed; + } + + private void StartBlinking() + { + _damageState.SetDamageState(); + } + + private void Explode() + { + // spawn explosion effect + var objExplosion = new ObjBomb(Map, EntityPosition.X, EntityPosition.Y, false, false) { DamageEnemies = true }; + objExplosion.Explode(); + Map.Objects.SpawnObject(objExplosion); + + Map.Objects.DeleteObjects.Add(this); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (!_damageCooldown.State || gameObject == this) + return Values.HitCollision.None; + _damageCooldown.Reset(); + + if (damageType == HitType.Bomb && !(gameObject is EnemyBombite)) + { + // spawn a bomb + _damageState.SpawnItem = "bomb_1"; + return _damageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + } + + // hookshot/boomerang freeze + + _body.FieldRectangle = RectangleF.Empty; + + if (damageType != HitType.MagicPowder) + _body.VelocityTarget = direction * 3; + else + _body.VelocityTarget = Vector2.Zero; + + _animator.Play("damage"); + _aiComponent.ChangeState("pong"); + + return Values.HitCollision.Enemy; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X * 1.75f, direction.Y * 1.75f, _body.Velocity.Z); + + return true; + } + + private void OnCollision(Values.BodyCollision direction) + { + if (_aiComponent.CurrentStateId == "pong") + { + Game1.GameManager.PlaySoundEffect("D360-09-09"); + + if ((direction & Values.BodyCollision.Horizontal) != 0) + _body.VelocityTarget.X = -_body.VelocityTarget.X; + else if ((direction & Values.BodyCollision.Vertical) != 0) + _body.VelocityTarget.Y = -_body.VelocityTarget.Y; + } + } + + private void OnHoleAbsorb() + { + _animator.SpeedMultiplier = 3f; + _animator.Play("idle"); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyBombiteGreen.cs b/InGame/GameObjects/Enemies/EnemyBombiteGreen.cs new file mode 100644 index 0000000..7731f83 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyBombiteGreen.cs @@ -0,0 +1,209 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyBombiteGreen : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly AiDamageState _damageState; + private readonly AiTriggerSwitch _damageCooldown; + private readonly AiStunnedState _aiStunnedState; + private readonly CSprite _sprite; + + private const float WalkSpeed = 0.5f; + + private int _direction; + private bool _startedAnimation; + private bool _follow; + + public EnemyBombiteGreen() : base("bombiteGreen") { } + + public EnemyBombiteGreen(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/bombiteGreen"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-7, -16)); + + _body = new BodyComponent(EntityPosition, -6, -12, 12, 11, 8) + { + AbsorbPercentage = 0.9f, + CollisionTypes = Values.CollisionTypes.Normal, + AvoidTypes = + Values.CollisionTypes.Hole | + Values.CollisionTypes.NPCWall, + Bounciness = 0.25f, + Drag = 0.85f, + }; + + var stateIdle = new AiState(UpdateIdle) { Init = InitIdle }; + stateIdle.Trigger.Add(new AiTriggerRandomTime(ChangeDirection, 250, 500)); + var stateFollow = new AiState(UpdateFollow); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("follow", stateFollow); + new AiFallState(_aiComponent, _body, OnHoleAbsorb, null); + _damageState = new AiDamageState(this, _body, _aiComponent, _sprite, 1, false); + _aiStunnedState = new AiStunnedState(_aiComponent, animationComponent, 3300, 900) { SilentStateChange = false }; + + _aiComponent.Trigger.Add(_damageCooldown = new AiTriggerSwitch(250)); + + _aiComponent.ChangeState("idle"); + ChangeDirection(); + + var damageCollider = new CBox(EntityPosition, -6, -13, 0, 12, 12, 4); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(_sprite) { Height = 1.0f, Rotation = 0.1f }); + } + + private void InitIdle() + { + _animator.Play("idle"); + } + + private void UpdateIdle() + { + if (_follow && !_damageState.IsInDamageState()) + _aiComponent.ChangeState("follow"); + } + + private void UpdateFollow() + { + // start animation when slowed down enough + if (!_startedAnimation && _body.Velocity.Length() < 0.1f) + { + _startedAnimation = true; + _animator.Play("timer"); + } + + if (_startedAnimation) + { + if (!_animator.IsPlaying) + Explode(); + else if (_animator.CurrentFrameIndex > 2) + { + // blink + _sprite.SpriteShader = Game1.TotalGameTime % (AiDamageState.BlinkTime * 2) < AiDamageState.BlinkTime ? Resources.DamageSpriteShader0 : null; + } + + // move towards the player + var direction = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + var distance = direction.Length(); + if (direction != Vector2.Zero) + direction.Normalize(); + + if (distance > 20) + _body.VelocityTarget = direction; + else + _body.VelocityTarget = Vector2.Zero; + } + } + + private void ChangeDirection() + { + _direction = Game1.RandomNumber.Next(0, 4); + _body.VelocityTarget = AnimationHelper.DirectionOffset[_direction] * WalkSpeed; + } + + private void Explode() + { + // spawn explosion effect + var objExplosion = new ObjBomb(Map, EntityPosition.X, EntityPosition.Y, false, false); + objExplosion.Explode(); + Map.Objects.SpawnObject(objExplosion); + + Map.Objects.DeleteObjects.Add(this); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_damageState.IsInDamageState()) + return Values.HitCollision.None; + + if (damageType == HitType.Bomb && !(gameObject is EnemyBombite)) + { + // spawn a bomb + _damageState.SpawnItem = "bomb_1"; + return _damageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + } + + // stun state + if (damageType == HitType.Hookshot || damageType == HitType.Boomerang) + { + _body.VelocityTarget = Vector2.Zero; + _body.Velocity.X += direction.X * 4.0f; + _body.Velocity.Y += direction.Y * 4.0f; + + _aiStunnedState.StartStun(); + _animator.Pause(); + + return Values.HitCollision.Enemy; + } + + if (damageType != HitType.MagicPowder) + { + if (pieceOfPower) + Game1.GameManager.PlaySoundEffect("D370-17-11"); + + Game1.GameManager.PlaySoundEffect("D360-03-03"); + + if (pieceOfPower) + _damageState.HitKnockBack(gameObject, direction, damageType, pieceOfPower, false); + else + { + _body.Velocity.X += direction.X * 5.0f; + _body.Velocity.Y += direction.Y * 5.0f; + _damageState.SetDamageState(false); + } + } + else + { + _body.Velocity.X += direction.X * 1.0f; + _body.Velocity.Y += direction.Y * 1.0f; + _damageState.SetDamageState(false); + } + + if (!_aiStunnedState.IsStunned()) + _follow = true; + + return Values.HitCollision.Enemy; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X * 1.75f, direction.Y * 1.75f, _body.Velocity.Z); + + return true; + } + + private void OnHoleAbsorb() + { + _animator.SpeedMultiplier = 3f; + _animator.Play("idle"); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyBone.cs b/InGame/GameObjects/Enemies/EnemyBone.cs new file mode 100644 index 0000000..f7beafa --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyBone.cs @@ -0,0 +1,93 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyBone : GameObject + { + private readonly CSprite _sprite; + + private double _liveTime = 1250; + + public EnemyBone(Map.Map map, int posX, int posY, float speed) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(-5, -5, 10, 10); + + var animator = AnimatorSaveLoad.LoadAnimator("Enemies/bone"); + animator.Play("idle"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(animator, _sprite, new Vector2(-5, -5)); + + var body = new BodyComponent(EntityPosition, -3, -3, 6, 6, 8) + { + IgnoresZ = true, + IgnoreHoles = true, + CollisionTypes = Values.CollisionTypes.Normal, + MoveCollision = OnCollision + }; + + var velocity = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (velocity != Vector2.Zero) + velocity.Normalize(); + body.VelocityTarget = velocity * speed; + + var damageBox = new CBox(EntityPosition, -3, -3, 0, 6, 6, 4); + var hittableBox = new CBox(EntityPosition, -3, -3, 0, 6, 6, 8); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(BodyComponent.Index, body); + AddComponent(PushableComponent.Index, new PushableComponent(body.BodyBox, OnPush)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerTop)); + } + + private void OnCollision(Values.BodyCollision collision) + { + Despawn(); + } + + private void Update() + { + _liveTime -= Game1.DeltaTime; + + if (_liveTime <= 125) + _sprite.Color = Color.White * ((float)_liveTime / 125f); + + if (_liveTime < 0) + Map.Objects.DeleteObjects.Add(this); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + Despawn(); + + return Values.HitCollision.Repelling; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + Despawn(); + + return true; + } + + private void Despawn() + { + Map.Objects.DeleteObjects.Add(this); + Map.Objects.SpawnObject(new ObjAnimator(Map, (int)EntityPosition.X, (int)EntityPosition.Y, Values.LayerTop, "Particles/despawn", "run", true)); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyBonePutter.cs b/InGame/GameObjects/Enemies/EnemyBonePutter.cs new file mode 100644 index 0000000..90de971 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyBonePutter.cs @@ -0,0 +1,246 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using ProjectZ.InGame.GameObjects.Dungeon; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyBonePutter : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly AnimationComponent _animatorComponent; + private readonly AiDamageState _damageState; + + private readonly Vector2 _roomCenter; + private Vector2 _startPosition; + private Vector2 _targetPosition; + private float _flyCounter; + private float _flyTime; + private int _bombThrowCounter; + + private const float JumpSpeed = 0.25f; + + public EnemyBonePutter() : base("bone putter") { } + + public EnemyBonePutter(Map.Map map, int posX, int posY, bool hasWings) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 16); + EntitySize = new Rectangle(-8, -32, 16, 32); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/bone putter"); + + var sprite = new CSprite(EntityPosition); + _animatorComponent = new AnimationComponent(_animator, sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -4, -8, 8, 8, 8) + { + MoveCollision = OnCollision, + HoleOnPull = OnHolePull, + IgnoresZ = true, + Gravity = -0.075f, + DragAir = 0.875f, + AvoidTypes = Values.CollisionTypes.Hole | Values.CollisionTypes.NPCWall, + FieldRectangle = map.GetField(posX, posY) + }; + + var roomRectangle = map.GetField(posX, posY); + _roomCenter = new Vector2(roomRectangle.Center.X, roomRectangle.Center.Y + 8); + + _aiComponent = new AiComponent(); + + var stateFlying = new AiState(UpdateFlying) { Init = InitFlying }; + var stateJumping = new AiState(UpdateJumping) { Init = InitJumping }; + var stateHole = new AiState(); + + _aiComponent.States.Add("flying", stateFlying); + _aiComponent.States.Add("jumping", stateJumping); + _aiComponent.States.Add("holePull", stateHole); + new AiFallState(_aiComponent, _body, null, null, 200); + _damageState = new AiDamageState(this, _body, _aiComponent, sprite, hasWings ? 3 : 1, false); + _aiComponent.ChangeState(hasWings ? "flying" : "jumping"); + + var hittableBox = new CBox(EntityPosition, -6, -15, 2, 12, 14, 8, true); + var damageBox = new CBox(EntityPosition, -6, -15, 2, 12, 14, 4, true); + var pushBox = new CBox(EntityPosition, -6, -15, 2, 12, 14, 4, true); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, _animatorComponent); + AddComponent(PushableComponent.Index, new PushableComponent(pushBox, OnPush)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite)); + } + + public bool StartJump() + { + return _aiComponent.CurrentStateId == "jumping" && _body.IsGrounded && EntityPosition.Z <= 0; + } + + private void SpawnFairy() + { + // remove the enemy + Map.Objects.DeleteObjects.Add(this); + + // spawn explosion effect that ends in a fairy spawning + var animationExplosion = new ObjAnimator(Map, (int)EntityPosition.X - 8, (int)(EntityPosition.Y - EntityPosition.Z - 16), Values.LayerTop, "Particles/spawn", "run", true); + animationExplosion.Animator.OnAnimationFinished = () => + { + // remove the explosion animation + animationExplosion.Map.Objects.DeleteObjects.Add(animationExplosion); + // spawn fairy + animationExplosion.Map.Objects.SpawnObject(new ObjDungeonFairy(animationExplosion.Map, (int)EntityPosition.X, (int)(EntityPosition.Y - EntityPosition.Z - 4), 0)); + }; + + Map.Objects.SpawnObject(animationExplosion); + } + + private void InitFlying() + { + _animator.Play("fly"); + _startPosition = EntityPosition.Position; + _targetPosition = _startPosition; + _flyCounter = 0; + } + + private void UpdateFlying() + { + _flyCounter -= Game1.DeltaTime; + + if (_flyCounter > 0) + { + var lerpPercentage = 0.5f - MathF.Sin(_flyCounter / _flyTime * MathF.PI - MathF.PI / 2) * 0.5f; + var newPosition = Vector2.Lerp(_startPosition, _targetPosition, lerpPercentage); + EntityPosition.Set(newPosition); + } + else + { + ThrowBomb(); + + EntityPosition.Set(_targetPosition); + _startPosition = _targetPosition; + + // the target direction will be in the direction of the center if we are farther away from the center + var centerDirection = EntityPosition.Position - _roomCenter; + var centerDistance = centerDirection.Length(); + if (centerDirection != Vector2.Zero) + centerDirection.Normalize(); + var centerRadian = MathF.Atan2(centerDirection.Y, centerDirection.X); + + // set a new target position + var centerOffset = Math.Clamp((50 - centerDistance) / 25, 0, 1); + var randomRotation = centerRadian - (MathF.PI + Game1.RandomNumber.Next(0, 628) / 100f) * centerOffset; + var randomDistance = Game1.RandomNumber.Next(12, 20); + _targetPosition.X = _startPosition.X - MathF.Cos(randomRotation) * randomDistance; + _targetPosition.Y = _startPosition.Y - MathF.Sin(randomRotation) * randomDistance; + + _animatorComponent.MirroredH = _targetPosition.X > _startPosition.X; + _animatorComponent.UpdateSprite(); + + // random fly time + _flyTime = Game1.RandomNumber.Next(600, 800); + _flyCounter = _flyTime; + } + } + + private void ThrowBomb() + { + _bombThrowCounter--; + if (_bombThrowCounter > 0) + return; + + var playerDistance = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDistance.Length() > 64) + return; + + _bombThrowCounter = Game1.RandomNumber.Next(2, 6); + + // spawn a bomb + var bomb = new ObjBomb(Map, 0, 0, false, true); + bomb.EntityPosition.Set(new Vector3(EntityPosition.X, EntityPosition.Y + 1, 18)); + bomb.Body.Velocity = new Vector3(0, 0, 0.25f); + bomb.Body.Gravity = -0.1f; + bomb.Body.Bounciness = 0.4f; + Map.Objects.SpawnObject(bomb); + } + + private void InitJumping() + { + _animator.Play("jump"); + _body.IgnoresZ = false; + _body.IsGrounded = false; + _body.JumpStartHeight = 0; + } + + private void UpdateJumping() + { + if (_body.IsGrounded) + Jump(); + } + + private void Jump() + { + // jump into a random direction + var randomRotation = Game1.RandomNumber.Next(0, 628) / 100f; + _body.VelocityTarget.X = -MathF.Cos(randomRotation) * JumpSpeed; + _body.VelocityTarget.Y = -MathF.Sin(randomRotation) * JumpSpeed; + _body.Velocity.Z = 1.5f; + + _animatorComponent.MirroredH = _body.VelocityTarget.X > 0; + _animatorComponent.UpdateSprite(); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + if (type == HitType.Bow) + damage = 3; + + if (_aiComponent.CurrentStateId == "flying" && (type == HitType.MagicPowder || type == HitType.Boomerang)) + { + SpawnFairy(); + return Values.HitCollision.Enemy; + } + + if (_aiComponent.CurrentStateId == "flying") + _aiComponent.ChangeState("jumping"); + + return _damageState.OnHit(originObject, direction, type, damage, pieceOfPower); + } + + private void OnHolePull(Vector2 direction, float percentage) + { + if (percentage < 0.5f) + return; + + _aiComponent.ChangeState("holePull"); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X * 1.75f, direction.Y * 1.75f, _body.Velocity.Z); + + return true; + } + + private void OnCollision(Values.BodyCollision collision) + { + if ((collision & Values.BodyCollision.Horizontal) != 0) + _body.Velocity.X = -_body.Velocity.X * 0.5f; + if ((collision & Values.BodyCollision.Vertical) != 0) + _body.Velocity.Y = -_body.Velocity.Y * 0.5f; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyBooBuddy.cs b/InGame/GameObjects/Enemies/EnemyBooBuddy.cs new file mode 100644 index 0000000..97f6ac6 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyBooBuddy.cs @@ -0,0 +1,252 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyBooBuddy : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly AnimationComponent _animatorComponent; + private readonly AiDamageState _aiDamageState; + private readonly DamageFieldComponent _damageField; + private readonly DrawShadowCSpriteComponent _shadowDrawComponent; + + private RectangleF _rangeBox; + private string _ligthKey; + + private Vector2 _targetPositionOffset; + private float _speed; + private static float _positionRadiant = 0.76f; + + private float _directionChangeCounter; + private Vector2 _targetVelocity; + + private float _cooldownCounter; + private bool _cooldownPosition; + + private int _fadeTime = 250; + + public EnemyBooBuddy() : base("boo buddy") { } + + public EnemyBooBuddy(Map.Map map, int posX, int posY, string lightKey) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 24, 0); + EntitySize = new Rectangle(-8, -21, 16, 21); + + _ligthKey = lightKey; + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/boo buddy"); + _animator.Play("attack"); + + var sprite = new CSprite(EntityPosition); + _animatorComponent = new AnimationComponent(_animator, sprite, new Vector2(0, -5)); + + _rangeBox = map.GetField(posX, posY, 8); + + _body = new BodyComponent(EntityPosition, -7, -20, 14, 14, 8) + { + IgnoresZ = true, + CollisionTypes = Values.CollisionTypes.None, + }; + + // randomize the speed and the target position so that the ghosts don't align with each other + _positionRadiant += (float)Math.PI; + _targetPositionOffset = new Vector2((float)Math.Sin(_positionRadiant) * 6, (float)Math.Cos(_positionRadiant) * 6 + 4); + _speed = 0.55f + Game1.RandomNumber.Next(0, 101) / 1000f; + + _aiComponent = new AiComponent(); + + var stateAttacking = new AiState(UpdateAttacking) { Init = InitAttacking }; + var stateCooldown = new AiState(UpdateCooldown) { Init = InitCooldown }; + var stateFleeing = new AiState(UpdateFleeing) { Init = InitFleeing }; + var stateFading = new AiState(); + stateFading.Trigger.Add(new AiTriggerCountdown(_fadeTime, UpdateFading, FinishedFading)); + + _aiComponent.States.Add("attacking", stateAttacking); + _aiComponent.States.Add("cooldown", stateCooldown); + _aiComponent.States.Add("fleeing", stateFleeing); + _aiComponent.States.Add("fading", stateFading); + _aiDamageState = new AiDamageState(this, _body, _aiComponent, sprite, 4, true, false); + + var damageCollider = new CBox(EntityPosition, -7, -20, 0, 14, 14, 8); + + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageCollider, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, OnHit)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, _animatorComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, _shadowDrawComponent = new DrawShadowCSpriteComponent(sprite)); + + if (!string.IsNullOrEmpty(_ligthKey)) + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + + _aiComponent.ChangeState("attacking"); + } + + private void KeyChanged() + { + var lightOn = Game1.GameManager.SaveManager.GetString(_ligthKey) == "1"; + + if (lightOn) + _aiComponent.ChangeState("fleeing"); + else if (_aiComponent.CurrentStateId == "fleeing") + _aiComponent.ChangeState("attacking"); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (damageType == HitType.Bow) + return _aiDamageState.OnHit(gameObject, direction, damageType, 1, pieceOfPower); + + if (_aiComponent.CurrentStateId == "fleeing" || damageType == HitType.MagicRod) + return _aiDamageState.OnHit(gameObject, direction, damageType, 4, pieceOfPower); + + // was hit in the attack state -> change int cooldown mode + if (_aiComponent.CurrentStateId == "attacking") + { + _aiComponent.ChangeState("cooldown"); + return Values.HitCollision.Enemy; + } + + return Values.HitCollision.None; + } + + private void InitAttacking() + { + _animatorComponent.Sprite.Color = Color.White; + _shadowDrawComponent.IsActive = true; + + _animator.Play("attack"); + } + + private void UpdateAttacking() + { + if (_rangeBox.Contains(MapManager.ObjLink.BodyRectangle)) + { + // move towards the player + var playerDirection = MapManager.ObjLink.EntityPosition.Position + _targetPositionOffset - EntityPosition.Position; + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + + _targetVelocity = playerDirection * _speed; + } + else + { + _directionChangeCounter -= Game1.DeltaTime; + + // change direction + if (_directionChangeCounter <= 0) + { + _directionChangeCounter = Game1.RandomNumber.Next(750, 1000); + + // move towards the center of the room with a random offset + var center = _rangeBox.Center + new Vector2(8, 12); + var centerOffset = center - EntityPosition.Position; + + // depending on how far away the enemy is to the center of the room the direction can diverge more or less + var offsetLength = (int)centerOffset.Length(); + var randomOffset = Game1.RandomNumber.Next(0, Math.Max(1, 50 - offsetLength)) / 50f * 2f * Math.PI; + + var radius = Math.Atan2(centerOffset.Y, centerOffset.X) + randomOffset; + + _targetVelocity = new Vector2((float)Math.Cos(radius), (float)Math.Sin(radius)) * _speed * 0.5f; + } + } + + var percentage = (float)Math.Pow(0.9, Game1.TimeMultiplier); + _body.VelocityTarget = percentage * _body.VelocityTarget + (1 - percentage) * _targetVelocity; + _animatorComponent.MirroredH = _targetVelocity.X < 0; + } + + private void InitCooldown() + { + // disable the damage field + _damageField.IsActive = false; + + _animator.Play("hit"); + _cooldownPosition = false; + _cooldownCounter = 0; + _body.VelocityTarget = Vector2.Zero; + } + + private void UpdateCooldown() + { + _cooldownCounter += Game1.DeltaTime; + + // blink + var isTransparent = _cooldownCounter % 133 < 66; + _animatorComponent.Sprite.Color = isTransparent ? Color.Transparent : Color.White; + _shadowDrawComponent.IsActive = !isTransparent; + + // change location + if (!_cooldownPosition && _cooldownCounter > 500) + { + _cooldownPosition = true; + + // the new position is the mirror position from the center + var center = _rangeBox.Center + new Vector2(8, 8); + var centerOffset = EntityPosition.Position - center; + EntityPosition.Set(center - centerOffset); + } + + // finished cooldown + if (_cooldownCounter > 1000) + { + _aiComponent.ChangeState("attacking"); + + // reactivate the damage field + _damageField.IsActive = true; + } + } + + private void InitFleeing() + { + _animatorComponent.Sprite.Color = Color.White; + _shadowDrawComponent.IsActive = true; + + _animator.Play("flee"); + } + + private void UpdateFleeing() + { + // move away from the player + var playerDirection = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + + var percentage = (float)Math.Pow(0.9, Game1.TimeMultiplier); + _body.VelocityTarget = percentage * _body.VelocityTarget + (1 - percentage) * playerDirection * 0.25f; + _animatorComponent.MirroredH = playerDirection.X < 0; + + // remove enemy if he is too far away + var center = _rangeBox.Center + new Vector2(0, 12); + var centerOffset = EntityPosition.Position - center; + if (Math.Abs(centerOffset.X) > 80 || Math.Abs(centerOffset.Y) > 72) + _aiComponent.ChangeState("fading"); + } + + private void UpdateFading(double time) + { + // fade away + _animatorComponent.Sprite.Color = Color.White * (float)(time / _fadeTime); + } + + private void FinishedFading() + { + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyBuzzBlob.cs b/InGame/GameObjects/Enemies/EnemyBuzzBlob.cs new file mode 100644 index 0000000..8c4223e --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyBuzzBlob.cs @@ -0,0 +1,193 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using ProjectZ.InGame.GameObjects.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyBuzzBlob : GameObject + { + private readonly Animator _animator; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _damageState; + private readonly AiStunnedState _sunnedState; + + private readonly float _moveSpeed = 0.33f; + private const int ShockTime = 550; + private bool _isCukeman; + + public EnemyBuzzBlob() : base("buzz blob") { } + + public EnemyBuzzBlob(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-10, -16, 20, 20); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/buzzblob"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-6, -16)); + + var fieldRectangle = map.GetField(posX, posY); + + _body = new BodyComponent(EntityPosition, -4, -10, 8, 10, 8) + { + AvoidTypes = Values.CollisionTypes.Hole | + Values.CollisionTypes.NPCWall, + FieldRectangle = fieldRectangle + }; + + var stateWalking = new AiState() { Init = InitWalking }; + stateWalking.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("walking"), 500, 1000)); + var stateShocking = new AiState(UpdateShocking); + stateShocking.Trigger.Add(new AiTriggerCountdown(ShockTime, null, () => _aiComponent.ChangeState("postShock"))); + var statePostShock = new AiState() { Init = InitPostShock }; + statePostShock.Trigger.Add(new AiTriggerCountdown(350, null, () => _aiComponent.ChangeState("walking"))); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("walking", stateWalking); + _aiComponent.States.Add("shocking", stateShocking); + _aiComponent.States.Add("postShock", statePostShock); + _damageState = new AiDamageState(this, _body, _aiComponent, sprite, 4, false) { OnDeath = OnDeath, OnBurn = () => _animator.Pause() }; + _sunnedState = new AiStunnedState(_aiComponent, animationComponent, 3300, 900) { ShakeOffset = 1, SilentStateChange = false, ReturnState = "walking" }; + new AiFallState(_aiComponent, _body, OnHolePull, OnHoleDeath, 400); + + _aiComponent.ChangeState("walking"); + + var interactionBox = new CBox(EntityPosition, -10, -16, 20, 20, 8); + var hittableBox = new CBox(EntityPosition, -6, -14, 12, 14, 8); + var damageBox = new CBox(EntityPosition, -5, -12, 0, 10, 12, 4); + var pushableBox = new CBox(EntityPosition, -4, -11, 0, 8, 11, 4); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(InteractComponent.Index, new InteractComponent(interactionBox, OnInteract)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + } + + private void OnDeath(bool pieceOfPower) + { + Game1.GameManager.UseShockEffect = false; + + _damageState.BaseOnDeath(pieceOfPower); + } + + private void UpdateShocking() + { + MapManager.ObjLink.CanWalk = false; + } + + private void InitPostShock() + { + Game1.GameManager.UseShockEffect = false; + } + + private void InitWalking() + { + _animator.Play(_isCukeman ? "cukeman" : "walk"); + + // new random direction + var directionIndex = Game1.RandomNumber.Next(0, 8); + var radius = directionIndex / 4.0 * Math.PI; + _body.VelocityTarget = new Vector2((float)Math.Sin(radius), (float)Math.Cos(radius)) * _moveSpeed; + } + + private void OnHolePull() + { + _animator.Play("walk"); + _animator.SpeedMultiplier = 2.0f; + } + + private void OnHoleDeath() + { + Game1.GameManager.UseShockEffect = false; + } + + private bool OnInteract() + { + if (!_isCukeman) + return false; + + Game1.GameManager.StartDialogPath("cukeman"); + + return true; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X, direction.Y, _body.Velocity.Z) * 2f; + + return true; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_damageState.IsInDamageState()) + return Values.HitCollision.None; + + if ((damageType & HitType.Hookshot) != 0) + { + _animator.Pause(); + _sunnedState.StartStun(); + + _body.Velocity.X = direction.X * 5; + _body.Velocity.Y = direction.Y * 5; + _body.VelocityTarget = Vector2.Zero; + + return Values.HitCollision.Enemy; + } + else if (damageType == HitType.MagicPowder) + { + _isCukeman = true; + _animator.Play("cukeman"); + Game1.GameManager.PlaySoundEffect("D360-03-03"); + + // spawn explosion effect + ObjAnimator animator; + Map.Objects.SpawnObject(animator = new ObjAnimator(Map, 0, 0, Values.LayerBottom, "Particles/spawn", "run", true)); + animator.EntityPosition.Set(new Vector2(EntityPosition.X - 8, EntityPosition.Y - 16)); + + return Values.HitCollision.Enemy; + } + else if (!_sunnedState.IsStunned() && ((damageType & HitType.Sword) != 0 || damageType == HitType.PegasusBootsSword)) + { + StartShock(); + + return Values.HitCollision.Enemy; + } + + if ((damageType & HitType.Sword) == 0 && damageType != HitType.PegasusBootsSword && damageType != HitType.SwordShot) + damage *= 2; + + return _damageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + } + + private void StartShock() + { + if (_aiComponent.CurrentStateId == "shocking") + return; + + MapManager.ObjLink.ShockPlayer(ShockTime); + Game1.GameManager.PlaySoundEffect("D378-28-1C"); + + _body.VelocityTarget = Vector2.Zero; + _aiComponent.ChangeState("shocking"); + _animator.Play("shock"); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyCamoGoblin.cs b/InGame/GameObjects/Enemies/EnemyCamoGoblin.cs new file mode 100644 index 0000000..f7be869 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyCamoGoblin.cs @@ -0,0 +1,207 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyCamoGoblin : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly DrawShadowCSpriteComponent _shadowComponent; + private readonly BodyDrawComponent _bodyDrawComponent; + private readonly DamageFieldComponent _damageField; + private readonly AiDamageState _damageState; + private readonly Animator _animator; + private readonly AnimationComponent _animationComponent; + + private readonly float _movementSpeed; + private readonly string _strColor; + + public EnemyCamoGoblin() : base("camo goblin") { } + + // color: 0 = red, 1 = green, 2 = blue + public EnemyCamoGoblin(Map.Map map, int posX, int posY, int color) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -24, 16, 24); + + if (color == 0) + { + _strColor = "red"; + _movementSpeed = 1; + } + else if (color == 1) + { + _strColor = "green"; + _movementSpeed = 0.75f; + } + else + { + _strColor = "blue"; + _movementSpeed = 1; // TODO: look at real speed + } + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/camo goblin"); + + var sprite = new CSprite(EntityPosition); + + _animationComponent = new AnimationComponent(_animator, sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -7, -14, 14, 14, 8) + { + HoleOnPull = OnHolePull, + CollisionTypes = Values.CollisionTypes.Normal, + AvoidTypes = Values.CollisionTypes.Hole, + FieldRectangle = map.GetField(posX, posY, 16), + Bounciness = 0.25f, + Drag = 0.85f, + }; + + var stateIdle = new AiState(UpdateIdle) { Init = InitIdle }; + var stateMove = new AiState { Init = InitMove }; + stateMove.Trigger.Add(new AiTriggerRandomTime(EndMove, 500, 800)); + var stateSpawn = new AiState(UpdateSpawn) { Init = InitSpawn }; + var stateWobble = new AiState(UpdateWobble) { Init = InitWobble }; + var stateDespawn = new AiState(UpdateDespawn) { Init = InitDespawn }; + var stateHolePull = new AiState(); + stateHolePull.Trigger.Add(new AiTriggerCountdown(1000, null, () => _aiComponent.ChangeState("idle"))); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("move", stateMove); + _aiComponent.States.Add("spawn", stateSpawn); + _aiComponent.States.Add("wobble", stateWobble); + _aiComponent.States.Add("despawn", stateDespawn); + _aiComponent.States.Add("holePull", stateHolePull); + _damageState = new AiDamageState(this, _body, _aiComponent, sprite, 1) { OnBurn = () => _animator.Pause() }; + new AiFallState(_aiComponent, _body, null, null, 0); + + var damageBox = new CBox(EntityPosition, -6, -20, 0, 12, 20, 4); + var hittableBox = new CBox(EntityPosition, -6, -20, 0, 12, 20, 8); + var pushableBox = new CBox(EntityPosition, -6, -20, 0, 12, 20, 8); + + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageBox, HitType.Enemy, 2) { IsActive = false }); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, _animationComponent); + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(DrawComponent.Index, _bodyDrawComponent = new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, _shadowComponent = new DrawShadowCSpriteComponent(sprite)); + + _aiComponent.ChangeState("idle"); + } + + private void InitIdle() + { + _shadowComponent.IsActive = false; + _bodyDrawComponent.Layer = Values.LayerBottom; + _animator.Play("eyes_" + _strColor); + } + + private void UpdateIdle() + { + var distance = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (distance.Length() < 36 && _body.FieldRectangle.Contains(MapManager.ObjLink.BodyRectangle)) + _aiComponent.ChangeState("move"); + } + + private void InitMove() + { + // move towards the player + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDirection != Vector2.Zero) + { + playerDirection.Normalize(); + _body.VelocityTarget = playerDirection * _movementSpeed; + } + } + + private void EndMove() + { + _aiComponent.ChangeState("spawn"); + } + + private void InitSpawn() + { + _shadowComponent.IsActive = true; + _bodyDrawComponent.Layer = Values.LayerPlayer; + _animator.Play("spawn_" + _strColor); + _animationComponent.MirroredH = EntityPosition.X > MapManager.ObjLink.EntityPosition.X; + _body.VelocityTarget = Vector2.Zero; + } + + private void UpdateSpawn() + { + if (!_animator.IsPlaying) + { + _aiComponent.ChangeState("wobble"); + } + } + + private void InitWobble() + { + _damageField.IsActive = true; + _animator.Play("wobble_" + _strColor); + } + + private void UpdateWobble() + { + // finished wobbling? + if (!_animator.IsPlaying) + { + _damageField.IsActive = false; + _aiComponent.ChangeState("despawn"); + } + } + + private void InitDespawn() + { + _animator.Play("despawn_" + _strColor); + } + + private void UpdateDespawn() + { + if (!_animator.IsPlaying) + { + _aiComponent.ChangeState("idle"); + } + } + + private void OnHolePull(Vector2 direction, float percentage) + { + _aiComponent.ChangeState("holePull"); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + // can only be hit in the wobble state + if (_aiComponent.CurrentStateId != "spawn" && + _aiComponent.CurrentStateId != "wobble") + return Values.HitCollision.None; + + return _damageState.OnHit(originObject, direction, type, damage, pieceOfPower); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + // can only be pushed in the wobble state + if (_aiComponent.CurrentStateId != "spawn" && + _aiComponent.CurrentStateId != "wobble") + return false; + + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X, direction.Y, _body.Velocity.Z); + + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyCardBoy.cs b/InGame/GameObjects/Enemies/EnemyCardBoy.cs new file mode 100644 index 0000000..5e1d44b --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyCardBoy.cs @@ -0,0 +1,239 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyCardBoy : GameObject + { + private readonly CSprite _sprite; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly DamageFieldComponent _damgeField; + + private readonly string _key; + private readonly int _index; + + private float _changeTime = 500; + private float _changeCounter; + private float _walkSpeed = 0.5f; + private int _cardIndex; + private int _dir; + + public EnemyCardBoy() : base("card boy") { } + + public EnemyCardBoy(Map.Map map, int posX, int posY, int index, string key) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _index = index; + + if (string.IsNullOrEmpty(key)) + { + IsDead = true; + return; + } + + _key = key; + if (Game1.GameManager.SaveManager.GetString(_key) == "1") + IsDead = true; + + Game1.GameManager.SaveManager.RemoveInt(_key + _index); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/card boy"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-8, -16)); + + _body = new BodyComponent(EntityPosition, -7, -10, 14, 10, 8) + { + MoveCollision = OnCollision, + CollisionTypes = + Values.CollisionTypes.Normal | + Values.CollisionTypes.Enemy | + Values.CollisionTypes.Player | + Values.CollisionTypes.NPCWall, + FieldRectangle = map.GetField(posX, posY), + Drag = 0.75f, + }; + + var stateIdle = new AiState(Update); + stateIdle.Trigger.Add(new AiTriggerRandomTime(ToWalking, 250, 500)); + var stateWalking = new AiState(Update); + stateWalking.Trigger.Add(new AiTriggerRandomTime(ToIdle, 750, 1000)); + var stateWaiting = new AiState(); + var stateDamage = new AiState(); + stateDamage.Trigger.Add(new AiTriggerCountdown(400, DamageTick, FinishDamage)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("walking", stateWalking); + _aiComponent.States.Add("damage", stateDamage); + _aiComponent.States.Add("waiting", stateWaiting); + + _aiComponent.ChangeState("idle"); + + var damageBox = new CBox(EntityPosition, -8, -14, 0, 16, 13, 4); + var hittableBox = new CBox(EntityPosition, -8, -15, 16, 14, 8); + var pushableBox = new CBox(EntityPosition, -7, -14, 14, 13, 8); + + AddComponent(DamageFieldComponent.Index, _damgeField = new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(_sprite)); + } + + private void ToIdle() + { + _damgeField.IsActive = true; + _aiComponent.ChangeState("idle"); + _body.VelocityTarget = Vector2.Zero; + } + + private void ToWalking() + { + _aiComponent.ChangeState("walking"); + // random new direction + _dir = Game1.RandomNumber.Next(0, 4); + _body.VelocityTarget = AnimationHelper.DirectionOffset[_dir] * _walkSpeed; + } + + private void Update() + { + _changeCounter += Game1.DeltaTime; + if (_changeCounter > _changeTime * 4) + _changeCounter -= _changeTime * 4; + + _cardIndex = (int)(_changeCounter / _changeTime); + + var time = _animator.FrameCounter; + var frame = _animator.CurrentFrameIndex; + _animator.Play((_cardIndex + 1).ToString(), frame, time); + _animator.IsPlaying = _aiComponent.CurrentStateId == "walking"; + } + + private void KeyChanged() + { + // reset boy + if (_aiComponent.CurrentStateId == "waiting" && + Game1.GameManager.SaveManager.GetInt(_key + _index, -1) == -1) + _aiComponent.ChangeState("idle"); + + if (Game1.GameManager.SaveManager.GetString(_key) == "1") + RemoveEntity(); + else + CheckOther(); + } + + private void RemoveEntity() + { + Map.Objects.SpawnObject( + new ObjAnimator(Map, (int)EntityPosition.X - 16, (int)EntityPosition.Y - 24, Values.LayerTop, "Particles/explosion", "run", true)); + Map.Objects.DeleteObjects.Add(this); + } + + private void CheckOther() + { + // all boys set + var resetBoys = true; + // all boy states equal + var allEqual = true; + for (var i = 0; i < 3; i++) + { + if (Game1.GameManager.SaveManager.GetInt(_key + i, -1) == -1) + resetBoys = false; + if (Game1.GameManager.SaveManager.GetInt(_key + i, -1) != _cardIndex) + allEqual = false; + } + + if (!allEqual && resetBoys) + { + Game1.GameManager.PlaySoundEffect("D360-29-1D"); + + for (var i = 0; i < 3; i++) + Game1.GameManager.SaveManager.RemoveInt(_key + i); + } + + // all card boys have the same state + if (allEqual) + { + Game1.GameManager.SaveManager.SetString(_key, "1"); + Game1.GameManager.PlaySoundEffect("D378-19-13"); + } + } + + private void AddDamage() + { + _aiComponent.ChangeState("damage"); + _body.VelocityTarget = Vector2.Zero; + _animator.IsPlaying = false; + _damgeField.IsActive = false; + } + + private void DamageTick(double time) + { + _sprite.SpriteShader = time % 133 < 66 ? Resources.DamageSpriteShader0 : null; + } + + private void FinishDamage() + { + _sprite.SpriteShader = null; + _aiComponent.ChangeState("waiting"); + Game1.GameManager.SaveManager.SetInt(_key + _index, _cardIndex); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_aiComponent.CurrentStateId == "damage") + return Values.HitCollision.None; + + Game1.GameManager.PlaySoundEffect("D360-03-03"); + + _body.Velocity.X = direction.X * 2.5f; + _body.Velocity.Y = direction.Y * 2.5f; + + AddDamage(); + + return Values.HitCollision.Enemy; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + { + _body.Velocity = new Vector3(direction.X * 1.75f, direction.Y * 1.75f, _body.Velocity.Z); + + if (_aiComponent.CurrentStateId != "damage" && + _aiComponent.CurrentStateId != "waiting") + AddDamage(); + } + + return true; + } + + private void OnCollision(Values.BodyCollision direction) + { + if (_aiComponent.CurrentStateId != "walking") + return; + + if (direction == Values.BodyCollision.Vertical) + _body.VelocityTarget.Y = 0; + else if (direction == Values.BodyCollision.Horizontal) + _body.VelocityTarget.X = 0; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyCheepCheep.cs b/InGame/GameObjects/Enemies/EnemyCheepCheep.cs new file mode 100644 index 0000000..385f0eb --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyCheepCheep.cs @@ -0,0 +1,215 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyCheepCheep : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _damageState; + private readonly Animator _animator; + + private readonly CBox _damageBox; + private readonly CBox _headJumpBox; + + private Vector2 _jumpStart; + private const int JumpTime = 1500; + + private readonly float _movementSpeed; + private int _dir; + private readonly bool _canJump; + + public EnemyCheepCheep() : base("cheep cheep") { } + + public EnemyCheepCheep(Map.Map map, int posX, int posY, int dir, bool canJump) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _dir = dir; + _canJump = canJump; + + _movementSpeed = canJump ? 0.75f : 0.5f; + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/cheep cheep"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -16)); + + _body = new BodyComponent(EntityPosition, -8, -12, 16, 10, 8) + { + MoveCollision = OnCollision, + AvoidTypes = Values.CollisionTypes.NPCWall, + CollisionTypes = + Values.CollisionTypes.Normal, + FieldRectangle = map.GetField(posX, posY), + DragAir = 0.8f, + Gravity2DWater = 0f + }; + + var stateMoving = new AiState(); + if (_canJump) + { + stateMoving.Trigger.Add(new AiTriggerRandomTime(ToMoving, 350, 1250)); + stateMoving.Trigger.Add(new AiTriggerRandomTime(ToJump, 750, 1250)); + } + + var statePause = new AiState(); + statePause.Trigger.Add(new AiTriggerCountdown(700, null, ToMoving)); + var stateJumping = new AiState(); + stateJumping.Trigger.Add(new AiTriggerCountdown(JumpTime, UpdateJump, EndJump)); + var stateDead = new AiState(UpdateDeath); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("moving", stateMoving); + _aiComponent.States.Add("pause", statePause); + _aiComponent.States.Add("jumping", stateJumping); + _aiComponent.States.Add("dead", stateDead); + _damageState = new AiDamageState(this, _body, _aiComponent, sprite, 1) + { + HitMultiplierX = 3.0f, + HitMultiplierY = 2.0f, + FlameOffset = new Point(0, 2), + OnBurn = () => _animator.Pause() + }; + + ToMoving(); + + var hittableBox = new CBox(EntityPosition, -8, -14, 0, 16, 12, 8); + _damageBox = new CBox(EntityPosition, -6, -14, 0, 12, 12, 4); + _headJumpBox = new CBox(EntityPosition, -6, -16, 0, 12, 6, 8); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(_damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + _body.IgnoresZ = false; + + return _damageState.OnHit(originObject, direction, type, damage, pieceOfPower); + } + + public override void Init() + { + // look into the direction of the player + if (_dir % 2 != 0 && MapManager.ObjLink.NextMapPositionStart != null) + _animator.Play("idle_" + (EntityPosition.X > MapManager.ObjLink.NextMapPositionStart.Value.X ? 0 : 2)); + } + + private void ToMoving() + { + _aiComponent.ChangeState("moving"); + + _body.VelocityTarget = AnimationHelper.DirectionOffset[_dir] * _movementSpeed; + + // update the animation if the fish is going to the left or right + if (_dir % 2 == 0) + _animator.Play("idle_" + _dir); + + _dir = (_dir + 2) % 4; + } + + private void ToPausing() + { + _aiComponent.ChangeState("pause"); + _body.VelocityTarget = Vector2.Zero; + } + + private void ToJump() + { + _body.IgnoresZ = true; + _body.VelocityTarget = Vector2.Zero; + + _aiComponent.ChangeState("jumping"); + Game1.GameManager.PlaySoundEffect("D360-36-24"); + + // scale down the damage box + _damageBox.OffsetY += 8; + _damageBox.Box.Height -= 8; + + _jumpStart = EntityPosition.Position; + + // splash animation + var position = new Point((int)_jumpStart.X, (int)_jumpStart.Y); + var splashAnimator = new ObjAnimator(_body.Owner.Map, position.X, position.Y - 14, 0, 3, 1, "Particles/fishingSplash", "idle", true); + Map.Objects.SpawnObject(splashAnimator); + } + + private void UpdateJump(double time) + { + var newPosition = _jumpStart - new Vector2(0, 64) * MathF.Sin((float)(time / JumpTime) * MathF.PI); + EntityPosition.Set(newPosition); + + // player jumped on the fish? + if ((MapManager.ObjLink._body.Velocity.Y > 0 && !MapManager.ObjLink._body.IsGrounded || time > JumpTime / 2) && + _headJumpBox.Box.Bottom >= MapManager.ObjLink._body.BodyBox.Box.Bottom && + _headJumpBox.Box.Intersects(MapManager.ObjLink._body.BodyBox.Box)) + { + Game1.GameManager.PlaySoundEffect("D370-14-0E"); + + MapManager.ObjLink._body.Velocity.Y -= 1f; + _aiComponent.ChangeState("dead"); + _animator.Play("dead_" + _dir); + _body.VelocityTarget = Vector2.Zero; + _body.IgnoresZ = false; + _body.Gravity2DWater = 0.05f; + _body.CollisionTypes = Values.CollisionTypes.None; + } + } + + private void EndJump() + { + // scale up the damage box + _damageBox.OffsetY -= 8; + _damageBox.Box.Height += 8; + + _body.IgnoresZ = false; + UpdateJump(JumpTime); + ToMoving(); + } + + private void UpdateDeath() + { + if ((_body.CurrentFieldState & MapStates.FieldStates.DeepWater) != 0) + _body.CollisionTypes = Values.CollisionTypes.Normal; + } + + private void OnCollision(Values.BodyCollision direction) + { + // kill the fish when it reaches the ground + if (_aiComponent.CurrentStateId == "dead" && + (direction & Values.BodyCollision.Vertical) != 0) + { + _damageState.OnHit(MapManager.ObjLink, new Vector2(0, 1), HitType.Sword1, 1, false); + return; + } + + if ((direction & Values.BodyCollision.Vertical) != 0) + _body.Velocity.Y = 0; + + if (_aiComponent.CurrentStateId != "moving") + return; + + if (_canJump) + ToMoving(); + else + ToPausing(); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyCrab.cs b/InGame/GameObjects/Enemies/EnemyCrab.cs new file mode 100644 index 0000000..9d93352 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyCrab.cs @@ -0,0 +1,101 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyCrab : GameObject + { + private readonly Animator _animator; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + + private int _currentDirection; + + public EnemyCrab() : base("crab") { } + + public EnemyCrab(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/crab"); + _animator.Play("walk"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -16)); + + var fieldRectangle = map.GetField(posX, posY); + + _body = new BodyComponent(EntityPosition, -7, -10, 14, 10, 8) + { + MoveCollision = OnCollision, + CollisionTypes = + Values.CollisionTypes.Normal | + Values.CollisionTypes.Enemy | + Values.CollisionTypes.Player, + AvoidTypes = Values.CollisionTypes.Hole | + Values.CollisionTypes.NPCWall, + FieldRectangle = fieldRectangle, + Bounciness = 0.25f, + Drag = 0.85f + }; + + var stateWalkingV = new AiState(() => { }); + stateWalkingV.Trigger.Add(new AiTriggerRandomTime(ToWalking, 250, 750)); + var stateWalkingH = new AiState(() => { }); + stateWalkingH.Trigger.Add(new AiTriggerRandomTime(ToWalking, 1000, 1500)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("walkingV", stateWalkingV); + _aiComponent.States.Add("walkingH", stateWalkingH); + var damageState = new AiDamageState(this, _body, _aiComponent, sprite, 2) { OnBurn = () => _animator.Pause() }; + ToWalking(); + + var hittableRectangle = new CBox(EntityPosition, -8, -15, 16, 15, 8); + var damageCollider = new CBox(EntityPosition, -8, -11, 0, 16, 11, 4); + + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableRectangle, damageState.OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + } + + private void ToWalking() + { + _currentDirection = Game1.RandomNumber.Next(0, 4); + _aiComponent.ChangeState("walking" + (_currentDirection % 2 == 0 ? "H" : "V")); + + // change the direction the crab is walking + var speed = _currentDirection % 2 == 0 ? 1.0f : 0.33f; + _body.VelocityTarget = AnimationHelper.DirectionOffset[_currentDirection] * speed; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X, direction.Y, _body.Velocity.Z); + + return true; + } + + private void OnCollision(Values.BodyCollision direction) + { + // change direction after collisions + if (direction.HasFlag(Values.BodyCollision.Horizontal)) + _body.VelocityTarget.X = -_body.VelocityTarget.X * 0.5f; + else if (direction == Values.BodyCollision.Vertical) + _body.VelocityTarget.Y = -_body.VelocityTarget.Y * 0.5f; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyCrow.cs b/InGame/GameObjects/Enemies/EnemyCrow.cs new file mode 100644 index 0000000..f29cc08 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyCrow.cs @@ -0,0 +1,210 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyCrow : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly AiDamageState _damageState; + private readonly AiTriggerTimer _followTimer; + private readonly CBox _damageCollider; + private readonly CBox _hittableBoxFly; + private readonly HittableComponent _hittableComponent; + + private readonly Box _activationBox; + + private double _dirRadius; + private int _dirIndex; + private bool _goldLeaf; + + private const string _leafSaveKey = "ow_goldLeafCrow"; + + public EnemyCrow() : base("crow") { } + + public EnemyCrow(Map.Map map, int posX, int posY, bool goldLeaf) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 12, 0); + + _goldLeaf = goldLeaf; + + if (_goldLeaf) + EntitySize = new Rectangle(-8, -32, 16, 48); + else + EntitySize = new Rectangle(-8, -32, 16, 36); + + // abort spawn if the player already has the leaf + if (_goldLeaf && Game1.GameManager.SaveManager.GetString(_leafSaveKey) == "1") + { + IsDead = true; + return; + } + + _activationBox = new Box(posX - 10, posY - 32, 0, 36, 80, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/crow"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-7, -16)); + + _body = new BodyComponent(EntityPosition, -6, -14, 12, 14, 8) + { + CollisionTypes = Values.CollisionTypes.None, + IgnoreHoles = true, + IgnoresZ = true + }; + + var stateWaiting = new AiState(UpdateWaiting); + stateWaiting.Trigger.Add(new AiTriggerRandomTime(UpdateLookDirection, 250, 750)); + var stateStart = new AiState(UpdateStart) { Init = InitStart }; + var stateFlying = new AiState(UpdateFlying); + stateFlying.Trigger.Add(_followTimer = new AiTriggerTimer(1000)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("waiting", stateWaiting); + _aiComponent.States.Add("start", stateStart); + _aiComponent.States.Add("flying", stateFlying); + _damageState = new AiDamageState(this, _body, _aiComponent, sprite, 2, true, false); + + if (_goldLeaf) + _damageState.OnDeath = OnDeath; + + _damageState.IsActive = false; + + _aiComponent.ChangeState("waiting"); + + _damageCollider = new CBox(EntityPosition, -6, -14, 0, 12, 14, 4, true); + var hittableBox = new CBox(EntityPosition, -8, -32, 0, 16, _goldLeaf ? 48 : 36, 8); + _hittableBoxFly = new CBox(EntityPosition, -6, -15, 0, 12, 14, 8, true); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(_damageCollider, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, _hittableComponent = new HittableComponent(hittableBox, OnHit)); + AddComponent(PushableComponent.Index, new PushableComponent(_damageCollider, OnPush)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerTop)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite)); + } + + private void OnDeath(bool pieceofpower) + { + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + playerDirection *= 2.25f; + + // spawn the golden leaf jumping towards the player + var objLeaf = new ObjItem(Map, 0, 0, null, _leafSaveKey, "goldLeaf", null, true); + objLeaf.EntityPosition.Set(new Vector3(EntityPosition.X, EntityPosition.Y, EntityPosition.Z)); + objLeaf.SetVelocity(new Vector3(playerDirection.X, playerDirection.Y, 1.5f)); + objLeaf.Collectable = false; + Map.Objects.SpawnObject(objLeaf); + + _damageState.BaseOnDeath(pieceofpower); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (damageType == HitType.MagicPowder) + return Values.HitCollision.None; + + if (damageType == HitType.Bow || damageType == HitType.MagicRod) + damage /= 2; + + // start attacking? + if (_aiComponent.CurrentStateId == "waiting" && (damageType == HitType.Bomb || damageType == HitType.ThrownObject)) + { + _aiComponent.ChangeState("start"); + return Values.HitCollision.None; + } + + return _damageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + } + + private void UpdateLookDirection() + { + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDirection.Length() > 96) + return; + + _dirIndex = MapManager.ObjLink.PosX < EntityPosition.X - _dirIndex * 4 ? -1 : 1; + _animator.Play("idle_" + _dirIndex); + } + + private void UpdateWaiting() + { + // activate the crow + if (!_goldLeaf && MapManager.ObjLink._body.BodyBox.Box.Intersects(_activationBox)) + _aiComponent.ChangeState("start"); + } + + private void InitStart() + { + _hittableComponent.HittableBox = _hittableBoxFly; + } + + private void UpdateStart() + { + _animator.Play("fly_" + _dirIndex); + + EntityPosition.Set(new Vector3( + EntityPosition.X, + EntityPosition.Y, + EntityPosition.Z + 0.5f * Game1.TimeMultiplier)); + + if (EntityPosition.Z >= 15) + { + EntityPosition.Z = 15; + _aiComponent.ChangeState("flying"); + _damageState.IsActive = true; + _dirRadius = Math.Atan2(MapManager.ObjLink.PosY - EntityPosition.Y, MapManager.ObjLink.PosX - EntityPosition.X); + } + } + + private void UpdateFlying() + { + var direction = MapManager.ObjLink.EntityPosition.Position - new Vector2(EntityPosition.X, EntityPosition.Y - EntityPosition.Z); + var directionRadius = Math.Atan2(direction.Y, direction.X); + + if (direction.Length() < 80) + { + var followSpeed = 0.02f; + if (directionRadius < _dirRadius - followSpeed || _followTimer.State) + _dirRadius -= followSpeed * Game1.TimeMultiplier; + else if (directionRadius > _dirRadius + followSpeed) + _dirRadius += followSpeed * Game1.TimeMultiplier; + } + + var velocity = new Vector2((float)Math.Cos(_dirRadius), (float)Math.Sin(_dirRadius)); + _body.VelocityTarget = velocity * 1.25f; + + _dirIndex = velocity.X < 0 ? -1 : 1; + _animator.Play("fly_" + _dirIndex); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (_aiComponent.CurrentStateId == "waiting") + return false; + + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction * 1.75f, _body.Velocity.Z); + + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyDarknut.cs b/InGame/GameObjects/Enemies/EnemyDarknut.cs new file mode 100644 index 0000000..5cc32c6 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyDarknut.cs @@ -0,0 +1,268 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyDarknut : GameObject + { + public BodyComponent Body; + + public bool FinishedSpawning = true; + public bool SpawnGoldLeaf; + + private readonly CSprite _sprite; + private readonly EnemyDarknutSword _sword; + private readonly Animator _animator; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _damageState; + + private Rectangle _fieldRectangle; + + private const float MoveSpeed = 0.5f; + private const float AttackSpeed = 0.55f; + private const int AttackRange = 80; + + private int _direction; + + private const string _leafSaveKey = "ow_goldLeafNut"; + + private bool _isActive = true; + public override bool IsActive + { + set + { + _sword.IsActive = value; + _isActive = value; + } + get => _isActive; + } + + public EnemyDarknut() : base("darknut") { } + + public EnemyDarknut(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/darknut"); + _animator.Play("walk_1"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-8, -16)); + + _fieldRectangle = map.GetField(posX, posY); + + Body = new BodyComponent(EntityPosition, -7, -10, 14, 10, 8) + { + MoveCollision = OnCollision, + CollisionTypes = Values.CollisionTypes.Normal | + Values.CollisionTypes.Enemy, + AvoidTypes = Values.CollisionTypes.Hole | + Values.CollisionTypes.NPCWall, + FieldRectangle = _fieldRectangle, + Bounciness = 0.25f, + AbsorbPercentage = 0.9f, + Drag = 0.85f + }; + + var stateSpawned = new AiState(); + stateSpawned.Trigger.Add(new AiTriggerCountdown(550, null, EndWallSpawn)); + var stateIdle = new AiState { Init = InitIdle }; + stateIdle.Trigger.Add(new AiTriggerRandomTime(EndIdle, 300, 500)); + var stateWalk = new AiState { Init = InitWalking }; + stateWalk.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("idle"), 550, 850)); + var stateAttack = new AiState(StateAttack); + + _aiComponent = new AiComponent(); + _aiComponent.Trigger.Add(new AiTriggerUpdate(UpdateDamageTick)); + _aiComponent.States.Add("spawned", stateSpawned); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("walking", stateWalk); + _aiComponent.States.Add("attack", stateAttack); + new AiFallState(_aiComponent, Body, OnHoleAbsorb, OnAbsorbDeath); + _damageState = new AiDamageState(this, Body, _aiComponent, _sprite, 2) + { + OnDeath = OnDeath, + OnBurn = OnBurn + }; + + var damageBox = new CBox(EntityPosition, -8, -12, 0, 16, 12, 4); + var hittableBox = new CBox(EntityPosition, -4, -14, 8, 12, 8); + var pushableBox = new CBox(EntityPosition, -7, -11, 0, 14, 11, 4); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, _damageState.OnHit)); + AddComponent(BodyComponent.Index, Body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(Body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(_sprite)); + + _sword = new EnemyDarknutSword(Map, this); + } + + public override void Init() + { + // add the sword to the map + Map.Objects.SpawnObject(_sword); + + // start randomly idle or walking facing a random direction + _direction = Game1.RandomNumber.Next(0, 4); + _aiComponent.ChangeState(Game1.RandomNumber.Next(0, 2) == 0 ? "walking" : "idle"); + } + + private void OnBurn() + { + _animator.Pause(); + _sword.Animator.Pause(); + } + + private void UpdateDamageTick() + { + _sword.Sprite.SpriteShader = _sprite.SpriteShader; + } + + public void WallSpawn() + { + FinishedSpawning = false; + IsActive = true; + _sword.IsActive = true; + _damageState.IsActive = false; + _aiComponent.ChangeState("spawned"); + + // look down while spawning + _direction = 3; + _animator.Play("walk_" + _direction); + _sword.Animator.Play("walk_" + _direction); + Body.VelocityTarget = Vector2.Zero; + } + + private void EndWallSpawn() + { + FinishedSpawning = true; + _damageState.IsActive = true; + _aiComponent.ChangeState("attack"); + } + + private void InitIdle() + { + _animator.Play("stand_" + _direction); + _sword.Animator.Play("stand_" + _direction); + Body.VelocityTarget = Vector2.Zero; + } + + private void EndIdle() + { + var distance = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + + if (_fieldRectangle.Contains(MapManager.ObjLink.PosX, MapManager.ObjLink.PosY) && distance.Length() < AttackRange) + _aiComponent.ChangeState("attack"); + else + _aiComponent.ChangeState("walking"); + } + + private void InitWalking() + { + ChangeDirection(); + } + + private void StateAttack() + { + var direction = (MapManager.ObjLink.EntityPosition.Position + AnimationHelper.DirectionOffset[_direction] * 3) - EntityPosition.Position; + + if (!_fieldRectangle.Contains(MapManager.ObjLink.PosX, MapManager.ObjLink.PosY) || + direction.Length() > AttackRange) + { + _aiComponent.ChangeState("idle"); + return; + } + + if (direction != Vector2.Zero) + direction.Normalize(); + + Body.VelocityTarget = direction * AttackSpeed; + + _direction = AnimationHelper.GetDirection(direction); + _animator.Play("walk_" + _direction); + _sword.Animator.Play("walk_" + _direction); + + _animator.SpeedMultiplier = 2f; + _sword.Animator.SpeedMultiplier = 2f; + + } + + private void ChangeDirection() + { + // random new direction + _direction = Game1.RandomNumber.Next(0, 4); + _animator.Play("walk_" + _direction); + _sword.Animator.Play("walk_" + _direction); + Body.VelocityTarget = AnimationHelper.DirectionOffset[_direction] * MoveSpeed; + } + + private void OnDeath(bool pieceOfPower) + { + _damageState.BaseOnDeath(pieceOfPower); + + Map.Objects.DeleteObjects.Add(_sword); + + if (!SpawnGoldLeaf) + return; + + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + playerDirection *= 1.75f; + + // spawn the golden leaf jumping towards the player + var objLeaf = new ObjItem(Map, 0, 0, null, _leafSaveKey, "goldLeaf", null); + if (!objLeaf.IsDead) + { + objLeaf.EntityPosition.Set(new Vector3(EntityPosition.X, EntityPosition.Y, EntityPosition.Z)); + objLeaf.SetVelocity(new Vector3(playerDirection.X, playerDirection.Y, 1.0f)); + objLeaf.Collectable = false; + Map.Objects.SpawnObject(objLeaf); + } + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + Body.Velocity = new Vector3(direction, Body.Velocity.Z); + + return true; + } + + private void OnCollision(Values.BodyCollision direction) + { + if (_aiComponent.CurrentStateId != "walking") + return; + + // stop walking + _aiComponent.ChangeState("idle"); + } + + private void OnHoleAbsorb() + { + _animator.SpeedMultiplier = 3f; + _animator.Play("walk_" + _direction); + _sword.Animator.SpeedMultiplier = 3f; + _sword.Animator.Play("walk_" + _direction); + } + + private void OnAbsorbDeath() + { + Map.Objects.DeleteObjects.Add(_sword); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyDarknutSpear.cs b/InGame/GameObjects/Enemies/EnemyDarknutSpear.cs new file mode 100644 index 0000000..e33a664 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyDarknutSpear.cs @@ -0,0 +1,158 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyDarknutSpear : GameObject + { + private readonly Animator _animator; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + + private readonly Vector2[] _shotOffset = + { + new Vector2(-8, -3), new Vector2(0, -3), + new Vector2(8, -3), new Vector2(0, 2) + }; + + private float _moveSpeed = 0.5f; + private int _direction; + + public EnemyDarknutSpear() : base("darknut spear") { } + + public EnemyDarknutSpear(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/darknut spear"); + _animator.Play("walk_1"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -7, -10, 14, 10, 8) + { + MoveCollision = OnCollision, + CollisionTypes = Values.CollisionTypes.Normal | + Values.CollisionTypes.Enemy, + AvoidTypes = Values.CollisionTypes.Hole | Values.CollisionTypes.NPCWall, + FieldRectangle = map.GetField(posX, posY), + Bounciness = 0.25f, + Drag = 0.85f + }; + + var walkingState = new AiState { Init = InitWalking }; + walkingState.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("idle"), 550, 850)); + var idleState = new AiState { Init = InitIdle }; + idleState.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("walking"), 300, 500)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("walking", walkingState); + _aiComponent.States.Add("idle", idleState); + new AiFallState(_aiComponent, _body, OnHoleAbsorb); + var damageState = new AiDamageState(this, _body, _aiComponent, sprite, 2); + + // start randomly idle or walking facing a random direction + _direction = Game1.RandomNumber.Next(0, 4); + _aiComponent.ChangeState(Game1.RandomNumber.Next(0, 2) == 0 ? "walking" : "idle"); + + var damageBox = new CBox(EntityPosition, -8, -12, 0, 16, 12, 4); + var hittableBox = new CBox(EntityPosition, -7, -15, 14, 15, 8); + var pushableBox = new CBox(EntityPosition, -7, -11, 0, 14, 11, 4); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, damageState.OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + } + + private void InitIdle() + { + _animator.Play("stand_" + _direction); + _body.VelocityTarget = Vector2.Zero; + + ThrowSpear(); + } + + private void InitWalking() + { + ChangeDirection(); + } + + private void ChangeDirection() + { + // random new direction + _direction = Game1.RandomNumber.Next(0, 4); + _animator.Play("walk_" + _direction); + _body.VelocityTarget = AnimationHelper.DirectionOffset[_direction] * _moveSpeed; + } + + private void ThrowSpear() + { + if (Game1.RandomNumber.Next(0, 4) == 0) + return; + + // shoot if the player is in the range and in the right direction + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDirection.Length() < 128) + { + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + var direction = AnimationHelper.GetDirection(playerDirection); + if (direction == _direction) + { + var box = Box.Empty; + if (!Map.Objects.Collision(new Box( + EntityPosition.X + _shotOffset[_direction].X - 4, + EntityPosition.Y + _shotOffset[_direction].Y - 4, 0, 8, 8, 8), + Box.Empty, Values.CollisionTypes.Normal, 0, _body.Level, ref box)) + { + // shoot + var shot = new EnemySpear(Map, new Vector3( + EntityPosition.X + _shotOffset[_direction].X, + EntityPosition.Y + _shotOffset[_direction].Y, 3), + AnimationHelper.DirectionOffset[_direction] * 2f); + Map.Objects.SpawnObject(shot); + } + } + } + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X, direction.Y, _body.Velocity.Z); + + return true; + } + + private void OnCollision(Values.BodyCollision direction) + { + if (_aiComponent.CurrentStateId != "walking") + return; + + // stop walking + _aiComponent.ChangeState("idle"); + } + + private void OnHoleAbsorb() + { + _animator.SpeedMultiplier = 3f; + _animator.Play("walk_" + _direction); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyDarknutSword.cs b/InGame/GameObjects/Enemies/EnemyDarknutSword.cs new file mode 100644 index 0000000..a1162a9 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyDarknutSword.cs @@ -0,0 +1,87 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyDarknutSword : GameObject + { + public readonly Animator Animator; + public readonly CSprite Sprite; + + private readonly EnemyDarknut _owner; + private readonly CBox _collisionBox; + + private double _lastHitTime; + + public EnemyDarknutSword(Map.Map map, EnemyDarknut owner) : base(map) + { + _owner = owner; + _owner.EntityPosition.AddPositionListener(typeof(EnemyDarknutSword), PositionChange); + + EntityPosition = new CPosition(owner.EntityPosition.X, owner.EntityPosition.Y - 1, owner.EntityPosition.Z); + EntitySize = new Rectangle(-22, -8 - 24, 44, 48); + + Animator = AnimatorSaveLoad.LoadAnimator("Enemies/darknut sword"); + + Sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(Animator, Sprite, new Vector2(-8, -15)); + + _collisionBox = new CBox(0, 0, 0, 0, 0, 4); + UpdateCollisionBox(); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(_collisionBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(_collisionBox, OnHit)); + AddComponent(PushableComponent.Index, new PushableComponent(_collisionBox, OnPush)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(Sprite, Values.LayerPlayer)); + } + + private void PositionChange(CPosition position) + { + EntityPosition.Set(new Vector2(position.X, position.Y - position.Z - 1)); + } + + private void Update() + { + UpdateCollisionBox(); + } + + private void UpdateCollisionBox() + { + _collisionBox.Box.X = EntityPosition.X - 8 + Animator.CollisionRectangle.X; + _collisionBox.Box.Y = EntityPosition.Y - 15 + Animator.CollisionRectangle.Y; + _collisionBox.Box.Width = Animator.CollisionRectangle.Width; + _collisionBox.Box.Height = Animator.CollisionRectangle.Height; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + { + _owner.Body.Velocity.X = direction.X * 1.5f; + _owner.Body.Velocity.Y = direction.Y * 1.5f; + } + + return true; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (damageType == HitType.MagicRod || damageType == HitType.MagicPowder || damageType == HitType.Bow || damageType == HitType.Hookshot || damageType == HitType.Boomerang || + (_lastHitTime != 0 && Game1.TotalGameTime - _lastHitTime < 250)) + return Values.HitCollision.None; + + _lastHitTime = Game1.TotalGameTime; + + _owner.Body.Velocity.X = direction.X * 1.5f; + _owner.Body.Velocity.Y = direction.Y * 1.5f; + + return Values.HitCollision.RepellingParticle; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyFireball.cs b/InGame/GameObjects/Enemies/EnemyFireball.cs new file mode 100644 index 0000000..2131bfe --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyFireball.cs @@ -0,0 +1,110 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyFireball : GameObject + { + private readonly CSprite _sprite; + private readonly BodyComponent _body; + private readonly Rectangle _fieldRectangle; + private double _liveTime = 2250; + + public EnemyFireball(Map.Map map, int posX, int posY, float speed, bool hittable = true) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(-5, -5, 10, 10); + + var animator = AnimatorSaveLoad.LoadAnimator("Enemies/fireball"); + animator.Play("idle"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(animator, _sprite, new Vector2(-5, -5)); + + _body = new BodyComponent(EntityPosition, -5, -5, 10, 10, 8) + { + IgnoresZ = true, + IgnoreHoles = true, + CollisionTypes = Values.CollisionTypes.None + }; + + _fieldRectangle = Map.GetField(posX, posY); + + var playerDirection = new Vector2(MapManager.ObjLink.EntityPosition.X, MapManager.ObjLink.EntityPosition.Y - 4) - EntityPosition.Position; + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + _body.VelocityTarget = playerDirection * speed; + + var damageBox = new CBox(EntityPosition, -3, -3, 0, 6, 6, 4); + var hittableBox = new CBox(EntityPosition, -4, -4, 0, 8, 8, 8); + + AddComponent(BodyComponent.Index, _body); + if (hittable) + { + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(PushableComponent.Index, new PushableComponent(damageBox, OnPush)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + } + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerTop)); + } + + public void SetVelocity(Vector2 velocity) + { + _body.VelocityTarget = velocity; + } + + private void Update() + { + _liveTime -= Game1.DeltaTime; + + if (_liveTime <= 125) + _sprite.Color = Color.White * ((float)_liveTime / 125f); + // start despawning if we get outside of the current room + else if (!_fieldRectangle.Contains(EntityPosition.Position)) + _liveTime = 125; + + if (_liveTime < 0) + Map.Objects.DeleteObjects.Add(this); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + if ((type & HitType.Sword) == 0) + return Values.HitCollision.None; + + Game1.GameManager.PlaySoundEffect("D360-03-03"); + + OnDeath(); + + return Values.HitCollision.Enemy; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + OnDeath(); + + return true; + } + + private void OnDeath() + { + var splashAnimator = new ObjAnimator(Map, 0, 0, 0, 0, Values.LayerTop, "Particles/spawn", "run", true); + splashAnimator.EntityPosition.Set(EntityPosition.Position - new Vector2(8, 8)); + Map.Objects.SpawnObject(splashAnimator); + + // TODO: add sound effect + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyFish.cs b/InGame/GameObjects/Enemies/EnemyFish.cs new file mode 100644 index 0000000..306863a --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyFish.cs @@ -0,0 +1,156 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using ProjectZ.InGame.GameObjects.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyFish : GameObject + { + private AnimationComponent _animationComponent; + private AiComponent _aiComponent; + private AiDamageState _damageState; + private BodyComponent _body; + private Animator _animator; + private CSprite _sprite; + + private float _speed = 0.5f; + private int _direction; + + // blinking + public EnemyFish() : base("fish") { } + + public EnemyFish(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 11, 0); + EntitySize = new Rectangle(-8, -11 - 16, 16, 32); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/fish"); + _animator.Play("swim"); + + _sprite = new CSprite(EntityPosition); + _animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(0, 4)); + + _body = new BodyComponent(EntityPosition, -5, -7, 10, 8, 8) + { + MoveCollision = OnCollision, + Gravity = -0.075f, + DragAir = 1.0f, + IgnoreHeight = true, + CollisionTypes = + Values.CollisionTypes.Normal | + Values.CollisionTypes.NPCWall + }; + + // start swimming randomly left or right + _direction = Game1.RandomNumber.Next(0, 2) * 2 - 1; + _body.VelocityTarget.X = _direction * _speed; + + // states + var stateSwim = new AiState(UpdateSwim) { Init = StartSwimming }; + stateSwim.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("jump"), 1500, 3000)); + var stateJump = new AiState(UpdateJump) { Init = StartJump }; + + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("swim", stateSwim); + _aiComponent.States.Add("jump", stateJump); + _damageState = new AiDamageState(this, _body, _aiComponent, _sprite, 1) + { HitMultiplierX = 0, HitMultiplierY = 0, FlameOffset = new Point(0, 2), IsActive = false }; + + _aiComponent.ChangeState("swim"); + + var damageBox = new CBox(EntityPosition, -6, -10, 0, 12, 12, 4, true); + var hittableBox = new CBox(EntityPosition, -8, -11, 0, 16, 14, 8, true); + var pushableBox = new CBox(EntityPosition, -7, -11, 0, 14, 14, 8, true); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, _damageState.OnHit)); + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, _animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer) { DeepWaterOutline = true, WaterOutlineOffsetY = 1 }); + } + + private void StartSwimming() + { + _damageState.IsActive = false; + _animator.Play("swim"); + _body.VelocityTarget.X = _direction * _speed; + } + + private void UpdateSwim() + { + _animationComponent.MirroredH = _direction > 0; + } + + private void Splash() + { + Game1.GameManager.PlaySoundEffect("D360-14-0E", false, EntityPosition.Position); + + // spawn splash effect + var fallAnimation = new ObjAnimator(_body.Owner.Map, + (int)(_body.Position.X + _body.OffsetX + _body.Width / 2.0f), + (int)(_body.Position.Y + _body.OffsetY + 9), + Values.LayerPlayer, "Particles/fishingSplash", "idle", true); + _body.Owner.Map.Objects.SpawnObject(fallAnimation); + } + + private void StartJump() + { + _damageState.IsActive = true; + _body.VelocityTarget = Vector2.Zero; + _body.Velocity = new Vector3(_direction * 0.85f, 0, 1.5f); + _body.DragAir = 1.0f; + + Splash(); + } + + private void UpdateJump() + { + _animator.Play(_body.Velocity.Z > 0 ? "jump_up" : "jump_down"); + _sprite.SpriteEffect = _direction > 0 ? SpriteEffects.FlipHorizontally : SpriteEffects.None; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType pushType) + { + if (pushType == PushableComponent.PushType.Impact && _aiComponent.CurrentStateId == "jump") + { + _body.Velocity.X += direction.X; + _body.Velocity.Y += direction.Y; + _body.DragAir = 0.95f; + } + + return true; + } + + private void OnCollision(Values.BodyCollision direction) + { + if (_aiComponent.CurrentStateId == "damage" || _damageState.IsInDamageState()) + return; + + _body.Velocity.X = 0; + _body.Velocity.Y = 0; + + // change direction + if (_aiComponent.CurrentStateId == "swim") + { + _direction = -_direction; + _body.VelocityTarget.X = _direction * _speed; + } + else if ((direction & Values.BodyCollision.Floor) != 0) + { + Splash(); + _aiComponent.ChangeState("swim"); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyFlameFountain.cs b/InGame/GameObjects/Enemies/EnemyFlameFountain.cs new file mode 100644 index 0000000..34e62a1 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyFlameFountain.cs @@ -0,0 +1,47 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + class EnemyFlameFountain : GameObject + { + private readonly Animator _animator; + + private int _lastFrameIndex; + + public EnemyFlameFountain() : base("flame fountain") { } + + public EnemyFlameFountain(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 8, 0); + EntitySize = new Rectangle(-8, -8, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/flame fountain"); + _animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -8)); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerBottom)); + } + + private void Update() + { + // spawn a fireball + if (_animator.CurrentFrameIndex == 1 && _lastFrameIndex == 0) + { + Map.Objects.SpawnObject( + new EnemyFlameFountainFireball(Map, new Vector2(EntityPosition.X, EntityPosition.Y + 8), new Vector2(0, 1))); + } + + _lastFrameIndex = _animator.CurrentFrameIndex; + + } + } +} diff --git a/InGame/GameObjects/Enemies/EnemyFlameFountainFireball.cs b/InGame/GameObjects/Enemies/EnemyFlameFountainFireball.cs new file mode 100644 index 0000000..c44548a --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyFlameFountainFireball.cs @@ -0,0 +1,123 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.GameObjects.Base.Components.AI; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyFlameFountainFireball : GameObject + { + private readonly DamageFieldComponent _damageComponent; + private readonly CSprite _sprite; + + private const int LiveTime = 800; + private double _liveCounter = LiveTime; + + public EnemyFlameFountainFireball(Map.Map map, Vector2 position, Vector2 velocity) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(position.X, position.Y, 0); + EntitySize = new Rectangle(-8, -8, 16, 18); + + var animator = AnimatorSaveLoad.LoadAnimator("Enemies/flame fountain fireball"); + animator.Play("idle"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(animator, _sprite, Vector2.Zero); + + var body = new BodyComponent(EntityPosition, -4, -6, 8, 8, 8) + { + IgnoresZ = true, + IgnoreHoles = true, + CollisionTypes = Values.CollisionTypes.None + }; + + body.VelocityTarget = velocity; + + var damageBox = new CBox(EntityPosition, -3, -3, 0, 6, 6, 16); + var pushBox = new CBox(EntityPosition, -3, -3, 0, 6, 12, 8); + + AddComponent(DamageFieldComponent.Index, _damageComponent = new DamageFieldComponent(damageBox, HitType.Enemy, 10) { OnDamage = HitPlayer }); + AddComponent(BodyComponent.Index, body); + AddComponent(PushableComponent.Index, new PushableComponent(pushBox, OnPush)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerPlayer)); + AddComponent(LightDrawComponent.Index, new LightDrawComponent(DrawLight)); + + Game1.GameManager.PlaySoundEffect("D378-18-12", true, position); + } + + private bool HitPlayer() + { + // cooldown is lower so that the player will not get through the flamse + return MapManager.ObjLink.HitPlayer(new Vector2(0, 2), HitType.Enemy, _damageComponent.Strength, true, ObjLink.CooldownTime / 2); + } + + private void Update() + { + // blink + _sprite.SpriteShader = (Game1.TotalGameTime % (AiDamageState.BlinkTime * 2) < AiDamageState.BlinkTime) ? Resources.DamageSpriteShader0 : null; + + _liveCounter -= Game1.DeltaTime; + + // fade out + if (_liveCounter <= 75) + { + if (_sprite.Color == Color.White) + { + ((PushableComponent)Components[PushableComponent.Index]).IsActive = false; + ((DamageFieldComponent)Components[DamageFieldComponent.Index]).IsActive = false; + } + + _sprite.Color = Color.White * ((float)_liveCounter / 75); + } + + if (_liveCounter < 0) + Map.Objects.DeleteObjects.Add(this); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + // check if the player has the better shield and is facing up + if (Game1.GameManager.ShieldLevel == 2 && MapManager.ObjLink.Direction == 1 && type == PushableComponent.PushType.Impact) + { + var distanceMultiplier = (float)(_liveCounter / LiveTime); + // push the player back + MapManager.ObjLink._body.Velocity += new Vector3(0, 1, 0) * (0.4f + distanceMultiplier * 0.15f); + + SpawnFlames(); + return false; + } + + return true; + } + + private void SpawnFlames() + { + ((PushableComponent)Components[PushableComponent.Index]).IsActive = false; + + if (_liveCounter > 75) + _liveCounter = 75; + _damageComponent.IsActive = false; + + var flameLeft = new EnemyFlameFountainFireballRepelled(Map, new Vector2(EntityPosition.X - 3, EntityPosition.Y - 7), new Vector2(-1, 1) * 0.75f); + Map.Objects.SpawnObject(flameLeft); + + var flameRight = new EnemyFlameFountainFireballRepelled(Map, new Vector2(EntityPosition.X + 3, EntityPosition.Y - 7), new Vector2(1, 1) * 0.75f); + Map.Objects.SpawnObject(flameRight); + } + + private void DrawLight(SpriteBatch spriteBatch) + { + DrawHelper.DrawLight(spriteBatch, new Rectangle((int)EntityPosition.X - 16, (int)EntityPosition.Y - 16, 32, 32), + new Color(255, 200, 200) * 0.35f * (_sprite.Color.A / 255f)); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyFlameFountainFireballRepelled.cs b/InGame/GameObjects/Enemies/EnemyFlameFountainFireballRepelled.cs new file mode 100644 index 0000000..02d94b9 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyFlameFountainFireballRepelled.cs @@ -0,0 +1,65 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using ProjectZ.InGame.GameObjects.Base.Components.AI; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyFlameFountainFireballRepelled : GameObject + { + private readonly CSprite _sprite; + private double _liveTime = 650; + + public EnemyFlameFountainFireballRepelled(Map.Map map, Vector2 position, Vector2 velocity) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(position.X, position.Y, 0); + EntitySize = new Rectangle(-8, 0, 16, 16); + + var animator = AnimatorSaveLoad.LoadAnimator("Enemies/flame fountain fireball"); + animator.Play(velocity.X < 0 ? "left" : "right"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(animator, _sprite, new Vector2(0, 8)); + + var body = new BodyComponent(EntityPosition, -5, 3, 10, 10, 8) + { + IgnoresZ = true, + IgnoreHoles = true, + CollisionTypes = Values.CollisionTypes.None, + VelocityTarget = velocity + }; + + AddComponent(BodyComponent.Index, body); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerPlayer)); + AddComponent(LightDrawComponent.Index, new LightDrawComponent(DrawLight)); + } + + private void Update() + { + // blink + _sprite.SpriteShader = (Game1.TotalGameTime % (AiDamageState.BlinkTime * 2) < AiDamageState.BlinkTime) ? Resources.DamageSpriteShader0 : null; + + _liveTime -= Game1.DeltaTime; + + if (_liveTime <= 75) + _sprite.Color = Color.White * ((float)_liveTime / 75); + + if (_liveTime < 0) + Map.Objects.DeleteObjects.Add(this); + } + + private void DrawLight(SpriteBatch spriteBatch) + { + DrawHelper.DrawLight(spriteBatch, new Rectangle((int)EntityPosition.X - 16, (int)EntityPosition.Y - 8, 32, 32), + new Color(255, 200, 200) * 0.35f * (_sprite.Color.A / 255f)); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyFloorLayer.cs b/InGame/GameObjects/Enemies/EnemyFloorLayer.cs new file mode 100644 index 0000000..7a7a14c --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyFloorLayer.cs @@ -0,0 +1,235 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using ProjectZ.InGame.Controls; +using System.Collections.Generic; +using ProjectZ.InGame.GameObjects.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + // not sure why I called it an enemy... + internal class EnemyFloorLayer : GameObject + { + private readonly List _deactivatedGameObjects = new List(); + private readonly List _spawnedTiles = new List(); + + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + + private Vector2 _spawnPosition; + private Vector2 _startPosition; + private Vector2 _endPosition; + private Vector2 _moveDirection; + + private float _soundCounter; + private float _moveCounter; + private int _moveIndex; + + private string _fullKey; + private int _minMoveCount; + + private const float MoveSpeed = 0.5f; + + public EnemyFloorLayer() : base("floor layer") { } + + public EnemyFloorLayer(Map.Map map, int posX, int posY, int count, string fullKey) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 14, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _minMoveCount = count; + _fullKey = fullKey; + + _spawnPosition = EntityPosition.Position; + + _body = new BodyComponent(EntityPosition, -8, -14, 16, 14, 8) + { + IgnoreHoles = true, + CollisionTypes = + Values.CollisionTypes.Normal | + Values.CollisionTypes.Player, + FieldRectangle = map.GetField(posX, posY) + }; + + var sprite = new CSprite(EntityPosition); + var animator = AnimatorSaveLoad.LoadAnimator("Enemies/floor layer"); + animator.Play("idle"); + + var animatorComponent = new AnimationComponent(animator, sprite, new Vector2(0, 2)); + + _aiComponent = new AiComponent(); + + var stateIdle = new AiState() { Init = InitIdle }; + var stateMove = new AiState(UpdateMoving); + var stateDead = new AiState(UpdateDead) { Init = InitDead }; + + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("move", stateMove); + _aiComponent.States.Add("dead", stateDead); + + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animatorComponent); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(CollisionComponent.Index, new BodyCollisionComponent(_body, Values.CollisionTypes.Enemy)); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush) { InertiaTime = 250 }); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite) { Height = 1.0f, Rotation = 0.1f }); + + _aiComponent.ChangeState("idle"); + } + + private void InitIdle() + { + SetActive(true); + } + + private void InitDead() + { + SetActive(false); + } + + private void SetActive(bool active) + { + ((BodyCollisionComponent)Components[CollisionComponent.Index]).IsActive = active; + ((DrawComponent)Components[DrawComponent.Index]).IsActive = active; + ((DrawShadowComponent)Components[DrawShadowComponent.Index]).IsActive = active; + } + + private void UpdateDead() + { + // remove the floor when the player leaves the room and not all tiles where layed + if (!_body.FieldRectangle.Contains(MapManager.ObjLink.EntityPosition.Position) && _moveIndex != _minMoveCount + 1) + Reactivate(); + } + + private void Reactivate() + { + _moveIndex = 0; + EntityPosition.Set(_spawnPosition); + _aiComponent.ChangeState("idle"); + + ((PushableComponent)Components[PushableComponent.Index]).IsActive = true; + + // despawn the tiles + foreach (var tile in _spawnedTiles) + { + // reactivate holes + tile.SetHoleState(true); + Map.Objects.DeleteObjects.Add(tile); + + // spawn the explosion effect + var splashAnimator = new ObjAnimator(Map, (int)tile.EntityPosition.X, + (int)tile.EntityPosition.Y, 0, 0, Values.LayerTop, "Particles/spawn", "run", true); + Map.Objects.SpawnObject(splashAnimator); + } + _spawnedTiles.Clear(); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type != PushableComponent.PushType.Continues) + return false; + + StartMoving(direction); + + return false; + } + + private void StartMoving(Vector2 direction) + { + _aiComponent.ChangeState("move"); + + ((PushableComponent)Components[PushableComponent.Index]).IsActive = false; + + _moveDirection = direction; + _startPosition = EntityPosition.Position; + _endPosition = EntityPosition.Position; + + SetNewPosition(false); + } + + private void UpdateMoving() + { + MapManager.ObjLink.FreezePlayer(); + + _soundCounter -= Game1.DeltaTime; + if (_soundCounter < 0) + { + _soundCounter += 55; + Game1.GameManager.PlaySoundEffect("D360-62-3E", false); + } + + // get the new direction the player is pushing + var vecDirection = ControlHandler.GetMoveVector2(); + if (vecDirection != Vector2.Zero) + { + var newDirection = AnimationHelper.GetDirection(vecDirection); + _moveDirection = AnimationHelper.DirectionOffset[newDirection]; + } + + _moveCounter += Game1.DeltaTime; + // finished moving to the next segment? + var time = 16 / (60 * MoveSpeed) * 1000; + if (_moveCounter > time) + { + _moveCounter -= time; + + SetNewPosition(true); + } + + // calculate the new position + var percentage = _moveCounter / time; + var newPercentage = Vector2.Lerp(_startPosition, _endPosition, percentage); + EntityPosition.Set(newPercentage); + } + + private void SetNewPosition(bool spawnFloor) + { + _moveIndex++; + _startPosition = _endPosition; + _endPosition = _startPosition + _moveDirection * 16; + + // spawn the floor + if (spawnFloor) + { + var objFloor = new EnemyFloorLayerFloor(Map, (int)_startPosition.X - 8, (int)_startPosition.Y - 14); + Map.Objects.SpawnObject(objFloor); + _spawnedTiles.Add(objFloor); + } + + // stop moving if there is no hole at next position + if (!CheckForHole((int)_endPosition.X - 8, (int)_endPosition.Y - 14)) + { + Game1.GameManager.PlaySoundEffect("D360-47-2F"); + + // spawn the explosion effect + var splashAnimator = new ObjAnimator(Map, (int)EntityPosition.X - 8, + (int)EntityPosition.Y - 14, 0, 0, Values.LayerTop, "Particles/spawn", "run", true); + Map.Objects.SpawnObject(splashAnimator); + + if (_moveIndex > _minMoveCount && !string.IsNullOrEmpty(_fullKey)) + Game1.GameManager.SaveManager.SetString(_fullKey, "1"); + + _aiComponent.ChangeState("dead"); + } + } + + private bool CheckForHole(int posX, int posY) + { + _deactivatedGameObjects.Clear(); + Map.Objects.GetObjectsOfType(_deactivatedGameObjects, typeof(ObjHole), posX, posY, 16, 16); + Map.Objects.GetObjectsOfType(_deactivatedGameObjects, typeof(ObjLava), posX, posY, 16, 16); + foreach (var gameObject in _deactivatedGameObjects) + if (gameObject.IsActive && + gameObject.EntityPosition.Position == new Vector2(posX, posY)) + return true; + + return false; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyFloorLayerFloor.cs b/InGame/GameObjects/Enemies/EnemyFloorLayerFloor.cs new file mode 100644 index 0000000..2418588 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyFloorLayerFloor.cs @@ -0,0 +1,41 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Things; +using ProjectZ.InGame.GameObjects.Things; +using System.Collections.Generic; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyFloorLayerFloor : GameObject + { + private readonly List _underlyingObjects = new List(); + + public EnemyFloorLayerFloor(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + // remove the underlying objects + Map.Objects.GetObjectsOfType(_underlyingObjects, typeof(ObjHole), posX, posY, 16, 16); + Map.Objects.GetObjectsOfType(_underlyingObjects, typeof(ObjLava), posX, posY, 16, 16); + SetHoleState(false); + + AddComponent(DrawComponent.Index, new DrawSpriteComponent("d8 floor", EntityPosition, Vector2.Zero, Values.LayerBottom)); + } + + public void SetHoleState(bool active) + { + foreach (var gameObject in _underlyingObjects) + { + if (gameObject is ObjHole && gameObject.EntityPosition.Position == EntityPosition.Position) + gameObject.IsActive = active; + if (gameObject is ObjLava objLava && gameObject.EntityPosition.Position == EntityPosition.Position) + objLava.SetActive(active); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyFlyingTile.cs b/InGame/GameObjects/Enemies/EnemyFlyingTile.cs new file mode 100644 index 0000000..bfce925 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyFlyingTile.cs @@ -0,0 +1,295 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyFlyingTile : GameObject + { + private readonly Animator _animator; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly DrawCSpriteComponent _drawComponent; + private readonly BodyDrawShadowComponent _shadowComponent; + private readonly DamageFieldComponent _damageField; + private readonly AiDamageState _damageState; + + private ObjHole _objHole; + + private RectangleF _triggerField; + private const float FlySpeed = 1.5f; + + private readonly string _strFly = "fly"; + // we use the key and the index to indicate when the tile should start moving + private readonly string _strKey; + private readonly int _index; + + private float _soundCounter; + + // initial time for the activation + private float _activationCounter = 1500; + + private bool _stringSet; + private bool _wasActivated; + + public EnemyFlyingTile() : base("flying tile") { } + + public EnemyFlyingTile(Map.Map map, int posX, int posY, string strKey, int index, int mode) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 8, 0); + EntitySize = new Rectangle(-8, -24, 16, 32); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/flyingTile"); + _animator.Play("idle_" + mode); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(0, 0)); + + _body = new BodyComponent(EntityPosition, -5, -5, 10, 5, 8) + { + Gravity = -0.15f, + IgnoresZ = true, + CollisionTypes = Values.CollisionTypes.Normal, + MoveCollision = OnCollision + }; + + // the player needs to be inside the room + // mode == 1 is for the tiles used for the facade boss; in this mode the tiles should always attack + _triggerField = map.GetField(posX, posY, mode == 0 ? 16 : 0); + + // mode == 2 is just the gray version for dungeon 7 + if (mode == 2) + _strFly = "fly_1"; + + _strKey = strKey; + _index = index; + + var stateIdle = new AiState(UpdateIdle); + var stateAscent = new AiState(UpdateAscent) { Init = InitAscent }; + var stateWait = new AiState(); + stateWait.Trigger.Add(new AiTriggerCountdown(700, null, () => _aiComponent.ChangeState("flying"))); + var stateFlying = new AiState(UpdateFlying) { Init = InitFlying }; + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("ascent", stateAscent); + _aiComponent.States.Add("wait", stateWait); + _aiComponent.States.Add("flying", stateFlying); + _damageState = new AiDamageState(this, _body, _aiComponent, sprite, 1) { OnBurn = OnBurn, FlameOffset = new Point(0, 7), ExplosionOffsetY = 7 }; + _aiComponent.ChangeState("idle"); + + var damageCollider = new CBox(EntityPosition, -3, -3, 0, 6, 6, 4, true); + var hittableBox = new CBox(EntityPosition, -5, -5, 0, 10, 10, 8, true); + + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageCollider, HitType.Enemy, 2) { OnDamagedPlayer = OnDamagePlayer, IsActive = false }); + AddComponent(BodyComponent.Index, _body); + AddComponent(PushableComponent.Index, new PushableComponent(hittableBox, OnPush)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, _drawComponent = new DrawCSpriteComponent(sprite, Values.LayerBottom)); + AddComponent(DrawShadowComponent.Index, _shadowComponent = new BodyDrawShadowComponent(_body, sprite) { IsActive = false, OffsetY = 5 }); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + + if (!string.IsNullOrEmpty(_strKey)) + { + if (_index != 0) + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + else + Game1.GameManager.SaveManager.SetString(_strKey, "0"); + } + } + + public override void Init() + { + // get the hole that is under the tile + var holeList = new List(); + Map.Objects.GetGameObjectsWithTag(holeList, Values.GameObjectTag.Hole, + (int)EntityPosition.X - 8, (int)EntityPosition.Y - 8, 16, 16); + + if (holeList.Count > 0) + { + // there should only be one hole normally + _objHole = (ObjHole)holeList[0]; + // disable the hole under the tile + _objHole.SetActive(false); + } + } + + private void OnBurn() + { + SetSaveString(); + + _animator.Pause(); + _body.IgnoresZ = false; + } + + private void OnDamagePlayer() + { + OnDeath(new Vector3(0, 0, 0.25f)); + } + + private void OnKeyChange() + { + var stateValue = Game1.GameManager.SaveManager.GetString(_strKey, "-"); + if (stateValue == _index.ToString()) + _wasActivated = true; + + // stop the tile from activating the next tile + if (stateValue == "-1") + _wasActivated = false; + } + + private void SetSaveString() + { + if (_stringSet || !_wasActivated) + return; + + // set the string to activate the next flying tile + _stringSet = true; + if (!string.IsNullOrEmpty(_strKey)) + Game1.GameManager.SaveManager.SetString(_strKey, (_index + 1).ToString()); + } + + private void UpdateIdle() + { + // check if the player is inside the room + if ((_index == 0 || _wasActivated) && _triggerField.Contains(MapManager.ObjLink.BodyRectangle)) + { + _activationCounter -= Game1.DeltaTime; + + if (_activationCounter < 0 || _wasActivated) + { + _wasActivated = true; + _aiComponent.ChangeState("ascent"); + } + } + } + + private void InitAscent() + { + _drawComponent.Layer = Values.LayerPlayer; + _shadowComponent.IsActive = true; + _damageField.IsActive = true; + _animator.Play(_strFly); + + // if there is a hole under the tile enable it + _objHole?.SetActive(true); + } + + private void UpdateAscent() + { + PlaySound(); + + EntityPosition.Z += 0.25f * Game1.TimeMultiplier; + + if (EntityPosition.Z > 12) + { + EntityPosition.Z = 12; + SetSaveString(); + _aiComponent.ChangeState("wait"); + } + } + + private void InitFlying() + { + // start flying towards the player + var velocity = MapManager.ObjLink.EntityPosition.Position - new Vector2(EntityPosition.X, EntityPosition.Y - 4); + if (velocity != Vector2.Zero) + velocity.Normalize(); + + _body.VelocityTarget = velocity * FlySpeed; + } + + private void UpdateFlying() + { + PlaySound(); + } + + private void PlaySound() + { + _soundCounter -= Game1.DeltaTime; + + if (_soundCounter < 0) + { + _soundCounter += 225; + // @TODO: faster loop + Game1.GameManager.PlaySoundEffect("D360-63-3F"); + } + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + if (_aiComponent.CurrentStateId == "idle") + return Values.HitCollision.None; + + // burn + if (type == HitType.MagicRod || type == HitType.MagicPowder) + return _damageState.OnHit(originObject, direction, type, damage, pieceOfPower); + + OnDeath(new Vector3(direction * 1.0f, 0.1f)); + + return Values.HitCollision.Enemy; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (_aiComponent.CurrentStateId == "idle") + return false; + if (_aiComponent.CurrentStateId != "flying") + return true; + + if (type == PushableComponent.PushType.Impact) + OnDeath(new Vector3(direction * 0.35f, 0.1f)); + + return true; + } + + private void OnCollision(Values.BodyCollision collision) + { + if (_aiComponent.CurrentStateId != "flying") + return; + + OnDeath(new Vector3(0, 0, 0.25f)); + } + + private void OnDeath(Vector3 bodyVelocity) + { + SetSaveString(); + + Game1.GameManager.PlaySoundEffect("D378-09-09"); + + // spawn stone particles + var rndMin = 50; + var rndMax = 75; + var diff = 200f; + + var vector0 = new Vector3(-1, -1, 0) * Game1.RandomNumber.Next(rndMin, rndMax) / diff + bodyVelocity; + var vector1 = new Vector3(-1, 0, 0) * Game1.RandomNumber.Next(rndMin, rndMax) / diff + bodyVelocity; + var vector2 = new Vector3(1, -1, 0) * Game1.RandomNumber.Next(rndMin, rndMax) / diff + bodyVelocity; + var vector3 = new Vector3(1, 0, 0) * Game1.RandomNumber.Next(rndMin, rndMax) / diff + bodyVelocity; + + var stone0 = new ObjSmallStone(Map, (int)EntityPosition.X - 2, (int)EntityPosition.Y - 7, (int)EntityPosition.Z, vector0, true); + var stone1 = new ObjSmallStone(Map, (int)EntityPosition.X - 2, (int)EntityPosition.Y - 2, (int)EntityPosition.Z, vector1, true); + var stone2 = new ObjSmallStone(Map, (int)EntityPosition.X + 3, (int)EntityPosition.Y - 7, (int)EntityPosition.Z, vector2, false); + var stone3 = new ObjSmallStone(Map, (int)EntityPosition.X + 3, (int)EntityPosition.Y - 2, (int)EntityPosition.Z, vector3, false); + + Map.Objects.SpawnObject(stone0); + Map.Objects.SpawnObject(stone1); + Map.Objects.SpawnObject(stone2); + Map.Objects.SpawnObject(stone3); + + // remove the object + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyGel.cs b/InGame/GameObjects/Enemies/EnemyGel.cs new file mode 100644 index 0000000..65c42eb --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyGel.cs @@ -0,0 +1,213 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyGel : GameObject + { + private readonly Animator _animator; + private readonly AiComponent _ai; + private readonly BodyComponent _body; + private readonly AnimationComponent _animatorComponent; + private readonly BodyDrawComponent _bodyDrawComponent; + private readonly CSprite _sprite; + private readonly AiTriggerSwitch _grabCooldown; + + private int _grabX; + private int _grabY; + private int _dir; + private int _timerOffset; + + public EnemyGel() : base("gel") { } + + public EnemyGel(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-4, -12, 7, 17); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/gel"); + _animator.Play("0"); + + _sprite = new CSprite(EntityPosition); + _animatorComponent = new AnimationComponent(_animator, _sprite, new Vector2(-4, -7)); + + _timerOffset = Game1.RandomNumber.Next(0, 1000); + + var fieldRectangle = map.GetField(posX, posY); + + _body = new BodyComponent(EntityPosition, -4, -7, 7, 7, 8) + { + Gravity = -0.2f, + AvoidTypes = Values.CollisionTypes.Hole | + Values.CollisionTypes.NPCWall, + FieldRectangle = fieldRectangle + }; + + _grabX = Game1.RandomNumber.Next(90, 110); + _grabY = Game1.RandomNumber.Next(25, 40); + + _ai = new AiComponent(); + + var stateIdle = new AiState(UpdateIdle); + stateIdle.Trigger.Add(new AiTriggerCountdown(200, null, EndIdle)); + var stateWalking = new AiState(UpdateWalking); + stateWalking.Trigger.Add(new AiTriggerRandomTime(EndWalking, 100, 150)); + var stateShaking = new AiState(UpdateShaking); + stateShaking.Trigger.Add(new AiTriggerCountdown(1000, null, EndShaking)); + var stateJumping = new AiState(UpdateJumping); + var stateGrabbing = new AiState(UpdateGrabbing); + stateGrabbing.Trigger.Add(new AiTriggerRandomTime(EndGrabbing, 1500, 2500)); + + var stateGrabbingRelease = new AiState(UpdateJumping); + + _ai.States.Add("idle", stateIdle); + _ai.States.Add("walking", stateWalking); + _ai.States.Add("shaking", stateShaking); + _ai.States.Add("jumping", stateJumping); + _ai.States.Add("grabbing", stateGrabbing); + _ai.States.Add("grabbingRelease", stateGrabbingRelease); + new AiFallState(_ai, _body, null, null, 100); + new AiDeepWaterState(_body); + var damageState = new AiDamageState(this, _body, _ai, _sprite, 1); + + _ai.Trigger.Add(_grabCooldown = new AiTriggerSwitch(2000)); + + _ai.ChangeState("idle"); + + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, damageState.OnHit)); + AddComponent(ObjectCollisionComponent.Index, new ObjectCollisionComponent(new CRectangle(EntityPosition, new Rectangle(-4, -7, 7, 12)), OnPlayerCollision)); + AddComponent(AiComponent.Index, _ai); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, _animatorComponent); + AddComponent(DrawComponent.Index, _bodyDrawComponent = new BodyDrawComponent(_body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _sprite)); + } + + public void InitSpawn() + { + _body.Velocity.Z = 2; + } + + private void UpdateIdle() + { + _body.VelocityTarget = Vector2.Zero; + _animator.Play(_dir.ToString()); + } + + private void EndIdle() + { + // only start walking if the player is in the range of the enemy + var playerDistance = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDistance.Length() > 50) + { + _ai.ChangeState("idle"); + return; + } + + _ai.ChangeState("walking"); + } + + private void UpdateWalking() + { + var vecDirection = new Vector2( + MapManager.ObjLink.PosX - EntityPosition.X, + MapManager.ObjLink.PosY - EntityPosition.Y); + if (vecDirection != Vector2.Zero) + vecDirection.Normalize(); + _dir = vecDirection.X < 0 ? -1 : 1; + + _animator.Play((-_dir).ToString()); + + _body.VelocityTarget = vecDirection * 0.5f; + } + + private void EndWalking() + { + // start shaking + if (Game1.RandomNumber.Next(0, 10) == 0) + _ai.ChangeState("shaking"); + else + _ai.ChangeState("idle"); + } + + private void UpdateShaking() + { + _body.VelocityTarget = Vector2.Zero; + _animatorComponent.SpriteOffset.X = -4 + (float)Math.Sin((Game1.TotalGameTime + _timerOffset) / 25f); + _animatorComponent.UpdateSprite(); + } + + private void EndShaking() + { + // start jumping + _ai.ChangeState("jumping"); + + _animatorComponent.SpriteOffset.X = -4; + + var vecDirection = new Vector2( + MapManager.ObjLink.PosX - EntityPosition.X, + MapManager.ObjLink.PosY - EntityPosition.Y); + if (vecDirection != Vector2.Zero) + vecDirection.Normalize(); + + _body.VelocityTarget = vecDirection * 1.25f; + _body.Velocity.Z = 1.25f; + } + + private void UpdateJumping() + { + if (_body.IsGrounded) + { + _body.VelocityTarget = Vector2.Zero; + _ai.ChangeState("idle"); + } + } + + private void UpdateGrabbing() + { + EntityPosition.Set(MapManager.ObjLink.EntityPosition); + MapManager.ObjLink.SlowDown(0.5f); + MapManager.ObjLink.DisableItems = true; + + _bodyDrawComponent.Layer = Values.LayerTop; + _animator.Play(_dir.ToString()); + + _animatorComponent.SpriteOffset.X = -4 + (float)Math.Sin((Game1.TotalGameTime + _timerOffset) / _grabX) * 3.5f; + _animatorComponent.SpriteOffset.Y = -7 - 2 + (float)Math.Sin((Game1.TotalGameTime + _timerOffset) / _grabY) * 1.5f; + _animatorComponent.UpdateSprite(); + } + + private void EndGrabbing() + { + var angle = Game1.RandomNumber.Next(-100, 100) / 200f * (float)Math.PI; + var vecDirection = new Vector2((float)Math.Sin(angle), -(float)Math.Cos(angle)); + _body.VelocityTarget = vecDirection; + _body.Velocity.Z = 1.5f; + + _animatorComponent.SpriteOffset.X = -4; + _animatorComponent.SpriteOffset.Y = -7; + + _bodyDrawComponent.Layer = Values.LayerPlayer; + _ai.ChangeState("grabbingRelease"); + _grabCooldown.Reset(); + } + + private void OnPlayerCollision(GameObject gameObject) + { + if (_grabCooldown.State && + _ai.CurrentStateId != "grabbing" && + _ai.CurrentStateId != "grabbingRelease" && + _ai.CurrentStateId != "burning") + _ai.ChangeState("grabbing"); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyGhini.cs b/InGame/GameObjects/Enemies/EnemyGhini.cs new file mode 100644 index 0000000..d71dad4 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyGhini.cs @@ -0,0 +1,191 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using ProjectZ.InGame.GameObjects.Dungeon; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyGhini : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly AiDamageState _damageState; + private readonly DamageFieldComponent _damageField; + private readonly CSprite _sprite; + + private readonly Rectangle _triggerField; + private readonly Vector2 _centerPosition; + + private Vector2 _velocity; + + private double _direction; + + private float _flyHeight = 14; + private float _rotationDirection; + private float _dirChangeCount; + private float _transparency; + + private bool _mainGhini; + + public EnemyGhini() : base("ghini") { } + + public EnemyGhini(Map.Map map, int posX, int posY, bool mainGhini, bool spawnAnimation) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, spawnAnimation ? 0 : _flyHeight); + EntitySize = new Rectangle(-8, -32, 16, 32); + + _mainGhini = mainGhini; + + _triggerField = map.GetField(posX, posY); + _centerPosition = new Vector2(_triggerField.Center.X, _triggerField.Center.Y + 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/ghini"); + _animator.Play("fly_1"); + + _sprite = new CSprite(EntityPosition) { Color = spawnAnimation ? Color.Transparent : Color.White }; + var animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -6, -12, 12, 12, 8) + { + CollisionTypes = Values.CollisionTypes.None, + IgnoreHoles = true, + IgnoresZ = true, + }; + + var stateInit = new AiState(); + stateInit.Trigger.Add(new AiTriggerCountdown(64, null, () => _aiComponent.ChangeState("spawning"))); + var stateSpawning = new AiState(UpdateSpawning); + var stateFlying = new AiState(UpdateFlying); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("init", stateInit); + _aiComponent.States.Add("spawning", stateSpawning); + _aiComponent.States.Add("flying", stateFlying); + _damageState = new AiDamageState(this, _body, _aiComponent, _sprite, 8, true, false) { IsActive = !spawnAnimation }; + _damageState.OnDeath = OnDeath; + + _aiComponent.ChangeState(spawnAnimation ? "init" : "flying"); + + var damageCollider = new CBox(EntityPosition, -6, -14, 0, 12, 14, 8, true); + + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageCollider, HitType.Enemy, 4) { IsActive = !spawnAnimation }); + AddComponent(HittableComponent.Index, new HittableComponent(damageCollider, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new ShadowBodyDrawComponent(EntityPosition)); + } + + private void UpdateSpawning() + { + _transparency = AnimationHelper.MoveToTarget(_transparency, 1, Game1.TimeMultiplier * 0.15f); + _sprite.Color = Color.White * _transparency; + + EntityPosition.Z += Game1.TimeMultiplier * 0.25f; + + if (EntityPosition.Z >= _flyHeight) + { + EntityPosition.Z = _flyHeight; + _aiComponent.ChangeState("flying"); + _damageState.IsActive = true; + _damageField.IsActive = true; + } + } + + private void UpdateFlying() + { + _dirChangeCount -= Game1.DeltaTime; + + // change the direction + if (_dirChangeCount <= 0) + { + // the farther away the enemy is from the origin the more likely it becomes that he will move towards the center position + var directionToStart = _centerPosition - EntityPosition.Position; + var radiusToCenter = Math.Atan2(directionToStart.Y, directionToStart.X); + + var maxDistanceX = 85.0f; + var maxDistanceY = 55.0f; + var distanceMultiplier = Math.Clamp( + Math.Min( + (maxDistanceX - Math.Abs(directionToStart.X)) / maxDistanceX, + (maxDistanceY - Math.Abs(directionToStart.Y)) / maxDistanceY), 0, 1); + + _direction = radiusToCenter + (Math.PI - Game1.RandomNumber.Next(0, 628) / 100f) * distanceMultiplier; + + // new direction + new rotation speed + _dirChangeCount = Game1.RandomNumber.Next(750, 1500) * (distanceMultiplier * 0.5f + 0.5f); + _rotationDirection = Game1.RandomNumber.Next(-100, 100) / 1000f * distanceMultiplier; + } + + _velocity *= (float)Math.Pow(0.95f, Game1.TimeMultiplier); + + _velocity += new Vector2((float)Math.Cos(_direction), (float)Math.Sin(_direction)) * 0.035f * Game1.TimeMultiplier; + _direction += _rotationDirection * Game1.TimeMultiplier; + + // clamp the speed + if (_velocity.Length() > 1.75f) + { + _velocity.Normalize(); + _velocity *= 1.75f; + } + + _body.VelocityTarget = _velocity; + + _animator.Play("fly_" + (_body.VelocityTarget.X < 0 ? -1 : 1)); + } + + private void OnDeath(bool pieceOfPower) + { + if (_mainGhini) + KillOtherGhinies(); + + if (Game1.RandomNumber.Next(0, 100) < 75) + { + _damageState.SpawnItems = false; + // spawns a fairy + Map.Objects.SpawnObject(new ObjDungeonFairy(Map, (int)EntityPosition.X, (int)EntityPosition.Y, (int)EntityPosition.Z)); + } + + _damageState.BaseOnDeath(pieceOfPower); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + if (type == HitType.MagicPowder) + return Values.HitCollision.None; + + if (type == HitType.Bomb || type == HitType.Bow || type == HitType.MagicRod) + damage *= 2; + + return _damageState.OnHit(originObject, direction, type, damage, pieceOfPower); + } + + private void KillOtherGhinies() + { + var enemyList = new List(); + + Map.Objects.GetGameObjectsWithTag(enemyList, Values.GameObjectTag.Enemy, + _triggerField.X, _triggerField.Y, _triggerField.Width, _triggerField.Height); + + foreach (var enemy in enemyList) + { + if (enemy != this && enemy.IsActive && (enemy.GetType() == typeof(EnemyGhini) || + enemy.GetType() == typeof(EnemyGhiniGiant))) + { + var aiComponent = (AiComponent)enemy.Components[AiComponent.Index]; + aiComponent?.ChangeState("damageDeath"); + } + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyGhiniGiant.cs b/InGame/GameObjects/Enemies/EnemyGhiniGiant.cs new file mode 100644 index 0000000..80eebff --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyGhiniGiant.cs @@ -0,0 +1,164 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using ProjectZ.InGame.GameObjects.Dungeon; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyGhiniGiant : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly AiDamageState _damageState; + private readonly DamageFieldComponent _damageField; + private readonly CSprite _sprite; + + private Rectangle _fieldRectangle; + private Vector2 _velocity; + private Vector2 _vecDirection; + + private double _direction; + + private float _rotationDirection; + private float _dirChangeCount; + private float _transparency; + + private int _flyHeight = 7; + + public EnemyGhiniGiant() : base("giant ghini") { } + + public EnemyGhiniGiant(Map.Map map, int posX, int posY, bool spawnAnimation) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16 + 7, spawnAnimation ? 0 : _flyHeight); + EntitySize = new Rectangle(-16, -(30 + _flyHeight), 32, 30 + _flyHeight); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/ghiniGiant"); + _animator.Play("fly_1"); + + _sprite = new CSprite(EntityPosition) { Color = spawnAnimation ? Color.Transparent : Color.White }; + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-16, -30)); + + _fieldRectangle = map.GetField(posX, posY, 16); + + _body = new BodyComponent(EntityPosition, -12, -30, 24, 30, 8) + { + CollisionTypes = Values.CollisionTypes.None, + IgnoreHoles = true, + IgnoresZ = true, + }; + + var stateSpawning = new AiState(UpdateSpawning); + var stateFlying = new AiState(UpdateFlying); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("spawning", stateSpawning); + _aiComponent.States.Add("flying", stateFlying); + + _aiComponent.ChangeState(spawnAnimation ? "spawning" : "flying"); + + var damageBox = new CBox(EntityPosition, -12, -28, 0, 24, 26, 8, true); + var hittableBox = new CBox(EntityPosition, -13, -29, 0, 26, 28, 8, true); + _damageState = new AiDamageState(this, _body, _aiComponent, _sprite, 8, true, false) { OnDeath = OnDeath, IsActive = !spawnAnimation }; + + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageBox, HitType.Enemy, 4) { IsActive = !spawnAnimation }); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new ShadowBodyDrawComponent(EntityPosition) { ShadowWidth = 24, ShadowHeight = 6 }); + } + + private void UpdateSpawning() + { + _transparency = AnimationHelper.MoveToTarget(_transparency, 1, Game1.TimeMultiplier * 0.15f); + _sprite.Color = Color.White * _transparency; + + EntityPosition.Z += Game1.TimeMultiplier * 0.25f; + + if (EntityPosition.Z >= _flyHeight) + { + EntityPosition.Z = _flyHeight; + _aiComponent.ChangeState("flying"); + _damageState.IsActive = true; + _damageField.IsActive = true; + } + } + + private void UpdateFlying() + { + _dirChangeCount -= Game1.DeltaTime; + + // change the direction + if (_dirChangeCount <= 0) + { + var newDirection = Game1.RandomNumber.Next(0, 628) / 100f; + _vecDirection = new Vector2((float)Math.Cos(newDirection), (float)Math.Sin(newDirection)); + _direction = newDirection; + + // new direction + new rotation speed + _dirChangeCount = Game1.RandomNumber.Next(600, 1200); + _rotationDirection = Game1.RandomNumber.Next(-100, 100) / 1000f; + } + + _velocity *= (float)Math.Pow(0.95f, Game1.TimeMultiplier); + + _velocity += new Vector2((float)Math.Cos(_direction), (float)Math.Sin(_direction)) * 0.025f * Game1.TimeMultiplier; + _direction += _rotationDirection * Game1.TimeMultiplier; + + _velocity += _vecDirection * 0.025f * Game1.TimeMultiplier; + + if ((EntityPosition.X < _fieldRectangle.X && _vecDirection.X < 0) || + (EntityPosition.X > _fieldRectangle.X + _fieldRectangle.Width && _vecDirection.X > 0)) + { + _vecDirection.X = -Math.Sign(_vecDirection.X); + _vecDirection.Y = 0; + _dirChangeCount += 500; + _direction = 1; + } + + if ((EntityPosition.Y < _fieldRectangle.Y && _vecDirection.Y < 0) || + (EntityPosition.Y > _fieldRectangle.Y + _fieldRectangle.Height && _vecDirection.Y > 0)) + { + _vecDirection.X = 0; + _vecDirection.Y = -Math.Sign(_vecDirection.Y); + _dirChangeCount += 500; + } + + _body.VelocityTarget = _velocity; + + _animator.Play("fly_" + (_body.VelocityTarget.X < 0 ? -1 : 1)); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + if (type == HitType.MagicPowder) + return Values.HitCollision.None; + + if (type == HitType.Bomb || type == HitType.Bow || type == HitType.MagicRod) + damage *= 2; + + return _damageState.OnHit(originObject, direction, type, damage, pieceOfPower); + } + + private void OnDeath(bool pieceOfPower) + { + if (Game1.RandomNumber.Next(0, 100) < 75) + { + _damageState.SpawnItems = false; + // spawns a fairy + Map.Objects.SpawnObject(new ObjDungeonFairy(Map, (int)EntityPosition.X, (int)EntityPosition.Y, (int)EntityPosition.Z)); + } + + _damageState.BaseOnDeath(pieceOfPower); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyGiantBubble.cs b/InGame/GameObjects/Enemies/EnemyGiantBubble.cs new file mode 100644 index 0000000..91dc246 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyGiantBubble.cs @@ -0,0 +1,80 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyGiantBubble : GameObject + { + private readonly CSprite _sprite; + private readonly BodyComponent _body; + private readonly Animator _animator; + private readonly Color _lightColor = new Color(255, 255, 255) * 0.5f; + + public EnemyGiantBubble() : base("giant bubble") { } + + public EnemyGiantBubble(Map.Map map, int posX, int posY) : base(map) + { + // maybe create a new tag for enemies that should be ignored by the enemy trigger + Tags = Values.GameObjectTag.Damage; + + EntityPosition = new CPosition(posX + 16, posY + 16, 0); + EntitySize = new Rectangle(-32, -32, 64, 64); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/giant bubble"); + _animator.Play("idle"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -10, -10, 20, 20, 8) + { + MoveCollision = OnCollision, + IgnoresZ = true, + CollisionTypes = + Values.CollisionTypes.Normal | + Values.CollisionTypes.NPCWall + }; + + // start with a random direction + _body.VelocityTarget = new Vector2( + Game1.RandomNumber.Next(0, 2) * 2 - 1, Game1.RandomNumber.Next(0, 2) * 2 - 1) * 0.7f; + + var damageCollider = new CBox(EntityPosition, -12, -12, 0, 24, 24, 8); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 2)); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer) { WaterOutline = false }); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(_sprite)); + AddComponent(LightDrawComponent.Index, new LightDrawComponent(DrawLight)); + } + + private void OnCollision(Values.BodyCollision collider) + { + if ((collider & Values.BodyCollision.Horizontal) != 0) + _body.VelocityTarget.X = -_body.VelocityTarget.X; + if ((collider & Values.BodyCollision.Vertical) != 0) + _body.VelocityTarget.Y = -_body.VelocityTarget.Y; + } + + private void Update() + { + // blink + var animationFramePercentage = _animator.FrameCounter / _animator.CurrentFrame.FrameTime; + var state = animationFramePercentage % 0.5 < 0.25; + _sprite.SpriteShader = state ? Resources.DamageSpriteShader0 : null; + } + + private void DrawLight(SpriteBatch spriteBatch) + { + if (_sprite.SpriteShader != null) + DrawHelper.DrawLight(spriteBatch, new Rectangle((int)EntityPosition.X - 32, (int)EntityPosition.Y - 32, 64, 64), _lightColor); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyGibdo.cs b/InGame/GameObjects/Enemies/EnemyGibdo.cs new file mode 100644 index 0000000..e92c7e8 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyGibdo.cs @@ -0,0 +1,154 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyGibdo : GameObject + { + private readonly Animator _animator; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _damageState; + private readonly AiStunnedState _aiStunnedState; + + private const float MoveSpeed = 0.5f; + + private int _direction; + + public EnemyGibdo() : base("gibdo") { } + + public EnemyGibdo(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/gibdo"); + _animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -16)); + + _body = new BodyComponent(EntityPosition, -6, -10, 12, 10, 8) + { + MoveCollision = OnCollision, + CollisionTypes = Values.CollisionTypes.Normal | + Values.CollisionTypes.Enemy, + AvoidTypes = Values.CollisionTypes.Hole | Values.CollisionTypes.NPCWall, + FieldRectangle = map.GetField(posX, posY), + Bounciness = 0.25f, + Drag = 0.85f + }; + + var stateWalking = new AiState { Init = InitWalking }; + stateWalking.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("walk"), 550, 850)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("walk", stateWalking); + _damageState = new AiDamageState(this, _body, _aiComponent, sprite, 6, false) + { + HitMultiplierX = 1.0f, + HitMultiplierY = 1.0f, + OnDeath = OnDeath, + OnBurn = () => _animator.Pause() + }; + _aiStunnedState = new AiStunnedState(_aiComponent, animationComponent, 3300, 900); + new AiFallState(_aiComponent, _body, OnHoleAbsorb); + + _aiComponent.ChangeState("walk"); + + var damageBox = new CBox(EntityPosition, -7, -14, 0, 14, 14, 4); + var pushableBox = new CBox(EntityPosition, -6, -13, 0, 12, 13, 4); + var hittableBox = new CBox(EntityPosition, -7, -15, 14, 15, 8); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 4)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (damageType == HitType.Bomb) + damage = 3; + if (damageType == HitType.Boomerang) + damage = 2; + if (damageType == HitType.Bow) + damage = 1; + + if (damageType == HitType.Hookshot) + { + _body.VelocityTarget = Vector2.Zero; + _body.Velocity.X += direction.X * 0.75f; + _body.Velocity.Y += direction.Y * 0.75f; + + _aiStunnedState.StartStun(); + _animator.Pause(); + + return Values.HitCollision.Enemy; + } + + return _damageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + } + + private void OnDeath(bool pieceOfPower) + { + if (Map == null) + return; + + if (_aiComponent.CurrentStateId == "burning") + { + Map.Objects.DeleteObjects.Add(this); + // spawn the stalfos orange + Map.Objects.SpawnObject(new EnemyStalfosOrange(Map, (int)EntityPosition.X - 8, (int)EntityPosition.Y - 16, true)); + } + else + { + _damageState.BaseOnDeath(pieceOfPower); + } + } + + private void InitWalking() + { + _animator.Play("idle"); + + // walk into a random direction + _direction = Game1.RandomNumber.Next(0, 4); + _body.VelocityTarget = AnimationHelper.DirectionOffset[_direction] * MoveSpeed; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + { + _body.Velocity.X = direction.X * 0.75f; + _body.Velocity.Y = direction.Y * 0.75f; + } + + return true; + } + + private void OnCollision(Values.BodyCollision direction) + { + if ((direction & Values.BodyCollision.Horizontal) != 0) + _body.VelocityTarget.X = -_body.VelocityTarget.X; + if ((direction & Values.BodyCollision.Vertical) != 0) + _body.VelocityTarget.Y = -_body.VelocityTarget.Y; + } + + private void OnHoleAbsorb() + { + _animator.SpeedMultiplier = 3f; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyGoomba.cs b/InGame/GameObjects/Enemies/EnemyGoomba.cs new file mode 100644 index 0000000..f770b2f --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyGoomba.cs @@ -0,0 +1,204 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using ProjectZ.InGame.GameObjects.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyGoomba : GameObject + { + private readonly CSprite _sprite; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly BoxCollisionComponent _bodyCollision; + private readonly DamageFieldComponent _damageField; + private readonly AiDamageState _damageState; + + private int FadeTime = 75; + private float _directionCounter; + private const float WalkSpeed = 0.5f; + + public EnemyGoomba() : base("goomba") { } + + public EnemyGoomba(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/goomba"); + _animator.Play("walk"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-8, Map.Is2dMap ? -14 : -16)); + + _body = new BodyComponent(EntityPosition, -6, -11, 12, 11, 8) + { + MoveCollision = OnCollision, + CollisionTypes = + Values.CollisionTypes.Normal | + Values.CollisionTypes.Enemy | + Values.CollisionTypes.NPCWall, + AvoidTypes = Values.CollisionTypes.Hole, + FieldRectangle = map.GetField(posX, posY), + Drag = 0.85f, + DragAir = 0.85f, + Gravity2D = 0.15f, + }; + + // random dir -1 or 1 + var dir = Game1.RandomNumber.Next(0, 2) * 2 - 1; + _body.VelocityTarget.X = dir * WalkSpeed; + + var stateWalking = new AiState(UpdateWalking) { Init = InitWalking }; + var stateDead = new AiState(); + stateDead.Trigger.Add(new AiTriggerCountdown(1000 - FadeTime, null, () => _aiComponent.ChangeState("fade"))); + var stateFade = new AiState() { Init = InitFade }; + stateFade.Trigger.Add(new AiTriggerCountdown(FadeTime, DespawnTick, RemoveEntity)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("walking", stateWalking); + _aiComponent.States.Add("dead", stateDead); + _aiComponent.States.Add("fade", stateFade); + new AiFallState(_aiComponent, _body, OnHoleAbsorb); + _damageState = new AiDamageState(this, _body, _aiComponent, _sprite, 1) { OnBurn = () => _animator.Pause() }; + + _aiComponent.ChangeState("walking"); + + CBox damageCollider; + if (Map.Is2dMap) + damageCollider = new CBox(EntityPosition, -_body.Width / 2 - 1, -8, 0, _body.Width + 2, 8, 4); + else + damageCollider = new CBox(EntityPosition, -_body.Width / 2 - 1, -_body.Height, 0, _body.Width + 2, _body.Height, 4); + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageCollider, HitType.Enemy, 2)); + + if (Map.Is2dMap) + _damageState.HitMultiplierY = 1.0f; + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, OnHit)); + + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + if (Map.Is2dMap) + { + var collisionBox = new CBox(EntityPosition, -6, -8, 0, 12, 8, 4); + AddComponent(CollisionComponent.Index, _bodyCollision = new BoxCollisionComponent(collisionBox, Values.CollisionTypes.Enemy)); + } + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer)); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (damageType == HitType.MagicPowder || damageType == HitType.MagicRod) + _body.VelocityTarget = Vector2.Zero; + + return _damageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + } + + private void InitWalking() + { + int randomDirection; + if (Map.Is2dMap) + randomDirection = Game1.RandomNumber.Next(0, 2) * 2; + else + randomDirection = Game1.RandomNumber.Next(0, 4); + + _body.VelocityTarget = AnimationHelper.DirectionOffset[randomDirection] * WalkSpeed; + + _directionCounter = Game1.RandomNumber.Next(750, 1500); + } + + private void UpdateWalking() + { + // player jumped on top? + if ((!Map.Is2dMap && MapManager.ObjLink._body.Velocity.Z < 0 || + Map.Is2dMap && MapManager.ObjLink._body.Velocity.Y > 0 && MapManager.ObjLink.EntityPosition.Y + 4 < EntityPosition.Y) && + _body.BodyBox.Box.Intersects(MapManager.ObjLink._body.BodyBox.Box)) + { + JumpDeath(); + } + + if (Map.Is2dMap) + return; + + _directionCounter -= Game1.DeltaTime; + // change the direction + if (_directionCounter < 0) + _aiComponent.ChangeState("walking"); + } + + private void InitFade() + { + var animation = new ObjAnimator(Map, + (int)EntityPosition.X, (int)EntityPosition.Y - 4, 0, 0, Values.LayerTop, "Particles/despawnParticle", "orange", true); + Map.Objects.SpawnObject(animation); + + // spawn a heart + Map.Objects.SpawnObject(new ObjItem(Map, + (int)EntityPosition.X - 8, (int)EntityPosition.Y - 12, "j", null, "heart", null, true)); + } + + private void DespawnTick(double time) + { + if (time <= FadeTime) + _sprite.Color = Color.White * (float)(time / FadeTime); + } + + private void RemoveEntity() + { + Map.Objects.DeleteObjects.Add(this); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X * 1.75f, direction.Y * 1.75f, _body.Velocity.Z); + + return true; + } + + private void JumpDeath() + { + // player jumped on the goomba + Game1.GameManager.PlaySoundEffect("D370-14-0E"); + + if (Map.Is2dMap) + MapManager.ObjLink._body.Velocity.Y = -1.0f; + else + MapManager.ObjLink._body.Velocity.Z = 1.0f; + + _animator.Play("dead"); + _aiComponent.ChangeState("dead"); + _body.VelocityTarget = Vector2.Zero; + _damageField.IsActive = false; + if (_bodyCollision != null) + _bodyCollision.IsActive = false; + } + + private void OnHoleAbsorb() + { + _animator.SpeedMultiplier = 3f; + } + + private void OnCollision(Values.BodyCollision direction) + { + if (_aiComponent.CurrentStateId != "walking") + return; + + if (Map.Is2dMap && (direction & Values.BodyCollision.Horizontal) != 0) + _body.VelocityTarget.X = -_body.VelocityTarget.X; + + // stop walking into the wall + if (!Map.Is2dMap && (direction & (Values.BodyCollision.Horizontal | Values.BodyCollision.Vertical)) != 0) + _aiComponent.ChangeState("walking"); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyGopongaFlower.cs b/InGame/GameObjects/Enemies/EnemyGopongaFlower.cs new file mode 100644 index 0000000..ddddb63 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyGopongaFlower.cs @@ -0,0 +1,84 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyGopongaFlower : GameObject + { + private readonly AiDamageState _aiDamageState; + private readonly Animator _animator; + + private readonly int _animationLength; + + public EnemyGopongaFlower() : base("goponga flower") { } + + public EnemyGopongaFlower(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 8, 0); + EntitySize = new Rectangle(-8, -8, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/goponga flower"); + _animator.Play("idle"); + + foreach (var frame in _animator.CurrentAnimation.Frames) + _animationLength += frame.FrameTime; + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -8)); + + var body = new BodyComponent(EntityPosition, -8, -8, 16, 16, 8) { IgnoresZ = true }; + var collisionBox = new CBox(EntityPosition, -7, -7, 14, 14, 8); + + var hittableBox = new CBox(EntityPosition, -8, -8, 16, 16, 8); + + var aiComponent = new AiComponent(); + aiComponent.States.Add("idle", new AiState()); + _aiDamageState = new AiDamageState(this, body, aiComponent, sprite, 4) + { + HitMultiplierX = 0, + HitMultiplierY = 0 + }; + aiComponent.ChangeState("idle"); + + AddComponent(AiComponent.Index, aiComponent); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(hittableBox, HitType.Enemy, 4)); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(collisionBox, Values.CollisionTypes.Enemy)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BodyComponent.Index, body); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(body, sprite, Values.LayerPlayer) { WaterOutline = false }); + } + + private void Update() + { + // @HACK: this is used to sync all the animations with the same length + // otherwise they would not be in sync if they did not get updated at the same time + _animator.SetFrame(0); + _animator.SetTime(Game1.TotalGameTime % _animationLength); + _animator.Update(); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + // only bowwow can attack + if (type != HitType.BowWow && type != HitType.Hookshot && type != HitType.MagicRod && type != HitType.Boomerang) + return Values.HitCollision.Blocking; + + if (type != HitType.BowWow && (type == HitType.MagicRod || damage >= _aiDamageState.CurrentLives)) + { + _aiDamageState.HitMultiplierX = 4; + _aiDamageState.HitMultiplierY = 4; + } + + return _aiDamageState.OnHit(originObject, direction, type, damage, pieceOfPower); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyGopongaFlowerGiant.cs b/InGame/GameObjects/Enemies/EnemyGopongaFlowerGiant.cs new file mode 100644 index 0000000..6b9941d --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyGopongaFlowerGiant.cs @@ -0,0 +1,94 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyGopongaFlowerGiant : GameObject + { + private readonly Animator _animator; + private readonly AiDamageState _aiDamageState; + + public EnemyGopongaFlowerGiant() : base("giant goponga flower") { } + + public EnemyGopongaFlowerGiant(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 16, posY + 16, 0); + EntitySize = new Rectangle(-16, -16, 32, 32); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/goponga flower giant"); + _animator.OnAnimationFinished = AnimationFinished; + _animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-16, -16)); + + var body = new BodyComponent(EntityPosition, -14, -12, 28, 28, 8) { IgnoresZ = true }; + + var collisionBox = new CBox(EntityPosition, -15, -13, 30, 28, 8); + var hittableBox = new CBox(EntityPosition, -15, -13, 30, 28, 8); + var damageBox = new CBox(EntityPosition, -16, -14, 32, 30, 8); + + var aiComponent = new AiComponent(); + aiComponent.States.Add("idle", new AiState(() => { })); + _aiDamageState = new AiDamageState(this, body, aiComponent, sprite, 4) + { + HitMultiplierX = 0, + HitMultiplierY = 0, + FlameOffset = new Point(0, -8) + }; + aiComponent.ChangeState("idle"); + + AddComponent(AiComponent.Index, aiComponent); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(collisionBox, Values.CollisionTypes.Enemy)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 4)); + AddComponent(BodyComponent.Index, body); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(body, sprite, Values.LayerPlayer) { WaterOutline = false }); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + // only bowwow can attack + if (type != HitType.BowWow && type != HitType.Hookshot && type != HitType.MagicRod && type != HitType.Boomerang) + return Values.HitCollision.Blocking; + + if (type != HitType.BowWow && (type == HitType.MagicRod || damage >= _aiDamageState.CurrentLives)) + { + _aiDamageState.HitMultiplierX = 4; + _aiDamageState.HitMultiplierY = 4; + } + + return _aiDamageState.OnHit(originObject, direction, type, damage, pieceOfPower); + } + + private void AnimationFinished() + { + // start attacking the player? + if (_animator.CurrentAnimation.Id == "idle") + { + var playerDistance = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDistance.Length() < 128) + { + _animator.Play("pre_attack"); + + // shoot fireball + Map.Objects.SpawnObject(new EnemyFireball(Map, (int)EntityPosition.X, (int)EntityPosition.Y, 0.8f)); + + return; + } + + // continue with the idle animation and don't start an attack + _animator.Play("idle"); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyGreenZol.cs b/InGame/GameObjects/Enemies/EnemyGreenZol.cs new file mode 100644 index 0000000..ea1202a --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyGreenZol.cs @@ -0,0 +1,276 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + class EnemyGreenZol : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly CSprite _sprite; + private readonly Animator _animator; + private readonly AiDamageState _damageState; + private readonly DamageFieldComponent _damageField; + private readonly AnimationComponent _animationComponent; + + private readonly bool _fallMode; + + private int _jumpsLeft; + private bool _pushable = false; + + public EnemyGreenZol() : base("green zol") { } + + public EnemyGreenZol(Map.Map map, int posX, int posY, int posZ, bool fallMode) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 13, posZ); + EntitySize = new Rectangle(-8, -24, 16, 24); + + _fallMode = fallMode; + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/green zol"); + _animator.Play("walk_1"); + + _sprite = new CSprite(EntityPosition); + _animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-6, -16)); + + _body = new BodyComponent(EntityPosition, -6, -10, 12, 10, 8) + { + AbsorbPercentage = 1, + AvoidTypes = Values.CollisionTypes.NPCWall | + Values.CollisionTypes.DeepWater, + Gravity = -0.15f, + Bounciness = 0f, + Drag = 0.85f + }; + + var stateInit = new AiState(); + // small delay before possibility of spawning; needed for situation where the enemy is directly at the door + stateInit.Trigger.Add(new AiTriggerCountdown(450, null, () => _aiComponent.ChangeState("notSpawned"))); + var stateHidden = new AiState(); + stateHidden.Trigger.Add(new AiTriggerCountdown(2000, null, () => _aiComponent.ChangeState("notSpawned"))); + var stateNotSpawned = new AiState(UpdateNotSpawned); + var stateSpawning = new AiState(UpdateSpawning); + var stateFalling = new AiState(UpdateFalling); + var stateJumping = new AiState(UpdateJumping); + var stateWaiting = new AiState(UpdateWaiting); + stateWaiting.Trigger.Add(new AiTriggerRandomTime(WaitingTrigger, 750, 1250)); + var stateShaking = new AiState(); + stateShaking.Trigger.Add(new AiTriggerCountdown(500, ShakingTick, ShakingEnd)); + var stateDespawning = new AiState(UpdateDespawning); + var stateSpawnDelay = new AiState(); + stateSpawnDelay.Trigger.Add(new AiTriggerCountdown(450, null, EndSpawnDelay)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("init", stateInit); + _aiComponent.States.Add("notSpawned", stateNotSpawned); + _aiComponent.States.Add("hidden", stateHidden); + _aiComponent.States.Add("spawning", stateSpawning); + _aiComponent.States.Add("fall", stateFalling); + _aiComponent.States.Add("jumping", stateJumping); + _aiComponent.States.Add("waiting", stateWaiting); + _aiComponent.States.Add("shaking", stateShaking); + _aiComponent.States.Add("despawning", stateDespawning); + _aiComponent.States.Add("spawnDelay", stateSpawnDelay); + _damageState = new AiDamageState(this, _body, _aiComponent, _sprite, 1); + new AiFallState(_aiComponent, _body, null, null, 250); + new AiDeepWaterState(_body); + + _aiComponent.ChangeState("init"); + + var damageBox = new CBox(EntityPosition, -6, -11, 0, 12, 11, 4); + var hittableBox = new CBox(EntityPosition, -6, -11, 0, 12, 11, 8, true); + + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, _damageState.OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(BaseAnimationComponent.Index, _animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _sprite)); + + if (_fallMode) + InitFalling(); + else + { + _body.IsActive = false; + _damageState.IsActive = false; + _damageField.IsActive = false; + _sprite.IsVisible = false; + } + } + + /// + /// Function used by the chest to stay in the air for a little bit before falling down + /// + public void SpawnDelay() + { + _body.IgnoresZ = true; + _animator.Play("idle"); + _sprite.IsVisible = true; + _aiComponent.ChangeState("spawnDelay"); + } + + private void EndSpawnDelay() + { + _damageState.IsActive = true; + _damageField.IsActive = true; + _body.IsActive = true; + _body.IgnoresZ = false; + _body.IsGrounded = false; + + _jumpsLeft = Game1.RandomNumber.Next(3, 5); + ToJump(); + } + + private void InitFalling() + { + _body.IsGrounded = false; + _animator.Play("jump"); + _aiComponent.ChangeState("jumping"); + _sprite.Color = Color.Transparent; + } + + private void UpdateNotSpawned() + { + var distVec = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + + // spawn? + if (distVec.Length() < 32) + ToSpawning(); + } + + private void ToSpawning() + { + _jumpsLeft = Game1.RandomNumber.Next(3, 5); + _animator.Play("spawn"); + _sprite.IsVisible = true; + + _aiComponent.ChangeState("spawning"); + } + + private void UpdateSpawning() + { + // fall down + if (!_animator.IsPlaying) + ToFalling(); + } + + private void ToFalling() + { + Game1.GameManager.PlaySoundEffect("D360-36-24"); + + _pushable = true; + _body.IsActive = true; + _damageState.IsActive = true; + _damageField.IsActive = true; + + // fall down + EntityPosition.Z = 5; + + _animator.Play("idle"); + _aiComponent.ChangeState("fall"); + } + + private void UpdateFalling() + { + if (_body.IsGrounded) + _aiComponent.ChangeState("shaking"); + } + + private void UpdateWaiting() + { + _animator.Play("idle"); + } + + private void WaitingTrigger() + { + if (_jumpsLeft <= 0 && !_fallMode) + ToDespawn(); + else + ToJump(); + } + + private void ToJump() + { + _jumpsLeft--; + + _aiComponent.ChangeState("jumping"); + _animator.Play("jump"); + + Game1.GameManager.PlaySoundEffect("D360-36-24"); + + var vecDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (vecDirection != Vector2.Zero) + vecDirection.Normalize(); + vecDirection *= 0.75f; + + _body.VelocityTarget = new Vector2(vecDirection.X, vecDirection.Y); + _body.Velocity.Z = 1.5f; + } + + private void UpdateJumping() + { + _sprite.Color = Color.White * MathF.Min((100 - EntityPosition.Z) / 10f, 1); + + if (_body.IsGrounded) + { + _body.VelocityTarget = Vector2.Zero; + _aiComponent.ChangeState("waiting"); + } + } + + private void ShakingTick(double time) + { + var shakeState = (float)Math.Sin(time / 25f); + _animationComponent.SpriteOffset.X = -6 + shakeState; + _animationComponent.UpdateSprite(); + } + + private void ShakingEnd() + { + _animationComponent.SpriteOffset.X = -6; + _animationComponent.UpdateSprite(); + _aiComponent.ChangeState("waiting"); + } + + private void ToDespawn() + { + _aiComponent.ChangeState("despawning"); + _animator.Play("despawn"); + + _pushable = false; + _body.IsActive = false; + _damageState.IsActive = false; + _damageField.IsActive = false; + } + + private void UpdateDespawning() + { + // hide + if (_animator.IsPlaying) + return; + + _sprite.IsVisible = false; + _aiComponent.ChangeState("hidden"); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (!_pushable || type != PushableComponent.PushType.Impact) + return false; + + _body.Velocity = new Vector3(direction.X, direction.Y, _body.Velocity.Z); + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyHardhatBeetle.cs b/InGame/GameObjects/Enemies/EnemyHardhatBeetle.cs new file mode 100644 index 0000000..3565490 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyHardhatBeetle.cs @@ -0,0 +1,200 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyHardhatBeetle : GameObject + { + private readonly BodyComponent _body; + private readonly AiStunnedState _stunnedState; + private readonly Animator _animator; + private readonly AiDamageState _damageState; + + private Vector2 _vecDirection; + + private float _maxSpeed; + private float _acceleration; + private float _currentSpeed; + + private bool _isFollowing; + private bool _wasFollowing; + + public EnemyHardhatBeetle() : base("hardHatBeetle") { } + + public EnemyHardhatBeetle(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/hardhat beetle"); + _animator.Play("walk"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, Vector2.Zero); + + var fieldRectangle = map.GetField(posX, posY); + + _body = new BodyComponent(EntityPosition, -6, -10, 12, 9, 8) + { + MoveCollision = OnCollision, + Drag = 0.875f, + AvoidTypes = Values.CollisionTypes.Hole | + Values.CollisionTypes.NPCWall | + Values.CollisionTypes.DeepWater, + FieldRectangle = fieldRectangle + }; + + var aiComponent = new AiComponent(); + + var stateInit = new AiState(); + stateInit.Trigger.Add(new AiTriggerCountdown(350, null, () => aiComponent.ChangeState("moving"))); + var stateMoving = new AiState(UpdateMoving) { Init = InitMoving }; + + aiComponent.States.Add("init", stateInit); + aiComponent.States.Add("moving", stateMoving); + _stunnedState = new AiStunnedState(aiComponent, animationComponent, 3300, 900) { SilentStateChange = false }; + _damageState = new AiDamageState(this, _body, aiComponent, sprite, 1); + new AiDeepWaterState(_body); + new AiFallState(aiComponent, _body, OnHoleAbsorb, null); + + aiComponent.ChangeState("init"); + + // randomize speed and acceleration + _maxSpeed = Game1.RandomNumber.Next(30, 60) / 100f; + _acceleration = Game1.RandomNumber.Next(30, 60) / 2000f; + + var damageCollider = new CBox(EntityPosition, -7, -11, 0, 14, 11, 4); + var hittableRectangle = new CBox(EntityPosition, -8, -14, 16, 14, 8); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 4)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableRectangle, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush) { RepelMultiplier = 1.25f }); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(AiComponent.Index, aiComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + } + + private void InitMoving() + { + _animator.Play("walk"); + } + + private void UpdateMoving() + { + // accelerate + _currentSpeed += (float)Math.Pow(_acceleration, Game1.TimeMultiplier); + if (_currentSpeed > _maxSpeed) + _currentSpeed = _maxSpeed; + + if (_vecDirection != Vector2.Zero) + { + var oldPercentage = (float)Math.Pow(0.9f, Game1.TimeMultiplier); + var newDirection = _body.VelocityTarget * oldPercentage + + _vecDirection * (1 - oldPercentage); + newDirection.Normalize(); + + _body.VelocityTarget = newDirection * _maxSpeed; + } + else + _body.VelocityTarget = Vector2.Zero; + + _isFollowing = _body.FieldRectangle.Intersects(MapManager.ObjLink.BodyRectangle); + + if (_isFollowing) + { + _vecDirection = new Vector2( + MapManager.ObjLink.EntityPosition.X - EntityPosition.X, + MapManager.ObjLink.EntityPosition.Y - EntityPosition.Y); + + if (_vecDirection != Vector2.Zero) + _vecDirection.Normalize(); + } + + _wasFollowing = _isFollowing; + _isFollowing = false; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X * 1.5f, direction.Y * 1.5f, _body.Velocity.Z); + + return true; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_damageState.IsInDamageState()) + return Values.HitCollision.None; + _damageState.SetDamageState(false); + + if (damageType == HitType.Boomerang || damageType == HitType.Hookshot) + { + _body.VelocityTarget = Vector2.Zero; + _animator.Play("stunned"); + _stunnedState.StartStun(); + } + + _body.Velocity.X = direction.X * 3.0f; + _body.Velocity.Y = direction.Y * 3.0f; + + Game1.GameManager.PlaySoundEffect("D360-09-09"); + + return Values.HitCollision.Enemy; + } + + private void OnCollision(Values.BodyCollision direction) + { + // this is used so that the speed is not lost while sliding on a wall + // not sure if this could be done better + if (_wasFollowing) + { + if ((direction & Values.BodyCollision.Horizontal) != 0) + { + var ratio = Math.Abs(_vecDirection.X) / Math.Abs(_vecDirection.Y); + if (1 < ratio && ratio < 25) + { + _vecDirection.X = 0; + _vecDirection.Y *= ratio; + } + } + else if ((direction & Values.BodyCollision.Vertical) != 0) + { + var ratio = Math.Abs(_vecDirection.Y) / Math.Abs(_vecDirection.X); + if (1 < ratio && ratio < 25) + { + _vecDirection.X *= ratio; + _vecDirection.Y = 0; + } + } + + return; + } + + _body.VelocityTarget = Vector2.Zero; + + // collide with a wall + if ((direction & Values.BodyCollision.Horizontal) != 0) + _vecDirection.X = -_vecDirection.X; + else if ((direction & Values.BodyCollision.Vertical) != 0) + _vecDirection.Y = -_vecDirection.Y; + } + + private void OnHoleAbsorb() + { + _animator.SpeedMultiplier = 2.0f; + _animator.Play("walk"); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyIronMask.cs b/InGame/GameObjects/Enemies/EnemyIronMask.cs new file mode 100644 index 0000000..63e10e0 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyIronMask.cs @@ -0,0 +1,175 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyIronMask : GameObject + { + private readonly Animator _animator; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _damageState; + + private float _moveSpeed = 0.5f; + private float _moveSpeedUnprotected = 0.75f; + private int _direction; + private bool _isUnprotected; + + public EnemyIronMask() : base("iron mask") { } + + public EnemyIronMask(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/iron mask"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -15)); + + _body = new BodyComponent(EntityPosition, -6, -10, 12, 10, 8) + { + MoveCollision = OnCollision, + CollisionTypes = Values.CollisionTypes.Normal | + Values.CollisionTypes.Enemy, + AvoidTypes = Values.CollisionTypes.Hole | Values.CollisionTypes.NPCWall, + FieldRectangle = map.GetField(posX, posY), + Bounciness = 0.25f, + Drag = 0.85f + }; + + var stateIdle = new AiState { Init = InitIdle }; + stateIdle.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("walking"), 350, 750)); + var stateWalking = new AiState { Init = InitWalking }; + stateWalking.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("idle"), 750, 1000)); + var stateStunned = new AiState { Init = InitStunned }; + stateStunned.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("walking"), 1000, 1200)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("walking", stateWalking); + _aiComponent.States.Add("stunned", stateStunned); + _damageState = new AiDamageState(this, _body, _aiComponent, sprite, 2) { OnBurn = () => _animator.Pause() }; + new AiFallState(_aiComponent, _body, OnHoleAbsorb); + new AiDeepWaterState(_body); + + _aiComponent.ChangeState("idle"); + + // stand in a random direction + _direction = Game1.RandomNumber.Next(0, 4); + _animator.Play("walk_" + _direction); + _animator.IsPlaying = false; + + var damageBox = new CBox(EntityPosition, -8, -12, 0, 16, 12, 4); + var hittableBox = new CBox(EntityPosition, -7, -14, 14, 14, 8); + var pushableBox = new CBox(EntityPosition, -7, -12, 14, 12, 8); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + } + + private void InitStunned() + { + if (!_isUnprotected) + _animator.IsPlaying = false; + _body.VelocityTarget = Vector2.Zero; + } + + private void InitIdle() + { + if (!_isUnprotected) + _animator.IsPlaying = false; + _body.VelocityTarget = Vector2.Zero; + } + + private void InitWalking() + { + ChangeDirection(); + } + + private void ChangeDirection() + { + // random new direction + _direction = Game1.RandomNumber.Next(0, 4); + + if (!_isUnprotected) + _animator.Play("walk_" + _direction); + + _body.VelocityTarget = AnimationHelper.DirectionOffset[_direction] * + (_isUnprotected ? _moveSpeedUnprotected : _moveSpeed); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + // can be hit if the damage source is coming from the back + var dir = AnimationHelper.GetDirection(direction); + + if (!_isUnprotected && type == HitType.Hookshot && dir == (_direction + 2) % 4 && + _aiComponent.CurrentStateId != "stunned") + { + _isUnprotected = true; + _animator.Play("unprotected"); + _damageState.SetDamageState(false); + return Values.HitCollision.Repelling; + } + + // throw objects will kill him directly + if (type == HitType.ThrownObject || type == HitType.Bomb || type == HitType.MagicPowder || type == HitType.MagicRod) + return _damageState.OnHit(originObject, direction, type, damage, pieceOfPower); + + // gets attacked from behind or is unprotected? + if (dir == (_direction) % 4 || _isUnprotected || type == HitType.Hookshot) + return _damageState.OnHit(originObject, direction, type, damage, pieceOfPower); + + // gets attacked from behind/sides by a bow + if ((dir != (_direction + 2) % 4) && (type == HitType.Bow || type == HitType.Boomerang)) + return _damageState.OnHit(originObject, direction, type, damage, pieceOfPower); + + if (_aiComponent.CurrentStateId != "stunned") + { + _body.Velocity = new Vector3(direction, 0); + _aiComponent.ChangeState("stunned"); + } + + return Values.HitCollision.RepellingParticle; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X, direction.Y, _body.Velocity.Z); + + return true; + } + + private void OnCollision(Values.BodyCollision direction) + { + if (_aiComponent.CurrentStateId != "walking") + return; + + // stop walking + _aiComponent.ChangeState("idle"); + } + + private void OnHoleAbsorb() + { + _animator.SpeedMultiplier = 3f; + + if (!_isUnprotected) + _animator.Play("walk_" + _direction); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyKarakoro.cs b/InGame/GameObjects/Enemies/EnemyKarakoro.cs new file mode 100644 index 0000000..a80b017 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyKarakoro.cs @@ -0,0 +1,487 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyKarakoro : GameObject + { + private readonly Color[] _colors = { new Color(17, 172, 66), new Color(255, 8, 42), new Color(25, 132, 255) }; + + private readonly List _holeList = new List(); + private readonly BoxCollisionComponent _boxCollision; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly CSprite _sprite; + private readonly DamageFieldComponent _damageField; + private readonly CarriableComponent _carriableComponent; + private readonly AiDamageState _damageState; + + private ObjHole _hole; + + private readonly string _strKey; + private readonly string _strAllSetKey; + private const float WalkSpeed = 0.25f; + private const float RotateSpeed = 0.85f; + private const int ShakeTime = 900; + private int _direction; + private readonly int _colorIndex; + private float _initShakeSpriteOffsetX; + private bool _smallBody; + private bool _throwDamage; + + private Vector2 _holeStartPosition; + private Vector2 _holeTargetPosition; + private const int HoleTime = 350; + private bool _inHole; + + public EnemyKarakoro() : base("karakoro") { } + + public EnemyKarakoro(Map.Map map, int posX, int posY, int colorIndex, string strKey, string strAllSetKey) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 12, 0); + EntitySize = new Rectangle(-12, -15, 24, 16); + + _colorIndex = MathHelper.Clamp(colorIndex, 0, 2); + _strKey = strKey; + _strAllSetKey = strAllSetKey; + + // the strAllSetKey is meant to be set if all karakoro are in there hole + // if it is not set we reset each karakoro individually so the player has to start + // over if he dies or leaves after settings only some karakoros but not all + if (!string.IsNullOrEmpty(strKey) && + (string.IsNullOrEmpty(strAllSetKey) || + Game1.GameManager.SaveManager.GetString(strAllSetKey) != "1")) + { + Game1.GameManager.SaveManager.SetString(strKey, "0"); + } + else + { + IsDead = true; + return; + } + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/karakoro"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -7, -12, 14, 12, 8) + { + MoveCollision = OnMoveCollision, + HoleOnPull = OnHolePull, + HoleAbsorb = () => OnHolePull(Vector2.Zero, 100), + IgnoreHoles = true, + AbsorbPercentage = 0.9f, + CollisionTypes = + Values.CollisionTypes.Normal | + Values.CollisionTypes.NPCWall, + AvoidTypes = Values.CollisionTypes.Hole, + FieldRectangle = map.GetField(posX, posY, 8), + Bounciness = 0.55f, + Drag = 0.9f, + DragAir = 1.0f + }; + + var stateWalk = new AiState { Init = InitWalk }; + stateWalk.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("idle"), 750, 1000)); + var stateRotate = new AiState { Init = InitRotate }; + stateRotate.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("idle"), 500, 750)); + var stateIdle = new AiState { Init = InitIdle }; + stateIdle.Trigger.Add(new AiTriggerRandomTime(EndIdle, 250, 500)); + var stateBall = new AiState(UpdateBall) { Init = InitBall }; + stateBall.Trigger.Add(new AiTriggerCountdown(3300, null, () => _aiComponent.ChangeState("shake"))); + var stateCarried = new AiState() { Init = InitCarried }; + var stateShake = new AiState { Init = InitShake }; + stateShake.Trigger.Add(new AiTriggerCountdown(ShakeTime, ShakeTick, ShakeEnd)); + var stateHoleJump = new AiState { Init = InitHoleJump }; + stateHoleJump.Trigger.Add(new AiTriggerCountdown(HoleTime, HoleJumpTick, HoleJumpEnd)); + var stateHole = new AiState(); + var stateWrongHole = new AiState(); + stateWrongHole.Trigger.Add(new AiTriggerCountdown(400, null, EndWrongHole)); + + _aiComponent = new AiComponent(); + + _aiComponent.States.Add("walk", stateWalk); + _aiComponent.States.Add("rotate", stateRotate); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("ball", stateBall); + _aiComponent.States.Add("carried", stateCarried); + _aiComponent.States.Add("shake", stateShake); + _aiComponent.States.Add("holeJump", stateHoleJump); + _aiComponent.States.Add("hole", stateHole); + _aiComponent.States.Add("wrongHole", stateWrongHole); + _damageState = new AiDamageState(this, _body, _aiComponent, _sprite, 2) { HitMultiplierX = 2.5f, HitMultiplierY = 2.5f }; + + _aiComponent.ChangeState(Game1.RandomNumber.Next(0, 2) == 0 ? "idle" : "walk"); + _aiComponent.ChangeState("walk"); + + var damageBox = new CBox(EntityPosition, -8, -14, 0, 16, 14, 4); + var hittableBox = new CBox(EntityPosition, -8, -14, 0, 16, 14, 8); + var pushableBox = new CBox(EntityPosition, -8, -14, 0, 16, 14, 8); + + if (!string.IsNullOrEmpty(_strAllSetKey)) + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + AddComponent(CarriableComponent.Index, _carriableComponent = new CarriableComponent( + new CRectangle(EntityPosition, new Rectangle(-8, -15, 16, 16)), CarryInit, CarryUpdate, CarryThrow) + { IsActive = false }); + AddComponent(CollisionComponent.Index, _boxCollision = new BoxCollisionComponent(new CBox(EntityPosition, -8, -14, 16, 14, 8), Values.CollisionTypes.Enemy) { IsActive = false }); + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, DrawSprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _sprite) { Height = 1.0f, Rotation = 0.1f, ShadowWidth = 10, ShadowHeight = 5 }); + } + + private void OnKeyChange() + { + if (Game1.GameManager.SaveManager.GetString(_strAllSetKey, "0") == "1") + Despawn(); + } + + private void Despawn() + { + _hole.IsActive = true; + + Map.Objects.SpawnObject(new ObjAnimator(Map, + (int)EntityPosition.X - 8, (int)EntityPosition.Y - 16, Values.LayerPlayer, "Particles/spawn", "run", true)); + + Map.Objects.DeleteObjects.Add(this); + } + + private void UpdateBall() + { + if (_throwDamage) + { + var box = _body.BodyBox.Box; + var hitCollision = Map.Objects.Hit(this, box.Center, box, HitType.ThrownObject, 2, false); + if (hitCollision != 0) + { + _body.Velocity.X = -_body.Velocity.X * 0.5f; + _body.Velocity.Y = -_body.Velocity.Y * 0.5f; + } + } + } + + private void EndIdle() + { + var playerDistance = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + + if (playerDistance.Length() < 38) + _aiComponent.ChangeState("rotate"); + else + _aiComponent.ChangeState("walk"); + } + + private void InitRotate() + { + var lastFrame = _animator.CurrentFrameIndex; + + if (_animator.CurrentAnimation.Id == "rotate") + { + _animator.Continue(); + } + else + { + _animator.Play("rotate"); + + // make sure to start the animation at the same frame as the current walk animation + var directionFrame = _direction; + if (directionFrame == 1) + directionFrame = 2; + if (directionFrame == 2) + directionFrame = 1; + + _animator.SetFrame(directionFrame * 2 + lastFrame); + } + + var direction = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (direction != Vector2.Zero) + direction.Normalize(); + _body.VelocityTarget = direction * RotateSpeed; + } + + private void InitCarried() + { + if (_aiComponent.LastStateId == "shake") + _sprite.DrawOffset.X = _initShakeSpriteOffsetX; + } + + private void InitBall() + { + _carriableComponent.IsActive = true; + _damageField.IsActive = false; + _body.IgnoreHoles = false; + _body.VelocityTarget = Vector2.Zero; + _animator.Play("ball"); + } + + private void InitWalk() + { + // walk into a random direction + _direction = Game1.RandomNumber.Next(0, 4); + _body.VelocityTarget = AnimationHelper.DirectionOffset[_direction] * WalkSpeed; + + _animator.Play("walk_" + _direction); + } + + private void InitIdle() + { + _animator.Pause(); + _body.VelocityTarget = Vector2.Zero; + + // @HACK: the gets smaller when thrown; + // if this would not be the case the enemy could be moved into a wall because he has a smaller collision box + // so after the body was thrown we try to restore the original size + if (_smallBody) + { + var box = new Box(EntityPosition.Position.X - 7, EntityPosition.Position.Y - 12, 0, 14, 12, 8); + var cBox = Box.Empty; + if (!Map.Objects.Collision( + box, Box.Empty, _body.CollisionTypes, _body.CollisionTypesIgnore, 0, _body.Level, ref cBox)) + { + _smallBody = false; + _body.OffsetX = -7; + _body.OffsetY = -12; + _body.Width = 14; + _body.Height = 12; + } + } + } + + private void InitShake() + { + _initShakeSpriteOffsetX = _sprite.DrawOffset.X; + } + + private void ShakeTick(double counter) + { + _sprite.DrawOffset.X = _initShakeSpriteOffsetX + (float)Math.Sin((ShakeTime - counter) / 1000 * (60 / 4f) * Math.PI) * 2; + } + + private void ShakeEnd() + { + _carriableComponent.IsActive = false; + _damageField.IsActive = true; + _body.IgnoreHoles = true; + _sprite.DrawOffset.X = _initShakeSpriteOffsetX; + _aiComponent.ChangeState("walk"); + } + + private Vector3 CarryInit() + { + _smallBody = true; + _body.OffsetX = -4; + _body.OffsetY = -10; + _body.Width = 8; + _body.Height = 10; + + _aiComponent.ChangeState("carried"); + + // the stone was picked up + _body.IsActive = false; + + return EntityPosition.ToVector3(); + } + + private bool CarryUpdate(Vector3 newPosition) + { + if (!_body.FieldRectangle.Contains(new RectangleF( + newPosition.X + _body.OffsetX, newPosition.Y + _body.OffsetY, _body.Width, _body.Height))) + return false; + + EntityPosition.X = newPosition.X; + EntityPosition.Y = newPosition.Y; + EntityPosition.Z = newPosition.Z; + EntityPosition.NotifyListeners(); + + return true; + } + + private void CarryThrow(Vector2 velocity) + { + _aiComponent.ChangeState("ball"); + + _throwDamage = true; + + _body.IsActive = true; + _body.IsGrounded = false; + _body.JumpStartHeight = 0; + + var throwMultiplier = 0.75f; + _body.Velocity.X = velocity.X * throwMultiplier; + _body.Velocity.Y = velocity.Y * throwMultiplier; + _body.Velocity.Z = 1.0f; + } + + private void InitHoleJump() + { + // activate the collision so we can not walk into the ball in the hole + _boxCollision.IsActive = true; + _inHole = true; + _carriableComponent.IsActive = false; + _body.IsActive = false; + } + + private void HoleJumpTick(double counter) + { + var lerpAmount = 1 - (float)(counter / HoleTime); + var newPosition = Vector2.Lerp(_holeStartPosition, _holeTargetPosition, lerpAmount); + EntityPosition.Set(newPosition); + EntityPosition.Z = MathF.Sin(lerpAmount * MathF.PI) * 8; + } + + private void HoleJumpEnd() + { + HoleJumpTick(0); + + // check if we are in the right hole + if (_hole.Color == _colorIndex) + { + if (!string.IsNullOrEmpty(_strKey)) + Game1.GameManager.SaveManager.SetString(_strKey, "1"); + + Game1.GameManager.PlaySoundEffect("D378-04-04"); + _aiComponent.ChangeState("hole"); + } + else + { + Game1.GameManager.PlaySoundEffect("D360-29-1D"); + _aiComponent.ChangeState("wrongHole"); + } + + EntityPosition.Set(_holeTargetPosition); + } + + private void EndWrongHole() + { + // jump out of the hole + _boxCollision.IsActive = false; + _hole.IsActive = true; + _inHole = false; + _carriableComponent.IsActive = true; + _body.IsActive = true; + _body.Velocity.X = _body.FieldRectangle.Center.X < EntityPosition.X ? -1.25f : 1.25f; + _body.Velocity.Z = 1.75f; + _aiComponent.ChangeState("ball"); + } + + private void OnHolePull(Vector2 direction, float percentage) + { + if (!_inHole && percentage > 0.50f && _aiComponent.CurrentStateId == "ball") + { + // get the hole we are falling into + var bodyBox = _body.BodyBox.Box; + + _holeList.Clear(); + Map.Objects.GetComponentList( + _holeList, (int)bodyBox.X, (int)bodyBox.Y, (int)bodyBox.Width, (int)bodyBox.Height, CollisionComponent.Mask); + + foreach (var gameObjectHole in _holeList) + { + var collisionComponent = gameObjectHole.Components[CollisionComponent.Index] as CollisionComponent; + var collidingBox = Box.Empty; + if (collisionComponent == null || + (collisionComponent.CollisionType & Values.CollisionTypes.Hole) == 0 || + !collisionComponent.Collision(bodyBox, 0, 0, ref collidingBox)) + continue; + + if (gameObjectHole is ObjHole holeObject) + { + _hole = holeObject; + _hole.IsActive = false; + + _holeStartPosition = EntityPosition.Position; + _holeTargetPosition = new Vector2(holeObject.Center.X, holeObject.Center.Y + 8); + + _aiComponent.ChangeState("holeJump"); + + return; + } + } + } + } + + private void DrawSprite(SpriteBatch spriteBatch) + { + _sprite.Draw(spriteBatch); + + // draw the colored part of the sprite + var sourceX = _sprite.SourceRectangle.X; + _sprite.SourceRectangle.X += (int)(28 / _sprite.Scale); + + _sprite.Color = _colors[_colorIndex]; + _sprite.Draw(spriteBatch); + + _sprite.SourceRectangle.X = sourceX; + _sprite.Color = Color.White; + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + if (_damageState.IsInDamageState() || originObject == this) + return Values.HitCollision.None; + + if (!_inHole) + { + Game1.GameManager.PlaySoundEffect("D360-03-03"); + + _aiComponent.ChangeState("ball"); + _damageState.HitKnockBack(originObject, direction, type, pieceOfPower, false); + + return Values.HitCollision.Blocking; + } + + if (type == HitType.Bow) + return Values.HitCollision.Repelling; + + return Values.HitCollision.Particle | Values.HitCollision.Blocking; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + var pushStrength = 1f; + if (!_inHole && type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X * pushStrength, direction.Y * pushStrength, _body.Velocity.Z); + + return true; + } + + private void OnMoveCollision(Values.BodyCollision direction) + { + if ((direction & Values.BodyCollision.Horizontal) != 0) + _body.Velocity.X = -_body.Velocity.X * 0.5f; + if ((direction & Values.BodyCollision.Vertical) != 0) + _body.Velocity.Y = -_body.Velocity.Y * 0.5f; + if ((direction & Values.BodyCollision.Floor) != 0) + { + // stop dealing damage after hitting the floor + _throwDamage = false; + + if (_body.Velocity.Z == 0) + _body.Velocity *= 0.5f; + else + { + _body.Velocity.X *= 0.8f; + _body.Velocity.Y *= 0.8f; + } + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyKeese.cs b/InGame/GameObjects/Enemies/EnemyKeese.cs new file mode 100644 index 0000000..e5282e0 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyKeese.cs @@ -0,0 +1,129 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyKeese : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + + private readonly float _turnSpeed; + + private float _flyState; + private int _dir; + + public EnemyKeese() : base("keese") { } + + public EnemyKeese(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + _turnSpeed = Game1.RandomNumber.Next(20, 30) / 1000f; + _flyState = (float)Math.PI / 2 * Game1.RandomNumber.Next(0, 4); + _dir = Game1.RandomNumber.Next(0, 2) * 2 - 1; + + EntityPosition = new CPosition(posX + 8, posY + 24, 0); + EntitySize = new Rectangle(-8, -24, 16, 24); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/keese"); + _animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animatorComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -21)); + + var fieldRectangle = map.GetField(posX, posY, 8); + + _body = new BodyComponent(EntityPosition, -6, -20, 12, 8, 8) + { + IgnoresZ = true, + IgnoreHoles = true, + CollisionTypes = Values.CollisionTypes.None, + MoveCollision = OnCollision, + FieldRectangle = fieldRectangle + }; + + _aiComponent = new AiComponent(); + + var stateIdle = new AiState(UpdateIdle); + var stateCooldown = new AiState(); + stateCooldown.Trigger.Add(new AiTriggerRandomTime(StartIdle, 1000, 2000)); + var stateFlying = new AiState(UpdateFlying); + stateFlying.Trigger.Add(new AiTriggerRandomTime(StartCooldown, 1000, 2000)); + + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("cooldown", stateCooldown); + _aiComponent.States.Add("flying", stateFlying); + new AiFallState(_aiComponent, _body, null, null, 0); + var damageState = new AiDamageState(this, _body, _aiComponent, sprite, 1) { OnBurn = OnBurn }; + + _aiComponent.ChangeState("cooldown"); + + var damageCollider = new CBox(EntityPosition, -5, -20, 0, 10, 8, 4); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, damageState.OnHit)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animatorComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer) { WaterOutline = false }); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + } + + private void OnBurn() + { + _body.IgnoresZ = false; + _body.IgnoreHoles = false; + } + + private void StartIdle() + { + _aiComponent.ChangeState("idle"); + } + + private void UpdateIdle() + { + var distVec = EntityPosition.Position - new Vector2(MapManager.ObjLink.PosX, MapManager.ObjLink.PosY + 16); + + // start flying if the player is near the keese + if (distVec.Length() < 60) + StartFlying(); + } + + private void StartFlying() + { + _aiComponent.ChangeState("flying"); + _dir = Game1.RandomNumber.Next(0, 2) * 2 - 1; + } + + private void UpdateFlying() + { + _animator.Play("fly"); + + _flyState += _dir * _turnSpeed * Game1.TimeMultiplier; + var vecDirection = new Vector2((float)Math.Sin(_flyState), (float)Math.Cos(_flyState)); + + _body.VelocityTarget = vecDirection * 0.75f; + } + + private void StartCooldown() + { + _aiComponent.ChangeState("cooldown"); + _animator.Play("idle"); + _body.VelocityTarget = Vector2.Zero; + } + + private void OnCollision(Values.BodyCollision direction) + { + _flyState += (float)Math.PI; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyLeever.cs b/InGame/GameObjects/Enemies/EnemyLeever.cs new file mode 100644 index 0000000..773c86b --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyLeever.cs @@ -0,0 +1,220 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyLeever : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly BodyDrawComponent _bodyDrawComponent; + private readonly DamageFieldComponent _damageField; + private readonly AiDamageState _damageState; + private readonly Animator _animator; + private readonly CSprite _sprite; + + private readonly Rectangle _fieldPosition; + + private const float MoveSpeed = 0.5f; + + public EnemyLeever() : base("leever") { } + + public EnemyLeever(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-50, -50 - 8, 100, 100); + + _fieldPosition = map.GetField(posX, posY); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/leever"); + _animator.Play("move"); + + _sprite = new CSprite(EntityPosition); + _sprite.IsVisible = false; + + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-8, -16)); + + _body = new BodyComponent(EntityPosition, -7, -12, 14, 12, 8) + { + CollisionTypes = + Values.CollisionTypes.Normal | + Values.CollisionTypes.Enemy | + Values.CollisionTypes.Player, + AvoidTypes = + Values.CollisionTypes.Hole | + Values.CollisionTypes.NPCWall, + Bounciness = 0.25f, + Drag = 0.85f, + }; + + var stateInit = new AiState(); + stateInit.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("hidden"), 750, 1500)); + var stateHidden = new AiState(); + var stateSpawning = new AiState(UpdateSpawning); + var stateMoving = new AiState(UpdateMoving); + stateMoving.Trigger.Add(new AiTriggerRandomTime(ToLeaving, 2000, 3000)); + var stateLeaving = new AiState(UpdateLeaving); + var stateWaiting = new AiState(); + stateWaiting.Trigger.Add(new AiTriggerRandomTime(Spawn, 1000, 2000)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("init", stateInit); + _aiComponent.States.Add("hidden", stateHidden); + _aiComponent.States.Add("spawning", stateSpawning); + _aiComponent.States.Add("moving", stateMoving); + _aiComponent.States.Add("leaving", stateLeaving); + _aiComponent.States.Add("waiting", stateWaiting); + _damageState = new AiDamageState(this, _body, _aiComponent, _sprite, 2) { OnBurn = OnBurn }; + + _aiComponent.ChangeState("init"); + + var damageBox = new CBox(EntityPosition, -8, -13, 0, 16, 14, 4); + var hittableBox = new CBox(EntityPosition, -7, -14, 0, 14, 14, 8); + var spawnRectangle = new Rectangle(posX + 8 + EntitySize.X, posY + 16 + EntitySize.Y, EntitySize.Width, EntitySize.Height); + + AddComponent(ObjectCollisionComponent.Index, new ObjectCollisionComponent(spawnRectangle, OnEnterSpawnArea)); + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, _damageState.OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(DrawComponent.Index, _bodyDrawComponent = new BodyDrawComponent(_body, _sprite, Values.LayerPlayer) { IsActive = false }); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(_sprite)); + + Deactivate(); + } + + private void OnBurn() + { + _animator.Pause(); + } + + private void OnEnterSpawnArea(GameObject gameObject) + { + // spawn if the player enters the spawnRectangle + if (_aiComponent.CurrentStateId == "hidden") + Spawn(); + } + + private void Activate() + { + _damageField.IsActive = true; + _body.IsActive = true; + } + + private void Deactivate() + { + _damageState.IsActive = false; + _damageField.IsActive = false; + _body.IsActive = false; + } + + private void Spawn() + { + // find new position + var newPosition = new Vector2( + _fieldPosition.X + Game1.RandomNumber.Next(0, 10) * 16, + _fieldPosition.Y + Game1.RandomNumber.Next(0, 8) * 16); + + // make sure to not spawn directly at the player + var playerDistance = MapManager.ObjLink.EntityPosition.Position - new Vector2(newPosition.X + 8, newPosition.Y + 16); + if (playerDistance.Length() < 24) + return; + + // respawn if the position is free + var collidingRectangle = Box.Empty; + var fieldState = Map.GetFieldState(newPosition); + if ((fieldState & (MapStates.FieldStates.Water | MapStates.FieldStates.DeepWater)) == 0 && + !Map.Objects.Collision(new Box(newPosition.X, newPosition.Y, 0, 16, 16, 16), Box.Empty, + Values.CollisionTypes.Normal | Values.CollisionTypes.NPCWall | Values.CollisionTypes.Enemy | Values.CollisionTypes.Player, 0, 0, ref collidingRectangle)) + { + EntityPosition.Set(newPosition + new Vector2(8, 16)); + ToSpawning(); + } + } + + private void ToSpawning() + { + _aiComponent.ChangeState("spawning"); + + _bodyDrawComponent.IsActive = true; + _sprite.IsVisible = true; + + _animator.Play("spawn"); + } + + private void UpdateSpawning() + { + if (_animator.CurrentFrameIndex > 0) + _damageState.IsActive = true; + + if (!_animator.IsPlaying) + ToMoving(); + } + + private void ToMoving() + { + _aiComponent.ChangeState("moving"); + + Activate(); + + _animator.Play("move"); + } + + private void UpdateMoving() + { + // move in the direction of the player + var direction = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + direction.Normalize(); + _body.VelocityTarget = direction * MoveSpeed; + } + + private void ToLeaving() + { + _aiComponent.ChangeState("leaving"); + + Deactivate(); + + _body.VelocityTarget = Vector2.Zero; + _animator.Play("leave"); + } + + private void UpdateLeaving() + { + if (_animator.CurrentFrameIndex > 1) + _damageState.IsActive = false; + + if (!_animator.IsPlaying) + ToWaiting(); + } + + private void ToWaiting() + { + _aiComponent.ChangeState("waiting"); + + _bodyDrawComponent.IsActive = false; + _sprite.IsVisible = false; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (!_body.IsActive) + return false; + + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X, direction.Y, _body.Velocity.Z); + + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyLikeLike.cs b/InGame/GameObjects/Enemies/EnemyLikeLike.cs new file mode 100644 index 0000000..68b997f --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyLikeLike.cs @@ -0,0 +1,186 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyLikeLike : GameObject + { + private readonly Animator _animator; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _damageState; + private readonly CBox _collisionBox; + private readonly AiTriggerTimer _collisionTimer; + + private float _moveSpeed = 0.5f; + private int _direction; + private bool _hasPlayerTrapped; + private bool _stoleShield; + + public EnemyLikeLike() : base("like like") { } + + public EnemyLikeLike(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntityPosition.AddPositionListener(typeof(EnemyLikeLike), UpdatePosition); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/likelike"); + _animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -16)); + + _body = new BodyComponent(EntityPosition, -7, -12, 14, 12, 8) + { + MoveCollision = OnCollision, + CollisionTypes = Values.CollisionTypes.Normal | + Values.CollisionTypes.Enemy, + AvoidTypes = Values.CollisionTypes.Hole | + Values.CollisionTypes.NPCWall, + FieldRectangle = map.GetField(posX, posY), + Bounciness = 0.25f, + Drag = 0.85f, + AbsorbPercentage = 0.8f + }; + + var stateMove = new AiState(UpdateMoving); + stateMove.Trigger.Add(new AiTriggerRandomTime(ChangeDirection, 350, 650)); + stateMove.Trigger.Add(_collisionTimer = new AiTriggerTimer(1750)); + var stateTrap = new AiState(UpdateTrap); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("moving", stateMove); + _aiComponent.States.Add("trap", stateTrap); + new AiFallState(_aiComponent, _body, OnHoleAbsorb); + _damageState = new AiDamageState(this, _body, _aiComponent, sprite, 2); + _damageState.OnDeath = OnDeath; + ToMoving(); + + // start randomly idle or walking facing a random direction + _direction = Game1.RandomNumber.Next(0, 4); + + var boxHittable = new CBox(EntityPosition, -7, -14, 14, 14, 8); + _collisionBox = new CBox(EntityPosition, -5, -10, 10, 8, 2); + + AddComponent(HittableComponent.Index, new HittableComponent(boxHittable, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + } + + private void UpdatePosition(CPosition newPosition) + { + if (_hasPlayerTrapped) + MapManager.ObjLink.SetPosition(newPosition.Position); + } + + private void ToMoving() + { + ChangeDirection(); + _animator.SpeedMultiplier = 1.0f; + _aiComponent.ChangeState("moving"); + _hasPlayerTrapped = false; + } + + private void UpdateMoving() + { + // collided with the player? + if (_collisionTimer.State && !MapManager.ObjLink.IsTrapped() && + _collisionBox.Box.Intersects(MapManager.ObjLink._body.BodyBox.Box)) + ToTrap(); + } + + private void ToTrap() + { + MapManager.ObjLink.TrapPlayer(); + MapManager.ObjLink.SetPosition(EntityPosition.Position); + + if (!_stoleShield) + { + _stoleShield = MapManager.ObjLink.StealShield(); + if (_stoleShield) + _damageState.SpawnItem = "shieldBack"; + } + + _animator.SpeedMultiplier = 2.0f; + _aiComponent.ChangeState("trap"); + _body.VelocityTarget = Vector2.Zero; + _hasPlayerTrapped = true; + } + + private void UpdateTrap() + { + if (!MapManager.ObjLink.IsTrapped()) + ToMoving(); + } + + private void ChangeDirection() + { + // random new direction + _direction = Game1.RandomNumber.Next(0, 4); + _body.VelocityTarget = AnimationHelper.DirectionOffset[_direction] * _moveSpeed; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_hasPlayerTrapped && (damageType & HitType.Sword) != 0) + return Values.HitCollision.None; + + if (_hasPlayerTrapped && (damageType == HitType.Boomerang || damageType == HitType.Bow || + damageType == HitType.Hookshot || damageType == HitType.MagicRod)) + { + _hasPlayerTrapped = false; + MapManager.ObjLink.FreeTrappedPlayer(); + direction = MapManager.ObjLink.ForwardVector; + } + + return _damageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + } + + private void OnDeath(bool pieceOfPower) + { + _damageState.BaseOnDeath(pieceOfPower); + + // free the player + if (_hasPlayerTrapped) + MapManager.ObjLink.FreeTrappedPlayer(); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction * 1.5f, _body.Velocity.Z); + + return true; + } + + private void OnCollision(Values.BodyCollision direction) + { + if (_aiComponent.CurrentStateId != "moving") + return; + + if ((direction & (Values.BodyCollision.Horizontal | Values.BodyCollision.Vertical)) != 0) + { + _direction = (_direction + 2) % 4; + _body.VelocityTarget = AnimationHelper.DirectionOffset[_direction] * _moveSpeed; + } + } + + private void OnHoleAbsorb() + { + _animator.SpeedMultiplier = 3f; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyMadBomber.cs b/InGame/GameObjects/Enemies/EnemyMadBomber.cs new file mode 100644 index 0000000..97ab3b8 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyMadBomber.cs @@ -0,0 +1,237 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyMadBomber : GameObject + { + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly CSprite _sprite; + private readonly AiDamageState _damageState; + private readonly AiStunnedState _aiStunnedState; + private readonly DamageFieldComponent _damageField; + + private readonly Vector2[] _holeOffsets = { + new Vector2(0, 0), new Vector2(3, -1), new Vector2(-3, -1), + new Vector2(0, -3), new Vector2(-2, 2), new Vector2(2, 2) + }; + + private const string _leafSaveKey = "ow_goldLeafMadBomber"; + + private readonly Vector2 _spawnPosition; + private bool _wasHit; + + public EnemyMadBomber() : base("madBomber") { } + + public EnemyMadBomber(Map.Map map, int posX, int posY) : base(map) + { + // abort spawn if the player already has the leaf + if (Game1.GameManager.SaveManager.GetString(_leafSaveKey) == "1") + { + IsDead = true; + return; + } + + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 15, 0); + EntitySize = new Rectangle(-8, -15, 16, 16); + + _spawnPosition = new Vector2(posX + 8, posY + 15); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/mad bomber"); + + _sprite = new CSprite(EntityPosition) { IsVisible = false }; + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-8, -15)); + + var body = new BodyComponent(EntityPosition, -7, -14, 14, 14, 8) + { + IgnoreHoles = true + }; + + var stateCooldown = new AiState(); + stateCooldown.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("hidden"), 1000, 1500)); + var stateHidden = new AiState(UpdateHidden); + var stateComing = new AiState(UpdateComing); + var stateLeaving = new AiState(UpdateLeaving); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("cooldown", stateCooldown); + _aiComponent.States.Add("hidden", stateHidden); + _aiComponent.States.Add("coming", stateComing); + _aiComponent.States.Add("leaving", stateLeaving); + _aiStunnedState = new AiStunnedState(_aiComponent, animationComponent, 3300, 900); + + _aiComponent.ChangeState("hidden"); + + _damageState = new AiDamageState(this, body, _aiComponent, _sprite, 4, false) + { + IsActive = false, + SpawnItems = false, + HitMultiplierX = 0, + HitMultiplierY = 0, + OnDeath = OnDeath + }; + + var damageBox = new CBox(EntityPosition, -7, -14, 0, 14, 14, 8); + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(body.BodyBox, OnHit)); + AddComponent(BodyComponent.Index, body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(body, _sprite, Values.LayerPlayer)); + } + + private void OnDeath(bool pieceofpower) + { + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + playerDirection *= 2.25f; + + // spawn the golden leaf jumping towards the player + var objLeaf = new ObjItem(Map, 0, 0, null, _leafSaveKey, "goldLeaf", null); + objLeaf.EntityPosition.Set(new Vector3(EntityPosition.X, EntityPosition.Y + 1, 1)); + objLeaf.SetVelocity(new Vector3(playerDirection.X, playerDirection.Y, 1.5f)); + objLeaf.Collectable = false; + Map.Objects.SpawnObject(objLeaf); + + _damageState.BaseOnDeath(pieceofpower); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_damageState.IsInDamageState()) + return Values.HitCollision.None; + + if (_aiComponent.CurrentStateId == "coming") + _wasHit = true; + + // stun state + if (damageType == HitType.Hookshot) + { + _damageState.SetDamageState(false); + + _aiStunnedState.StartStun(); + _animator.Pause(); + + return Values.HitCollision.Enemy; + } + + if (damageType == HitType.Bow || damageType == HitType.MagicRod) + damage = 1; + if (damageType == HitType.MagicPowder || damageType == HitType.Boomerang) + damage = 0; + + var hitReturn = _damageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + + // make sure to not disapear while moving out of the hole with piece of power active + if (_damageState.CurrentLives <= 0) + { + _animator.Pause(); + _damageState.HasDamageState = true; + } + + return hitReturn; + } + + private void ToCooldown() + { + _aiComponent.ChangeState("cooldown"); + _sprite.IsVisible = false; + } + + private void UpdateHidden() + { + // only spawn if the player is close enough + var playerDirection = MapManager.ObjLink.EntityPosition.Position - new Vector2(_spawnPosition.X, _spawnPosition.Y - 15); + if (playerDirection.Length() < 64) + ToComing(); + } + + private void ToComing() + { + // find a hole to come out + var tryCounter = 0; + while (tryCounter < 10) + { + tryCounter++; + + var randomNum = Game1.RandomNumber.Next(0, _holeOffsets.Length); + var holePosition = _spawnPosition + _holeOffsets[randomNum] * 16; + + // check the distance to not spawn next to the player + var direction = MapManager.ObjLink.EntityPosition.Position - holePosition; + if (direction.Length() > 48) + { + _aiComponent.ChangeState("coming"); + + EntityPosition.Set(holePosition); + + var playerOnTheRight = EntityPosition.X < MapManager.ObjLink.EntityPosition.X; + _animator.Play(playerOnTheRight ? "come_1" : "come_0"); + + _sprite.IsVisible = true; + _damageState.IsActive = true; + _damageField.IsActive = true; + _wasHit = false; + + return; + } + } + } + + private void UpdateComing() + { + // finished the enter animation + if (!_animator.IsPlaying) + { + if (!_wasHit) + ThrowBomb(); + + ToLeaving(); + } + } + + private void ToLeaving() + { + _aiComponent.ChangeState("leaving"); + _animator.Play("leave"); + _damageState.IsActive = false; + _damageField.IsActive = false; + } + + private void ThrowBomb() + { + var throwDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (throwDirection != Vector2.Zero) + throwDirection.Normalize(); + throwDirection *= 0.8f; + + // spawn a bomb + var bomb = new ObjBomb(Map, 0, 0, false, true); + bomb.EntityPosition.Set(new Vector3(EntityPosition.X, EntityPosition.Y + 1, 6)); + bomb.Body.Velocity = new Vector3(throwDirection.X, throwDirection.Y, 1.5f); + bomb.Body.Gravity = -0.1f; + bomb.Body.DragAir = 1.0f; + bomb.Body.Bounciness = 0.25f; + Map.Objects.SpawnObject(bomb); + + Game1.GameManager.PlaySoundEffect("D360-08-08"); + } + + private void UpdateLeaving() + { + if (!_animator.IsPlaying) + ToCooldown(); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyMaskMimic.cs b/InGame/GameObjects/Enemies/EnemyMaskMimic.cs new file mode 100644 index 0000000..1bda607 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyMaskMimic.cs @@ -0,0 +1,168 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyMaskMimic : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly AnimationComponent _animatorComponent; + private readonly AiDamageState _aiDamageState; + private readonly AiStunnedState _aiStunnedState; + + private readonly Rectangle _fieldRectangle; + + private Vector2 _lastPosition; + private int _direction; + private bool _wasColliding; + + public EnemyMaskMimic() : base("mask mimic") { } + + public EnemyMaskMimic(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/mask mimic"); + _animator.Play("walk"); + + var sprite = new CSprite(EntityPosition); + _animatorComponent = new AnimationComponent(_animator, sprite, Vector2.Zero); + + _fieldRectangle = map.GetField(posX, posY); + + _body = new BodyComponent(EntityPosition, -7, -12, 14, 12, 8) + { + Gravity = -0.075f, + DragAir = 1.0f, + AvoidTypes = Values.CollisionTypes.Hole | Values.CollisionTypes.NPCWall, + FieldRectangle = _fieldRectangle, + IsSlider = true, + MaxSlideDistance = 4.0f + }; + + _aiComponent = new AiComponent(); + + var stateUpdate = new AiState(Update); + + _aiComponent.States.Add("idle", stateUpdate); + _aiStunnedState = new AiStunnedState(_aiComponent, _animatorComponent, 3300, 900); + new AiFallState(_aiComponent, _body, null, null, 300); + _aiDamageState = new AiDamageState(this, _body, _aiComponent, sprite, 2); + _aiComponent.ChangeState("idle"); + + var damageBox = new CBox(EntityPosition, -7, -15, 2, 14, 15, 4); + var hittableBox = new CBox(EntityPosition, -7, -15, 2, 14, 15, 8); + var pushableBox = new CBox(EntityPosition, -7, -14, 2, 14, 14, 8); + + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, _animatorComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite)); + } + + private void Update() + { + var moved = false; + if (_fieldRectangle.Contains(MapManager.ObjLink.EntityPosition.Position)) + { + if (_wasColliding) + { + var direction = -MapManager.ObjLink.LastMoveVector; + var diff = (MapManager.ObjLink.EntityPosition.Position - _lastPosition) / Game1.TimeMultiplier; + + // this will stop the enemy if the player is walking into an obstacle + direction = new Vector2( + Math.Min(Math.Abs(direction.X), Math.Abs(diff.X)) * Math.Sign(direction.X), + Math.Min(Math.Abs(direction.Y), Math.Abs(diff.Y)) * Math.Sign(direction.Y)); + + _body.VelocityTarget = direction * 0.75f; + + if (direction.Length() > 0.01f) + { + moved = true; + + // deadzone to not have a fixed point where the direction gets changed + if (Math.Abs(direction.X) * ((_direction % 2 == 0) ? 1.1f : 1f) > + Math.Abs(direction.Y) * ((_direction % 2 != 0) ? 1.1f : 1f)) + _direction = direction.X < 0 ? 0 : 2; + else + _direction = direction.Y < 0 ? 1 : 3; + + if (_animator.CurrentAnimation.Id != "walk_" + _direction) + _animator.Play("walk_" + _direction); + else + _animator.Continue(); + } + } + + _wasColliding = true; + _lastPosition = MapManager.ObjLink.EntityPosition.Position; + } + else + { + _wasColliding = false; + _body.VelocityTarget = Vector2.Zero; + } + + if (!moved) + _animator.Pause(); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X, direction.Y, _body.Velocity.Z); + + return true; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (damageType == HitType.MagicPowder) + return Values.HitCollision.None; + + if (damageType == HitType.Bow) + damage = 1; + + if (damageType == HitType.Hookshot || damageType == HitType.Boomerang) + { + _aiStunnedState.StartStun(); + + _body.VelocityTarget = Vector2.Zero; + + _body.Velocity.X = direction.X * 5; + _body.Velocity.Y = direction.Y * 5; + + return Values.HitCollision.Enemy; + } + + // can be hit if the damage source is coming from the back + var dir = AnimationHelper.GetDirection(direction); + if (dir == _direction || + damageType == HitType.Bomb || + damageType == HitType.Bow || + damageType == HitType.MagicRod) + { + return _aiDamageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + } + + return Values.HitCollision.RepellingParticle | Values.HitCollision.Repelling1; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyMegaThwomp.cs b/InGame/GameObjects/Enemies/EnemyMegaThwomp.cs new file mode 100644 index 0000000..aded797 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyMegaThwomp.cs @@ -0,0 +1,91 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyMegaThwomp : GameObject + { + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly BodyComponent _body; + + public EnemyMegaThwomp() : base("mega thwomp") { } + + public EnemyMegaThwomp(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, -1, 32, 32); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/mega thwomp"); + _animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(0, 0)); + + _body = new BodyComponent(EntityPosition, 0, -1, 32, 32, 8) + { + MoveCollision = OnCollision, + Gravity2D = 0.15f, + IsActive = false + }; + + var stateIdle = new AiState(); + // short delay before starting to fall down + var statePreFalling = new AiState(); + statePreFalling.Trigger.Add(new AiTriggerCountdown(500, null, ToFalling)); + var stateFalling = new AiState(); + var stateFallen = new AiState(); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("preFalling", statePreFalling); + _aiComponent.States.Add("falling", stateFalling); + _aiComponent.States.Add("fallen", stateFallen); + _aiComponent.ChangeState("idle"); + + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(CollisionComponent.Index, new BodyCollisionComponent(_body, Values.CollisionTypes.Normal)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerBottom)); + } + + private void ToPreFalling() + { + _aiComponent.ChangeState("preFalling"); + _animator.Play("hit"); + } + + private void ToFalling() + { + _aiComponent.ChangeState("falling"); + _body.IsActive = true; + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + if (type == HitType.PegasusBootsPush && _aiComponent.CurrentStateId == "idle") + ToPreFalling(); + + return Values.HitCollision.None; + } + + private void OnCollision(Values.BodyCollision collision) + { + if ((collision & Values.BodyCollision.Bottom) != 0) + { + _body.IsActive = false; + Game1.GameManager.ShakeScreen(750, 1, 2, 2.5f, 6.5f); + Game1.GameManager.PlaySoundEffect("D378-12-0C"); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyMiniMoldorm.cs b/InGame/GameObjects/Enemies/EnemyMiniMoldorm.cs new file mode 100644 index 0000000..afb5a73 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyMiniMoldorm.cs @@ -0,0 +1,220 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyMiniMoldorm : GameObject + { + private readonly AiComponent _aiComp; + private readonly BodyComponent _bodyComp; + private readonly BodyDrawComponent _bodyDrawComp; + private readonly CSprite _sprite; + private readonly DictAtlasEntry _spriteHead0; + private readonly DictAtlasEntry _spriteHead1; + private readonly DictAtlasEntry _spritePart0; + private readonly DictAtlasEntry _spritePart1; + + private Vector2 _tailOnePosition; + private Vector2 _tailTwoPosition; + + private float _directionChangeMultiplier; + private float _direction; + private float _changeDirCount; + private int _dir = 1; + private const int SpriteOffsetY = 7; + + public EnemyMiniMoldorm(Map.Map map, int posX, int posY) : base(map, "miniMoldormHead0") + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 8 + SpriteOffsetY, 0); + EntitySize = new Rectangle(-20, -20 - SpriteOffsetY, 40, 40); + _tailOnePosition = EntityPosition.Position; + _tailTwoPosition = EntityPosition.Position; + + _spriteHead0 = Resources.GetSprite("miniMoldormHead0"); + _spriteHead1 = Resources.GetSprite("miniMoldormHead1"); + _spritePart0 = Resources.GetSprite("miniMoldormPart0"); + _spritePart1 = Resources.GetSprite("miniMoldormPart1"); + + _sprite = new CSprite("miniMoldormHead0", EntityPosition, new Vector2(0, -SpriteOffsetY)) { Center = new Vector2(8, 8) }; + + _bodyComp = new BodyComponent(EntityPosition, -5, -5 - SpriteOffsetY, 10, 10, 8) + { + MoveCollision = OnCollision, + HoleAbsorb = OnHoleAbsorb, + AbsorbPercentage = 1f, + Gravity = -0.1f, + DragAir = 1.0f, + AvoidTypes = Values.CollisionTypes.Hole | Values.CollisionTypes.NPCWall, + FieldRectangle = map.GetField(posX, posY) + }; + + _aiComp = new AiComponent(); + + var stateWalking = new AiState(Update); + _aiComp.States.Add("walking", stateWalking); + var damageState = new AiDamageState(this, _bodyComp, _aiComp, _sprite, 2, false) + { + FlameOffset = new Point(0, 10 - SpriteOffsetY), + UpdateLastStateFire = true + }; + + _aiComp.ChangeState("walking"); + + var damageBox = new CBox(EntityPosition, -6, -6 - SpriteOffsetY, 12, 12, 4); + var hittableBox = new CBox(EntityPosition, -6, -6 - SpriteOffsetY, 12, 12, 8); + + AddComponent(AiComponent.Index, _aiComp); + AddComponent(BodyComponent.Index, _bodyComp); + AddComponent(PushableComponent.Index, new PushableComponent(_bodyComp.BodyBox, OnPush)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, damageState.OnHit)); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + _bodyDrawComp = new BodyDrawComponent(_bodyComp, _sprite, Values.LayerPlayer); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + } + + private void UpdateHeadSprite(Vector2 direction) + { + // calculate the sprite used + //var direction = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + //direction.Normalize(); + //_direction = -(float)Math.Atan2(direction.Y, direction.X) + (float)Math.PI; + + var modRotation = (MathF.Abs(_direction)) % (MathF.PI / 2); + var sprite = MathF.PI / 8 < modRotation && modRotation < MathF.PI / 2 - MathF.PI / 8; + _sprite.SourceRectangle = sprite ? _spriteHead1.ScaledRectangle : _spriteHead0.ScaledRectangle; + + // rotation of the sprite + var dir = AnimationHelper.GetDirection(direction, MathF.PI * (9 / 8f)); + _sprite.Rotation = dir * (float)Math.PI / 2; + } + + private void Update() + { + _changeDirCount -= Game1.DeltaTime; + + if (_changeDirCount < 0) + ChangeDirection(); + + _direction += _dir * 0.04f * Game1.TimeMultiplier; + + if (_direction < 0) + _direction += (float)(Math.PI * 2); + + // move + var vecDirection = new Vector2((float)Math.Sin(_direction), (float)Math.Cos(_direction)); + _bodyComp.VelocityTarget = vecDirection * 0.75f; + + if (_aiComp.CurrentStateId == "burning") + _bodyComp.VelocityTarget = Vector2.Zero; + + _directionChangeMultiplier = AnimationHelper.MoveToTarget(_directionChangeMultiplier, 1, 0.025f * Game1.TimeMultiplier); + + UpdateHeadSprite(vecDirection); + + UpdateTailPositions(); + } + + private void Draw(SpriteBatch spriteBatch) + { + // change the draw effect + if (_sprite.SpriteShader != null) + { + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, _sprite.SpriteShader); + } + + // draw the tail + var partTwoRectangle = _spritePart1.ScaledRectangle; + var posTwo = _tailTwoPosition - new Vector2(partTwoRectangle.Width / 2f, partTwoRectangle.Height / 2f); + spriteBatch.Draw(Resources.SprEnemies, posTwo, partTwoRectangle, Color.White); + + var partOneRectangle = _spritePart0.ScaledRectangle; + var posOne = _tailOnePosition - new Vector2(partOneRectangle.Width / 2f, partOneRectangle.Height / 2f); + spriteBatch.Draw(Resources.SprEnemies, posOne, partOneRectangle, Color.White); + + // draw the head + _bodyDrawComp.Draw(spriteBatch); + + // change the draw effect + if (_sprite.SpriteShader != null) + { + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, null); + } + } + + private void UpdateTailPositions() + { + // first + var goalPosition = new Vector2(EntityPosition.X, EntityPosition.Y - SpriteOffsetY) - + new Vector2((float)Math.Sin(_direction), (float)Math.Cos(_direction)) * 1.0f; + var direction = _tailOnePosition - goalPosition; + var clampLength = MathHelper.Clamp(direction.Length(), 0, 5.5f); + + if (direction != Vector2.Zero) + direction.Normalize(); + _tailOnePosition = goalPosition + direction * clampLength; + + // second + direction = _tailTwoPosition - _tailOnePosition; + clampLength = MathHelper.Clamp(direction.Length(), 0, 6); + + if (direction != Vector2.Zero) + direction.Normalize(); + _tailTwoPosition = _tailOnePosition + direction * clampLength; + } + + private void OnCollision(Values.BodyCollision collision) + { + if (Game1.RandomNumber.Next(0, 2) == 0) + _dir = -_dir; + + if ((collision & Values.BodyCollision.Horizontal) != 0) + _direction = (float)Math.Atan2(-_bodyComp.VelocityTarget.X * _directionChangeMultiplier, _bodyComp.VelocityTarget.Y); + else if ((collision & Values.BodyCollision.Vertical) != 0) + _direction = (float)Math.Atan2(_bodyComp.VelocityTarget.X, -_bodyComp.VelocityTarget.Y * _directionChangeMultiplier); + + _directionChangeMultiplier *= 0.5f; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _bodyComp.Velocity = new Vector3(direction.X * 1.75f, direction.Y * 1.75f, _bodyComp.Velocity.Z); + + return true; + } + + private void ChangeDirection() + { + _changeDirCount = Game1.RandomNumber.Next(2000, 4500); + _dir = -_dir; + } + + private void OnHoleAbsorb() + { + // absorb the tail + _tailOnePosition = Vector2.Lerp(_tailOnePosition, new Vector2(EntityPosition.X, EntityPosition.Y - SpriteOffsetY), 0.15f * Game1.TimeMultiplier); + _tailTwoPosition = Vector2.Lerp(_tailTwoPosition, _tailOnePosition, 0.15f * Game1.TimeMultiplier); + + if ((new Vector2(EntityPosition.X, EntityPosition.Y - SpriteOffsetY) - _tailTwoPosition).Length() > 2) + return; + + Map.Objects.DeleteObjects.Add(this); + + var fallAnimation = new ObjAnimator(Map, (int)EntityPosition.X - 5, (int)EntityPosition.Y - 5 - SpriteOffsetY, Values.LayerBottom, "Particles/fall", "idle", true); + Map.Objects.SpawnObject(fallAnimation); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyMoblin.cs b/InGame/GameObjects/Enemies/EnemyMoblin.cs new file mode 100644 index 0000000..485ea42 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyMoblin.cs @@ -0,0 +1,164 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyMoblin : GameObject + { + private readonly Animator _animator; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + + private readonly Vector2[] _shotOffset = + { + new Vector2(-8, -1),new Vector2(0, -3), + new Vector2(8, -1),new Vector2(0, 2) + }; + + private float _moveSpeed = 0.5f; + private int _direction; + + public EnemyMoblin() : base("moblin") { } + + public EnemyMoblin(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/moblin"); + _animator.Play("walk_1"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -16)); + + _body = new BodyComponent(EntityPosition, -6, -10, 12, 10, 8) + { + MoveCollision = OnCollision, + CollisionTypes = Values.CollisionTypes.Normal | + Values.CollisionTypes.Enemy, + AvoidTypes = Values.CollisionTypes.Hole | Values.CollisionTypes.NPCWall, + FieldRectangle = map.GetField(posX, posY), + Bounciness = 0.25f, + Drag = 0.85f + }; + + var stateInit = new AiState(); + stateInit.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("walking"), 0, 500)); + var stateIdle = new AiState { Init = InitIdle }; + stateIdle.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("walking"), 300, 500)); + var stateWalking = new AiState { Init = InitWalking }; + stateWalking.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("idle"), 550, 850)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("init", stateInit); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("walking", stateWalking); + new AiFallState(_aiComponent, _body, OnHoleAbsorb); + var damageState = new AiDamageState(this, _body, _aiComponent, sprite, 2) { OnBurn = () => _animator.Pause() }; + _aiComponent.ChangeState("init"); + + // stand in a random direction + _direction = Game1.RandomNumber.Next(0, 4); + _animator.Play("stand_" + _direction); + + var damageBox = new CBox(EntityPosition, -8, -12, 0, 16, 12, 4); + var hittableBox = new CBox(EntityPosition, -7, -15, 14, 15, 8); + var pushableBox = new CBox(EntityPosition, -7, -11, 0, 14, 11, 4); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, damageState.OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + } + + private void InitIdle() + { + _animator.Play("stand_" + _direction); + _body.VelocityTarget = Vector2.Zero; + + ThrowSpear(); + } + + private void InitWalking() + { + ChangeDirection(); + } + + private void ChangeDirection() + { + // random new direction + _direction = Game1.RandomNumber.Next(0, 4); + _animator.Play("walk_" + _direction); + _body.VelocityTarget = AnimationHelper.DirectionOffset[_direction] * _moveSpeed; + } + + private void ThrowSpear() + { + if (Game1.RandomNumber.Next(0, 2) == 0) + return; + + // shoot if the player is in the range and in the right direction + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDirection.Length() < 96) + { + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + var direction = AnimationHelper.GetDirection(playerDirection); + + if (direction == _direction) + { + var box = Box.Empty; + // check for collision + if (!Map.Objects.Collision(new Box( + EntityPosition.X + _shotOffset[_direction].X - 4, + EntityPosition.Y + _shotOffset[_direction].Y - 4, 0, 8, 8, 8), + Box.Empty, Values.CollisionTypes.Normal, 0, _body.Level, ref box)) + { + // shoot + var shot = new EnemySpear(Map, new Vector3( + EntityPosition.X + _shotOffset[_direction].X, + EntityPosition.Y + _shotOffset[_direction].Y, 3), + AnimationHelper.DirectionOffset[_direction] * 2f); + Map.Objects.SpawnObject(shot); + } + } + } + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X, direction.Y, _body.Velocity.Z); + + return true; + } + + private void OnCollision(Values.BodyCollision direction) + { + if (_aiComponent.CurrentStateId != "walking") + return; + + // stop walking + _aiComponent.ChangeState("idle"); + } + + private void OnHoleAbsorb() + { + _animator.SpeedMultiplier = 3f; + _animator.Play("walk_" + _direction); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyMoblinPig.cs b/InGame/GameObjects/Enemies/EnemyMoblinPig.cs new file mode 100644 index 0000000..8bb347e --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyMoblinPig.cs @@ -0,0 +1,160 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyMoblinPig : GameObject + { + private readonly Animator _animator; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + + private readonly Vector2[] _shotOffset = + { + new Vector2(-8, -1),new Vector2(0, -3), + new Vector2(8, -1),new Vector2(0, 2) + }; + + private float _moveSpeed = 0.5f; + private int _direction; + + public EnemyMoblinPig() : base("moblinPig") { } + + public EnemyMoblinPig(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/moblinPig"); + _animator.Play("stand_3"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -16)); + + _body = new BodyComponent(EntityPosition, -6, -10, 12, 10, 8) + { + MoveCollision = OnCollision, + CollisionTypes = Values.CollisionTypes.Normal | + Values.CollisionTypes.Enemy, + AvoidTypes = Values.CollisionTypes.Hole | Values.CollisionTypes.NPCWall, + FieldRectangle = map.GetField(posX, posY), + Bounciness = 0.25f, + Drag = 0.85f + }; + + var stateInit = new AiState(); + stateInit.Trigger.Add(new AiTriggerCountdown(750, null, () => _aiComponent.ChangeState("walking"))); + var stateWalk = new AiState { Init = InitWalking }; + stateWalk.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("idle"), 550, 850)); + var stateIdle = new AiState { Init = InitIdle }; + stateIdle.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("walking"), 300, 500)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("init", stateInit); + _aiComponent.States.Add("walking", stateWalk); + _aiComponent.States.Add("idle", stateIdle); + new AiFallState(_aiComponent, _body, OnHoleAbsorb); + var damageState = new AiDamageState(this, _body, _aiComponent, sprite, 2) { OnBurn = () => _animator.Pause() }; + + // start in a waiting state changing to the walking state after a certain amount of time + _aiComponent.ChangeState("init"); + + var damageBox = new CBox(EntityPosition, -8, -12, 0, 16, 12, 4); + var hittableBox = new CBox(EntityPosition, -7, -15, 14, 15, 8); + var pushableBox = new CBox(EntityPosition, -7, -11, 0, 14, 11, 4); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, damageState.OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + } + + private void InitIdle() + { + _animator.Play("stand_" + _direction); + _body.VelocityTarget = Vector2.Zero; + + ThrowSpear(); + } + + private void InitWalking() + { + ChangeDirection(); + } + + private void ChangeDirection() + { + // random new direction + _direction = Game1.RandomNumber.Next(0, 4); + _animator.Play("walk_" + _direction); + _body.VelocityTarget = AnimationHelper.DirectionOffset[_direction] * _moveSpeed; + } + + private void ThrowSpear() + { + if (Game1.RandomNumber.Next(0, 2) == 0) + return; + + // shoot if the player is in the range and in the right direction + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDirection.Length() < 128) + { + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + var direction = AnimationHelper.GetDirection(playerDirection); + if (direction == _direction) + { + var box = Box.Empty; + if (!Map.Objects.Collision(new Box( + EntityPosition.X + _shotOffset[_direction].X - 4, + EntityPosition.Y + _shotOffset[_direction].Y - 4, 0, 8, 8, 8), + Box.Empty, Values.CollisionTypes.Normal, 0, _body.Level, ref box)) + { + // shoot + var shot = new EnemySpear(Map, new Vector3( + EntityPosition.X + _shotOffset[_direction].X, + EntityPosition.Y + _shotOffset[_direction].Y, 3), + AnimationHelper.DirectionOffset[_direction] * 2f); + Map.Objects.SpawnObject(shot); + } + } + } + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X, direction.Y, _body.Velocity.Z); + + return true; + } + + private void OnCollision(Values.BodyCollision direction) + { + if (_aiComponent.CurrentStateId != "walking") + return; + + // stop walking + _aiComponent.ChangeState("idle"); + } + + private void OnHoleAbsorb() + { + _animator.SpeedMultiplier = 3f; + _animator.Play("walk_" + _direction); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyMoblinPigSword.cs b/InGame/GameObjects/Enemies/EnemyMoblinPigSword.cs new file mode 100644 index 0000000..4bb9fde --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyMoblinPigSword.cs @@ -0,0 +1,254 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using Microsoft.Xna.Framework.Graphics; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyMoblinPigSword : GameObject + { + private readonly EnemyMoblinPigSwordSword _sword; + + public BodyComponent Body; + + private readonly CSprite _sprite; + private readonly Animator _animator; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _damageState; + private readonly BodyDrawComponent _drawComponent; + + private Rectangle _fieldRectangle; + + private const float MoveSpeed = 0.5f; + private const float AttackMoveSpeed = 0.55f; + private const int AttackRange = 80; + + private int _direction; + + private bool _isActive = true; + public override bool IsActive + { + set + { + _isActive = value; + _sword.IsActive = value; + } + get => _isActive; + } + + public EnemyMoblinPigSword() : base("moblinPigSword") { } + + public EnemyMoblinPigSword(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/moblinPig"); + _animator.Play("walk_1"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-8, -16)); + + _fieldRectangle = map.GetField(posX, posY); + + Body = new BodyComponent(EntityPosition, -6, -10, 12, 10, 8) + { + MoveCollision = OnCollision, + CollisionTypes = Values.CollisionTypes.Normal | + Values.CollisionTypes.Enemy, + AvoidTypes = Values.CollisionTypes.Hole | Values.CollisionTypes.NPCWall, + FieldRectangle = _fieldRectangle, + Bounciness = 0.25f, + AbsorbPercentage = 0.9f, + Drag = 0.85f + }; + + var stateIdle = new AiState { Init = InitIdle }; + stateIdle.Trigger.Add(new AiTriggerRandomTime(EndIdle, 300, 500)); + var stateWalk = new AiState { Init = InitWalking }; + stateWalk.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("idle"), 550, 850)); + var stateAttack = new AiState(UpdateAttack); + + _aiComponent = new AiComponent(); + _aiComponent.Trigger.Add(new AiTriggerUpdate(UpdateDamageTick)); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("walking", stateWalk); + _aiComponent.States.Add("attack", stateAttack); + new AiFallState(_aiComponent, Body, OnHoleAbsorb, OnAbsorbDeath); + _damageState = new AiDamageState(this, Body, _aiComponent, _sprite, 2) + { + OnDeath = OnDeath, + OnBurn = OnBurn + }; + + var damageBox = new CBox(EntityPosition, -8, -12, 0, 16, 12, 4); + var hittableBox = new CBox(EntityPosition, -4, -14, 8, 12, 8); + var pushableBox = new CBox(EntityPosition, -7, -11, 0, 14, 11, 4); + + _drawComponent = new BodyDrawComponent(Body, _sprite, Values.LayerPlayer); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, _damageState.OnHit)); + AddComponent(BodyComponent.Index, Body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(_sprite)); + + _sword = new EnemyMoblinPigSwordSword(Map, this); + } + + public override void Init() + { + // add the sword to the map + Map.Objects.SpawnObject(_sword); + + //var playerDirection = MapManager.ObjLink.NextMapPositionEnd.Value - EntityPosition.Position; + //if (playerDirection.Length() < AttackRange) + //{ + // _aiComponent.ChangeState("attack"); + // // make sure to update the animation to look at the player when he enters the goblin cave + // UpdateDirection(playerDirection); + //} + //else + { + // start randomly idle or walking facing a random direction + _direction = Game1.RandomNumber.Next(0, 4); + _aiComponent.ChangeState(Game1.RandomNumber.Next(0, 2) == 0 ? "walking" : "idle"); + } + } + + private void OnBurn() + { + _animator.Pause(); + _sword.Animator.Pause(); + } + + private void UpdateDamageTick() + { + _sword.Sprite.SpriteShader = _sprite.SpriteShader; + } + + private void OnDeath(bool pieceOfPower) + { + _damageState.BaseOnDeath(pieceOfPower); + + Map.Objects.DeleteObjects.Add(_sword); + } + + private void InitIdle() + { + Body.VelocityTarget = Vector2.Zero; + + _animator.Play("stand_" + _direction); + _sword.Animator.Play("stand_" + _direction); + } + + private void EndIdle() + { + var distance = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + + if (_fieldRectangle.Contains(MapManager.ObjLink.PosX, MapManager.ObjLink.PosY) && distance.Length() < AttackRange) + _aiComponent.ChangeState("attack"); + else + _aiComponent.ChangeState("walking"); + } + + private void InitWalking() + { + ChangeDirection(); + } + + private void ChangeDirection() + { + _animator.SpeedMultiplier = 0.5f; + _sword.Animator.SpeedMultiplier = 0.5f; + + // random new direction + _direction = Game1.RandomNumber.Next(0, 4); + _animator.Play("walk_" + _direction); + _sword.Animator.Play("walk_" + _direction); + Body.VelocityTarget = AnimationHelper.DirectionOffset[_direction] * MoveSpeed; + } + + private void UpdateAttack() + { + var playerDirection = (MapManager.ObjLink.EntityPosition.Position + AnimationHelper.DirectionOffset[_direction] * 3) - EntityPosition.Position; + + if (!_fieldRectangle.Contains(MapManager.ObjLink.PosX, MapManager.ObjLink.PosY) || + playerDirection.Length() > AttackRange) + { + _aiComponent.ChangeState("idle"); + return; + } + + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + + Body.VelocityTarget = playerDirection * AttackMoveSpeed; + + UpdateDirection(playerDirection); + + _animator.SpeedMultiplier = 1f; + _sword.Animator.SpeedMultiplier = 1f; + } + + private void UpdateDirection(Vector2 direction) + { + _direction = AnimationHelper.GetDirection(direction); + + _animator.Play("walk_" + _direction); + _sword.Animator.Play("walk_" + _direction); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + Body.Velocity = new Vector3(direction.X, direction.Y, Body.Velocity.Z); + + return true; + } + + private void OnCollision(Values.BodyCollision direction) + { + if (_aiComponent.CurrentStateId != "walking") + return; + + // stop walking + _aiComponent.ChangeState("idle"); + } + + private void OnHoleAbsorb() + { + _animator.Play("walk_" + _direction); + _sword.Animator.Play("walk_" + _direction); + + _animator.SpeedMultiplier = 3f; + _sword.Animator.SpeedMultiplier = 3f; + } + + private void OnAbsorbDeath() + { + Map.Objects.DeleteObjects.Add(_sword); + } + + private void Draw(SpriteBatch spriteBatch) + { + if (_direction == 1) + ((DrawComponent)_sword.Components[DrawComponent.Index]).Draw(spriteBatch); + + _drawComponent.Draw(spriteBatch); + + if (_direction != 1) + ((DrawComponent)_sword.Components[DrawComponent.Index]).Draw(spriteBatch); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyMoblinPigSwordSword.cs b/InGame/GameObjects/Enemies/EnemyMoblinPigSwordSword.cs new file mode 100644 index 0000000..4a345e0 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyMoblinPigSwordSword.cs @@ -0,0 +1,87 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyMoblinPigSwordSword : GameObject + { + public readonly Animator Animator; + public readonly CSprite Sprite; + + private readonly EnemyMoblinPigSword _owner; + private readonly CBox _collisionBox; + + private double _lastHitTime; + + public EnemyMoblinPigSwordSword(Map.Map map, EnemyMoblinPigSword owner) : base(map) + { + _owner = owner; + _owner.EntityPosition.AddPositionListener(typeof(EnemyMoblinSwordSword), PositionChange); + + EntityPosition = new CPosition(owner.EntityPosition.X, owner.EntityPosition.Y - 1, owner.EntityPosition.Z); + EntitySize = new Rectangle(-22, -8 - 24, 44, 48); + + Animator = AnimatorSaveLoad.LoadAnimator("Enemies/moblinPig sword"); + + Sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(Animator, Sprite, new Vector2(-8, -15)); + + _collisionBox = new CBox(0, 0, 0, 0, 0, 4); + UpdateCollisionBox(); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(_collisionBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(_collisionBox, OnHit)); + AddComponent(PushableComponent.Index, new PushableComponent(_collisionBox, OnPush) { RepelParticle = true }); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(Sprite, Values.LayerPlayer)); + } + + private void PositionChange(CPosition position) + { + EntityPosition.Set(new Vector2(position.X, position.Y - position.Z - 1)); + } + + private void Update() + { + UpdateCollisionBox(); + } + + private void UpdateCollisionBox() + { + _collisionBox.Box.X = EntityPosition.X - 8 + Animator.CollisionRectangle.X; + _collisionBox.Box.Y = EntityPosition.Y - 15 + Animator.CollisionRectangle.Y; + _collisionBox.Box.Width = Animator.CollisionRectangle.Width; + _collisionBox.Box.Height = Animator.CollisionRectangle.Height; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + { + _owner.Body.Velocity.X = direction.X * 1.5f; + _owner.Body.Velocity.Y = direction.Y * 1.5f; + } + + return true; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (damageType == HitType.MagicRod || damageType == HitType.MagicPowder || damageType == HitType.Bow || damageType == HitType.Hookshot || damageType == HitType.Boomerang || + (_lastHitTime != 0 && Game1.TotalGameTime - _lastHitTime < 250)) + return Values.HitCollision.None; + + _lastHitTime = Game1.TotalGameTime; + + _owner.Body.Velocity.X = direction.X * 1.5f; + _owner.Body.Velocity.Y = direction.Y * 1.5f; + + return Values.HitCollision.RepellingParticle; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyMoblinSword.cs b/InGame/GameObjects/Enemies/EnemyMoblinSword.cs new file mode 100644 index 0000000..0772e98 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyMoblinSword.cs @@ -0,0 +1,235 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyMoblinSword : GameObject + { + public BodyComponent Body; + + private readonly CSprite _sprite; + private readonly EnemyMoblinSwordSword _sword; + private readonly Animator _animator; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _damageState; + + private Rectangle _fieldRectangle; + + private const float MoveSpeed = 0.5f; + private const float AttackMoveSpeed = 0.55f; + private const int AttackRange = 80; + + private int _direction; + + private bool _isActive = true; + public override bool IsActive + { + set + { + _isActive = value; + _sword.IsActive = value; + } + get => _isActive; + } + + public EnemyMoblinSword() : base("moblin sword") { } + + public EnemyMoblinSword(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/moblin sword"); + _animator.Play("walk_1"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-8, -16)); + + _fieldRectangle = map.GetField(posX, posY); + + Body = new BodyComponent(EntityPosition, -6, -10, 12, 10, 8) + { + MoveCollision = OnCollision, + CollisionTypes = Values.CollisionTypes.Normal | + Values.CollisionTypes.Enemy, + AvoidTypes = Values.CollisionTypes.Hole | Values.CollisionTypes.NPCWall, + FieldRectangle = _fieldRectangle, + Bounciness = 0.25f, + AbsorbPercentage = 0.9f, + Drag = 0.85f + }; + + var stateIdle = new AiState { Init = InitIdle }; + stateIdle.Trigger.Add(new AiTriggerRandomTime(EndIdle, 300, 500)); + var stateWalk = new AiState { Init = InitWalking }; + stateWalk.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("idle"), 550, 850)); + var stateAttack = new AiState(UpdateAttack); + + _aiComponent = new AiComponent(); + _aiComponent.Trigger.Add(new AiTriggerUpdate(UpdateDamageTick)); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("walking", stateWalk); + _aiComponent.States.Add("attack", stateAttack); + new AiFallState(_aiComponent, Body, OnHoleAbsorb, OnAbsorbDeath); + _damageState = new AiDamageState(this, Body, _aiComponent, _sprite, 2) + { + OnDeath = OnDeath, + OnBurn = OnBurn + }; + + var damageBox = new CBox(EntityPosition, -8, -12, 0, 16, 12, 4); + var hittableBox = new CBox(EntityPosition, -7, -15, 14, 15, 8); + var pushableBox = new CBox(EntityPosition, -7, -11, 0, 14, 11, 4); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, _damageState.OnHit)); + AddComponent(BodyComponent.Index, Body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(Body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(_sprite)); + + _sword = new EnemyMoblinSwordSword(Map, this); + } + + public override void Init() + { + // add the sword to the map + Map.Objects.SpawnObject(_sword); + + // make sure to update the animation to look at the player when he enters the goblin cave + var playerDirection = MapManager.ObjLink.NextMapPositionEnd.Value - EntityPosition.Position; + if (playerDirection.Length() < AttackRange) + { + _aiComponent.ChangeState("attack"); + UpdateDirection(playerDirection); + } + else + { + // start randomly idle or walking facing a random direction + _direction = Game1.RandomNumber.Next(0, 4); + _aiComponent.ChangeState(Game1.RandomNumber.Next(0, 2) == 0 ? "walking" : "idle"); + } + } + + private void OnBurn() + { + _animator.Pause(); + _sword.Animator.Pause(); + } + + private void UpdateDamageTick() + { + _sword.Sprite.SpriteShader = _sprite.SpriteShader; + } + + private void OnDeath(bool pieceOfPower) + { + _damageState.BaseOnDeath(pieceOfPower); + + Map.Objects.DeleteObjects.Add(_sword); + } + + private void InitIdle() + { + Body.VelocityTarget = Vector2.Zero; + + _animator.Play("stand_" + _direction); + _sword.Animator.Play("stand_" + _direction); + } + + private void EndIdle() + { + var distance = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + + if (_fieldRectangle.Contains(MapManager.ObjLink.PosX, MapManager.ObjLink.PosY) && distance.Length() < AttackRange) + _aiComponent.ChangeState("attack"); + else + _aiComponent.ChangeState("walking"); + } + + private void InitWalking() + { + ChangeDirection(); + } + + private void ChangeDirection() + { + // random new direction + _direction = Game1.RandomNumber.Next(0, 4); + _animator.Play("walk_" + _direction); + _sword.Animator.Play("walk_" + _direction); + Body.VelocityTarget = AnimationHelper.DirectionOffset[_direction] * MoveSpeed; + } + + private void UpdateAttack() + { + var playerDirection = (MapManager.ObjLink.EntityPosition.Position + AnimationHelper.DirectionOffset[_direction] * 3) - EntityPosition.Position; + + if (!_fieldRectangle.Contains(MapManager.ObjLink.PosX, MapManager.ObjLink.PosY) || + playerDirection.Length() > AttackRange) + { + _aiComponent.ChangeState("idle"); + return; + } + + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + + Body.VelocityTarget = playerDirection * AttackMoveSpeed; + + UpdateDirection(playerDirection); + + _animator.SpeedMultiplier = 2f; + _sword.Animator.SpeedMultiplier = 2f; + } + + private void UpdateDirection(Vector2 direction) + { + _direction = AnimationHelper.GetDirection(direction); + + _animator.Play("walk_" + _direction); + _sword.Animator.Play("walk_" + _direction); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + Body.Velocity = new Vector3(direction.X, direction.Y, Body.Velocity.Z); + + return true; + } + + private void OnCollision(Values.BodyCollision direction) + { + if (_aiComponent.CurrentStateId != "walking") + return; + + // stop walking + _aiComponent.ChangeState("idle"); + } + + private void OnHoleAbsorb() + { + _animator.Play("walk_" + _direction); + _sword.Animator.Play("walk_" + _direction); + + _animator.SpeedMultiplier = 3f; + _sword.Animator.SpeedMultiplier = 3f; + } + + private void OnAbsorbDeath() + { + Map.Objects.DeleteObjects.Add(_sword); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyMoblinSwordSword.cs b/InGame/GameObjects/Enemies/EnemyMoblinSwordSword.cs new file mode 100644 index 0000000..89fc10f --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyMoblinSwordSword.cs @@ -0,0 +1,87 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyMoblinSwordSword : GameObject + { + public readonly Animator Animator; + public readonly CSprite Sprite; + + private readonly EnemyMoblinSword _owner; + private readonly CBox _collisionBox; + + private double _lastHitTime; + + public EnemyMoblinSwordSword(Map.Map map, EnemyMoblinSword owner) : base(map) + { + _owner = owner; + _owner.EntityPosition.AddPositionListener(typeof(EnemyMoblinSwordSword), PositionChange); + + EntityPosition = new CPosition(owner.EntityPosition.X, owner.EntityPosition.Y - 1, owner.EntityPosition.Z); + EntitySize = new Rectangle(-22, -8 - 24, 44, 48); + + Animator = AnimatorSaveLoad.LoadAnimator("Enemies/moblin sword sword"); + + Sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(Animator, Sprite, new Vector2(-8, -15)); + + _collisionBox = new CBox(0, 0, 0, 0, 0, 4); + UpdateCollisionBox(); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(_collisionBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(_collisionBox, OnHit)); + AddComponent(PushableComponent.Index, new PushableComponent(_collisionBox, OnPush) { RepelParticle = true }); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(Sprite, Values.LayerPlayer)); + } + + private void PositionChange(CPosition position) + { + EntityPosition.Set(new Vector2(position.X, position.Y - position.Z - 1)); + } + + private void Update() + { + UpdateCollisionBox(); + } + + private void UpdateCollisionBox() + { + _collisionBox.Box.X = EntityPosition.X - 8 + Animator.CollisionRectangle.X; + _collisionBox.Box.Y = EntityPosition.Y - 15 + Animator.CollisionRectangle.Y; + _collisionBox.Box.Width = Animator.CollisionRectangle.Width; + _collisionBox.Box.Height = Animator.CollisionRectangle.Height; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + { + _owner.Body.Velocity.X = direction.X * 1.5f; + _owner.Body.Velocity.Y = direction.Y * 1.5f; + } + + return true; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (damageType == HitType.MagicRod || damageType == HitType.MagicPowder || damageType == HitType.Bow || damageType == HitType.Hookshot || damageType == HitType.Boomerang || + (_lastHitTime != 0 && Game1.TotalGameTime - _lastHitTime < 250)) + return Values.HitCollision.None; + + _lastHitTime = Game1.TotalGameTime; + + _owner.Body.Velocity.X = direction.X * 1.5f; + _owner.Body.Velocity.Y = direction.Y * 1.5f; + + return Values.HitCollision.RepellingParticle; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyMonkey.cs b/InGame/GameObjects/Enemies/EnemyMonkey.cs new file mode 100644 index 0000000..f08b83f --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyMonkey.cs @@ -0,0 +1,188 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyMonkey : GameObject + { + private readonly CSprite _sprite; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + + private const int FadeTime = 125; + private float _fleeCounter = 1500; + private int _throwState; + private int _bombCountdown = 5; + + private bool _fleeing; + + public EnemyMonkey() : base("monkey enemy") { } + + public EnemyMonkey(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 33, 17); + EntitySize = new Rectangle(-16, -38, 32, 38); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/monkey"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -8, -16, 16, 16, 8) + { + IgnoresZ = true, + DragAir = 1, + Gravity = -0.125f, + CollisionTypes = Values.CollisionTypes.None + }; + + var stateIdle = new AiState { Init = InitIdle }; + stateIdle.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("throwL"), 1000, 1500)); + var stateThrowL = new AiState { Init = InitThrow }; + stateThrowL.Trigger.Add(new AiTriggerCountdown(666, null, () => _aiComponent.ChangeState("throwR"))); + var stateThrowR = new AiState { Init = InitThrow }; + stateThrowR.Trigger.Add(new AiTriggerCountdown(666, null, () => _aiComponent.ChangeState("idle"))); + var stateFall = new AiState(UpdateFall) { Init = InitFall }; + var stateJump = new AiState(UpdateJump) { Init = InitJump }; + var stateFlee = new AiState(UpdateFlee); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("throwL", stateThrowL); + _aiComponent.States.Add("throwR", stateThrowR); + _aiComponent.States.Add("fall", stateFall); + _aiComponent.States.Add("jump", stateJump); + _aiComponent.States.Add("flee", stateFlee); + _aiComponent.ChangeState("idle"); + + var hitBox = new CBox(posX - 8, posY, 0, 32, 32, 8); + + AddComponent(HittableComponent.Index, new HittableComponent(hitBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _sprite)); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (!_fleeing && (damageType & HitType.PegasusBootsPush) != 0) + { + _fleeing = true; + _body.IgnoresZ = false; + _body.IsGrounded = false; + _body.Velocity = new Vector3(direction.X * 0.35f, 0.75f, 1.75f); + _aiComponent.ChangeState("fall"); + } + + return Values.HitCollision.None; + } + + private void InitIdle() + { + _animator.Play("idle"); + } + + private void InitThrow() + { + // is the player close enough? + var direction = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (direction.Y < -32 || Math.Abs(direction.X) > 64 || direction.Length() > 128) + { + _aiComponent.ChangeState("idle"); + return; + } + + Game1.GameManager.PlaySoundEffect("D360-08-08"); + + _body.VelocityTarget = new Vector2(0, 0); + + _animator.Play("throw" + (_throwState == 0 ? "l" : "r")); + _throwState = (_throwState + 1) % 2; + + var throwDirection = new Vector3(_throwState == 0 ? 0.5f : -0.5f, 0.75f, 1.75f); + _bombCountdown--; + + if (_bombCountdown >= 0) + { + // spawn a nut + Map.Objects.SpawnObject(new EnemyNut(Map, new Vector3(EntityPosition.X, EntityPosition.Y, 20), throwDirection)); + } + else + { + // spawn a bomb + var bomb = new ObjBomb(Map, 0, 0, false, true); + bomb.EntityPosition.Set(new Vector3(EntityPosition.X, EntityPosition.Y, 20)); + bomb.Body.Velocity = throwDirection; + bomb.Body.Gravity = -0.1f; + bomb.Body.DragAir = 1.0f; + bomb.Body.Bounciness = 0.25f; + Map.Objects.SpawnObject(bomb); + + _bombCountdown = Game1.RandomNumber.Next(10, 16); + } + } + + private void InitFall() + { + _animator.Play("fall"); + } + + private void UpdateFall() + { + if (_body.IsGrounded) + _aiComponent.ChangeState("jump"); + } + + private void InitJump() + { + _animator.Play("idle"); + + _body.IsGrounded = false; + _body.Velocity = new Vector3(0, 0, 2.0f); + + Game1.GameManager.PlaySoundEffect("D370-20-14"); + } + + private void UpdateJump() + { + if (_body.IsGrounded) + _aiComponent.ChangeState("flee"); + } + + private void UpdateFlee() + { + _fleeCounter -= Game1.DeltaTime; + _sprite.Color = Color.White * Math.Clamp(_fleeCounter / FadeTime, 0, 1); + if (_fleeCounter <= 0) + { + Map.Objects.DeleteObjects.Add(this); + return; + } + + if (_body.IsGrounded) + { + var direction = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + if (direction != Vector2.Zero) + direction.Normalize(); + + // jump away from the player + _body.Velocity = new Vector3(direction.X * 1.25f, direction.Y * 1.25f, 1.25f); + + Game1.GameManager.PlaySoundEffect("D370-20-14"); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyNut.cs b/InGame/GameObjects/Enemies/EnemyNut.cs new file mode 100644 index 0000000..eb95a7c --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyNut.cs @@ -0,0 +1,106 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + class EnemyNut : GameObject + { + private readonly BodyComponent _body; + private readonly CSprite _sprite; + + private int _collisionCount; + private bool _wasHit; + + public EnemyNut(Map.Map map, Vector3 position, Vector3 direction) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(position.X, position.Y, position.Z); + EntitySize = new Rectangle(-6, -48, 12, 48); + + _sprite = new CSprite(Resources.SprEnemies, EntityPosition, new Rectangle(306, 2, 12, 12), new Vector2(-6, -12)); + + _body = new BodyComponent(EntityPosition, -6, -12, 12, 12, 8) + { + MoveCollision = MoveCollision, + CollisionTypes = Values.CollisionTypes.None, + Gravity = -0.1f, + DragAir = 1.0f, + Bounciness = 0.75f + }; + _body.Velocity = direction; + + var hitBox = new CBox(EntityPosition, -5, -11, 0, 10, 10, 10, true); + AddComponent(PushableComponent.Index, new PushableComponent(hitBox, OnPush)); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(hitBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hitBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerPlayer)); + + var shadow = new DrawShadowSpriteComponent(Resources.SprShadow, EntityPosition, new Rectangle(0, 0, 65, 66), new Vector2(-6, -6), 12, 6); + AddComponent(DrawShadowComponent.Index, shadow); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X * 1.75f, direction.Y * 1.75f, _body.Velocity.Z); + + return true; + } + + private void MoveCollision(Values.BodyCollision collisionType) + { + _collisionCount++; + + if (_collisionCount > 3 || _wasHit) + { + // spawn explosion effect + if (_wasHit) + { + Game1.GameManager.PlaySoundEffect("D360-03-03"); + Map.Objects.SpawnObject(new ObjAnimator(Map, (int)EntityPosition.X - 12, + (int)EntityPosition.Y - 12, Values.LayerTop, "Particles/explosion0", "run", true)); + + if (Game1.RandomNumber.Next(0, 2) == 0) + { + var objItem = new ObjItem(Map, (int)EntityPosition.X - 8, (int)EntityPosition.Y - 8, "j", "", "ruby", "", true); + objItem.SetSpawnDelay(250); + Map.Objects.SpawnObject(objItem); + } + } + + Map.Objects.DeleteObjects.Add(this); + return; + } + + if (!_wasHit) + Game1.GameManager.PlaySoundEffect("D360-09-09"); + + // set a new random direction + var angle = (Game1.RandomNumber.Next(0, 100) / 100f) * (float)Math.PI * 2f; + _body.Velocity = new Vector3((float)Math.Sin(angle), (float)Math.Cos(angle), _body.Velocity.Z); + + // flip the sprite + _sprite.SpriteEffect ^= SpriteEffects.FlipHorizontally; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_wasHit) + return Values.HitCollision.None; + + _body.Velocity = new Vector3(direction.X, direction.Y, 0.1f) * 3.5f; + EntityPosition.Set(new Vector3(EntityPosition.X, EntityPosition.Y - EntityPosition.Z, 0)); + _wasHit = true; + + return Values.HitCollision.Enemy; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyOctorok.cs b/InGame/GameObjects/Enemies/EnemyOctorok.cs new file mode 100644 index 0000000..7bea38a --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyOctorok.cs @@ -0,0 +1,154 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyOctorok : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + + private readonly Vector2[] _shotOffset = + { + new Vector2(-8, -1),new Vector2(0, -6), + new Vector2(8, -1),new Vector2(0, 11) + }; + + private float _walkSpeed = 0.5f; + private int _direction; + + public EnemyOctorok() : base("octorok") { } + + public EnemyOctorok(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 12, 0); + EntitySize = new Rectangle(-8, -15, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/octorok"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -15)); + + _body = new BodyComponent(EntityPosition, -7, -12, 14, 12, 8) + { + MoveCollision = OnCollision, + AbsorbPercentage = 0.9f, + CollisionTypes = + Values.CollisionTypes.Normal | + Values.CollisionTypes.Enemy | + Values.CollisionTypes.Player, + AvoidTypes = + Values.CollisionTypes.Hole | + Values.CollisionTypes.NPCWall, + FieldRectangle = map.GetField(posX, posY), + Bounciness = 0.25f, + Drag = 0.85f, + }; + + var walkingState = new AiState { Init = ToWalking }; + walkingState.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("idle"), 750, 1000)); + var idleState = new AiState { Init = ToIdle }; + idleState.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("walking"), 250, 500)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("walking", walkingState); + _aiComponent.States.Add("idle", idleState); + new AiFallState(_aiComponent, _body, OnHoleAbsorb, null); + _aiComponent.ChangeState("walking"); + + var damageState = new AiDamageState(this, _body, _aiComponent, sprite, 1) { OnBurn = OnBurn }; + var damageBox = new CBox(EntityPosition, -8, -13, 0, 16, 13, 4); + var hittableBox = new CBox(EntityPosition, -7, -15, 0, 14, 15, 8); + var pushableBox = new CBox(EntityPosition, -7, -13, 0, 14, 13, 4); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, damageState.OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite) { Height = 1.0f, Rotation = 0.1f }); + } + + public override void Init() + { + base.Init(); + + if (!IsActive) + return; + + // random start position/state + _direction = Game1.RandomNumber.Next(0, 4); + _animator.Play("walk_" + _direction); + _aiComponent.ChangeState(Game1.RandomNumber.Next(0, 2) == 0 ? "idle" : "walking"); + } + + private void ToIdle() + { + _animator.Play("stand_" + _direction); + _body.VelocityTarget = new Vector2(0, 0); + + // shoot if the player is in the range and in the right direction + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDirection.Length() < 80) + { + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + var direction = AnimationHelper.GetDirection(playerDirection); + + if (direction == _direction) + { + // shoot + var shot = new EnemyOctorokShot(Map, + EntityPosition.X + _shotOffset[_direction].X, + EntityPosition.Y + _shotOffset[_direction].Y, + AnimationHelper.DirectionOffset[_direction] * 2f); + Map.Objects.SpawnObject(shot); + } + } + } + + private void ToWalking() + { + // random new direction + _direction = Game1.RandomNumber.Next(0, 4); + _animator.Play("walk_" + _direction); + _body.VelocityTarget = AnimationHelper.DirectionOffset[_direction] * _walkSpeed; + } + + private void OnBurn() + { + _animator.Pause(); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X * 1.75f, direction.Y * 1.75f, _body.Velocity.Z); + + return true; + } + + private void OnCollision(Values.BodyCollision direction) + { + if (_aiComponent.CurrentStateId == "walking") + _aiComponent.ChangeState("idle"); + } + + private void OnHoleAbsorb() + { + _animator.SpeedMultiplier = 3f; + _animator.Play("walk_" + _direction); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyOctorokShot.cs b/InGame/GameObjects/Enemies/EnemyOctorokShot.cs new file mode 100644 index 0000000..22145fa --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyOctorokShot.cs @@ -0,0 +1,172 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyOctorokShot : GameObject + { + private readonly AiComponent _aiComponent; + private readonly ShadowBodyDrawComponent _shadowBody; + private readonly DamageFieldComponent _damageField; + private readonly CSprite _drawComponent; + private readonly BodyComponent _body; + private readonly PushableComponent _pushableComponent; + + private float _lifeCounter = 950; + private float _despawnPercentage = 1; + private int _despawnTime = 750; + private bool _repelledPlayer; + + public EnemyOctorokShot(Map.Map map, float posX, float posY, Vector2 velocity) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX, posY, 2); + EntitySize = new Rectangle(-5, -12, 10, 12); + + // abort spawn in a wall + var box = Box.Empty; + if (Map.Objects.Collision(new Box(EntityPosition.X - 4, EntityPosition.Y - 8, 0, 8, 8, 8), + Box.Empty, Values.CollisionTypes.Normal, 0, 0, ref box)) + { + IsDead = true; + return; + } + + var animator = AnimatorSaveLoad.LoadAnimator("Enemies/octorok shot"); + animator.Play("idle"); + + _drawComponent = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(animator, _drawComponent, new Vector2(-5, -10)); + + _body = new BodyComponent(EntityPosition, -4, -8, 8, 8, 8) + { + CollisionTypes = Values.CollisionTypes.Normal, + MoveCollision = OnCollision, + VelocityTarget = velocity, + Bounciness = 0.35f, + Drag = 0.75f, + IgnoreHeight = true, + IgnoresZ = true, + IgnoreInsideCollision = false, + }; + + var stateIdle = new AiState(UpdateIdle); + var stateDespawn = new AiState() { Init = InitDespawn }; + stateDespawn.Trigger.Add(new AiTriggerCountdown(_despawnTime, Despawn, () => Despawn(0))); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("despawn", stateDespawn); + _aiComponent.ChangeState("idle"); + + var damageCollider = new CBox(EntityPosition, -5, -10, 0, 10, 10, 4); + + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageCollider, HitType.Enemy, 2) { OnDamage = OnDamage }); + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(PushableComponent.Index, _pushableComponent = new PushableComponent(_body.BodyBox, OnPush) { RepelMultiplier = 0.35f }); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _drawComponent, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, _shadowBody = new ShadowBodyDrawComponent(EntityPosition)); + } + + private void InitDespawn() + { + _pushableComponent.IsActive = false; + _body.IgnoresZ = false; + _damageField.IsActive = false; + Game1.GameManager.PlaySoundEffect("D360-07-07"); + } + + private void UpdateIdle() + { + _lifeCounter -= Game1.DeltaTime; + if (_lifeCounter < 0) + { + _body.IsGrounded = false; + _body.IgnoresZ = false; + _body.Gravity = -0.125f; + _body.Bounciness = 0.75f; + _body.Drag = 0.9f; + _body.Velocity = new Vector3(_body.VelocityTarget.X, _body.VelocityTarget.Y, 0); + _body.VelocityTarget = Vector2.Zero; + _aiComponent.ChangeState("despawn"); + } + } + + private void Despawn(double time) + { + _despawnPercentage = (float)(time / (_despawnTime / 3)); + if (_despawnPercentage > 1) + _despawnPercentage = 1; + + _drawComponent.Color = Color.White * _despawnPercentage; + _shadowBody.Transparency = _despawnPercentage; + + if (time <= 0) + Map.Objects.DeleteObjects.Add(this); + } + + private bool OnDamage() + { + _aiComponent.ChangeState("despawn"); + _body.Velocity = new Vector3(-_body.VelocityTarget.X * 0.25f, -_body.VelocityTarget.Y * 0.25f, 1.5f); + _body.VelocityTarget = Vector2.Zero; + + return _damageField.DamagePlayer(); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (_aiComponent.CurrentStateId != "despawn") + _aiComponent.ChangeState("despawn"); + else if (_repelledPlayer) + return false; + else + { + // it is possible that we despawn because of OnDamage in the same frame + // we need to make sure to still repell the player + _repelledPlayer = true; + return _repelledPlayer; + } + + _body.Velocity = new Vector3(direction.X * 0.25f, direction.Y * 0.25f, 1.5f); + _body.VelocityTarget = Vector2.Zero; + + return true; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_aiComponent.CurrentStateId != "despawn") + _aiComponent.ChangeState("despawn"); + else + return Values.HitCollision.None; + + _body.Velocity = new Vector3(direction.X, direction.Y, 1.5f); + _body.VelocityTarget = Vector2.Zero; + + return Values.HitCollision.Enemy; + } + + private void OnCollision(Values.BodyCollision direction) + { + if (direction == Values.BodyCollision.Floor) + return; + + if (_aiComponent.CurrentStateId != "despawn") + _aiComponent.ChangeState("despawn"); + + _body.Velocity = new Vector3(-_body.VelocityTarget.X * 0.25f, -_body.VelocityTarget.Y * 0.25f, 1.5f); + _body.VelocityTarget = Vector2.Zero; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyOctorokWinged.cs b/InGame/GameObjects/Enemies/EnemyOctorokWinged.cs new file mode 100644 index 0000000..11e2fdc --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyOctorokWinged.cs @@ -0,0 +1,233 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyOctorokWinged : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly AiDamageState _aiDamageState; + private readonly BodyDrawComponent _bodyDrawComponent; + private readonly AiTriggerSwitch _damageSwitch; + + private readonly Rectangle _wingRectangle = new Rectangle(160, 67, 8, 18); + + private readonly Vector2[] _shotOffset = + { + new Vector2(-8, -1),new Vector2(0, -6), + new Vector2(8, -1),new Vector2(0, 11) + }; + + private readonly Rectangle _fieldRectangle; + + private float _walkSpeed = 0.5f; + private int _direction; + private float _flyCounter; + + public EnemyOctorokWinged() : base("winged octorok") { } + + public EnemyOctorokWinged(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 15, 0); + EntitySize = new Rectangle(-8, -15 - 16, 16, 32); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/octorok"); + _fieldRectangle = map.GetField(posX, posY); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -15)); + + _body = new BodyComponent(EntityPosition, -7, -12, 14, 12, 8) + { + MoveCollision = OnCollision, + AbsorbPercentage = 0.9f, + CollisionTypes = + Values.CollisionTypes.Normal | + Values.CollisionTypes.Enemy, + AvoidTypes = Values.CollisionTypes.Hole | + Values.CollisionTypes.NPCWall, + FieldRectangle = _fieldRectangle, + Bounciness = 0.25f, + Drag = 0.85f, + Gravity = -0.04f, + }; + + var stateIdle = new AiState { Init = InitIdle }; + stateIdle.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("walking"), 250, 500)); + var stateWalking = new AiState { Init = InitWalking }; + stateWalking.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("idle"), 750, 1000)); + var stateFlying = new AiState(UpdateFlying) { Init = InitFlying }; + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("walking", stateWalking); + _aiComponent.States.Add("flying", stateFlying); + _aiDamageState = new AiDamageState(this, _body, _aiComponent, sprite, 1) { OnBurn = () => _animator.Pause() }; + _aiComponent.Trigger.Add(_damageSwitch = new AiTriggerSwitch(350)); + new AiFallState(_aiComponent, _body, OnHoleAbsorb); + + // random start position/state + _direction = Game1.RandomNumber.Next(0, 4); + _animator.Play("walk_" + _direction); + _aiComponent.ChangeState(Game1.RandomNumber.Next(0, 2) == 0 ? "idle" : "walking"); + + var damageCollider = new CBox(EntityPosition, -8, -13, 4, 16, 13, 4); + var hittableBox = new CBox(EntityPosition, -7, -15, 0, 14, 15, 8, true); + var pushableBox = new CBox(EntityPosition, -7, -13, 0, 14, 13, 4, true); + + _bodyDrawComponent = new BodyDrawComponent(_body, sprite, Values.LayerPlayer); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite) { Height = 1.0f, Rotation = 0.1f, ShadowWidth = 10, ShadowHeight = 5 }); + } + + private void InitIdle() + { + _animator.Play("stand_" + _direction); + _body.VelocityTarget = new Vector2(0, 0); + + // shoot if the player is in the range and in the right direction + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDirection.Length() < 80) + { + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + var direction = AnimationHelper.GetDirection(playerDirection); + + if (direction == _direction) + { + // shoot + var shot = new EnemyOctorokShot(Map, + EntityPosition.X + _shotOffset[_direction].X, + EntityPosition.Y + _shotOffset[_direction].Y, + AnimationHelper.DirectionOffset[_direction] * 2f); + Map.Objects.SpawnObject(shot); + } + } + } + + private void InitWalking() + { + // random new direction + _direction = Game1.RandomNumber.Next(0, 4); + _animator.Play("walk_" + _direction); + _body.VelocityTarget = AnimationHelper.DirectionOffset[_direction] * _walkSpeed; + } + + //private void UpdateWalking() + //{ + // _aiComponent.ChangeState("flying"); + + // _body.VelocityTarget = Vector2.Zero; + //} + + private void InitFlying() + { + // fly towards the player + var vecDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + vecDirection.Normalize(); + + _body.VelocityTarget = vecDirection; + _body.Velocity.Z = 1.25f; + _body.AvoidTypes = Values.CollisionTypes.NPCWall; + _body.FieldRectangle = RectangleF.Empty; + } + + private void UpdateFlying() + { + _flyCounter += Game1.DeltaTime; + + // face the player + var vecDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + _direction = AnimationHelper.GetDirection(vecDirection); + _animator.Play("walk_" + _direction); + + if (_body.IsGrounded && _body.Velocity.Z <= 0) + { + _flyCounter = 0; + _aiComponent.ChangeState("idle"); + _damageSwitch.Reset(); + _body.AvoidTypes = Values.CollisionTypes.Hole | + Values.CollisionTypes.NPCWall; + _body.FieldRectangle = _fieldRectangle; + } + } + + private void Draw(SpriteBatch spriteBatch) + { + // draw the wings + spriteBatch.Draw(Resources.SprEnemies, new Vector2(EntityPosition.X - _wingRectangle.Width - 5, EntityPosition.Y - 8 - EntityPosition.Z), + _wingRectangle, Color.White, 0, new Vector2(0, 9), Vector2.One, + (int)_flyCounter % 132 < 66 ? SpriteEffects.FlipVertically : SpriteEffects.None, 0); + spriteBatch.Draw(Resources.SprEnemies, new Vector2(EntityPosition.X + 5, EntityPosition.Y - 8 - EntityPosition.Z), + _wingRectangle, Color.White, 0, new Vector2(0, 9), Vector2.One, + ((int)_flyCounter % 132 < 66 ? SpriteEffects.FlipVertically : SpriteEffects.None) | SpriteEffects.FlipHorizontally, 0); + + // draw the body + _bodyDrawComponent.Draw(spriteBatch); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if ((damageType & HitType.Sword) != 0 && !_body.IsGrounded) + return Values.HitCollision.None; + + // start flying over the player if the octorok is facing him + var playerDirection = AnimationHelper.GetDirection( + MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position); + + if (_direction != (playerDirection + 2) % 4 && _damageSwitch.State && + (_aiComponent.CurrentStateId == "walking" || _aiComponent.CurrentStateId == "idle") && + damageType != HitType.PegasusBootsSword && + damageType != HitType.Bow && + damageType != HitType.Hookshot && + damageType != HitType.MagicRod && + damageType != HitType.MagicPowder && + damageType != HitType.Boomerang) + { + _aiComponent.ChangeState("flying"); + return Values.HitCollision.None; + } + + return _aiDamageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X * 1.75f, direction.Y * 1.75f, _body.Velocity.Z); + + return true; + } + + private void OnCollision(Values.BodyCollision direction) + { + if (_aiComponent.CurrentStateId == "walking") + _aiComponent.ChangeState("idle"); + } + + private void OnHoleAbsorb() + { + _animator.SpeedMultiplier = 3f; + _animator.Play("walk_" + _direction); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyPairodd.cs b/InGame/GameObjects/Enemies/EnemyPairodd.cs new file mode 100644 index 0000000..3a8700e --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyPairodd.cs @@ -0,0 +1,208 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyPairodd : GameObject + { + private readonly AiComponent _aiComponent; + private readonly AiDamageState _damageState; + private readonly BodyComponent _body; + private readonly Animator _animator; + private readonly CSprite _sprite; + private readonly DrawShadowCSpriteComponent _shadowComponent; + private readonly AiTriggerTimer _teleportCooldown; + private readonly AiTriggerCountdown _shootCountdown; + private readonly AiStunnedState _aiStunnedState; + + private readonly Rectangle _fieldRectangle; + private readonly Vector2 _centerPosition; + + public EnemyPairodd() : base("pairodd") { } + + public EnemyPairodd(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + Tags = Values.GameObjectTag.Enemy; + + _fieldRectangle = map.GetField(posX, posY); + _centerPosition = new Vector2(_fieldRectangle.Center.X, _fieldRectangle.Center.Y + 8); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/pairodd"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-8, -16)); + + _body = new BodyComponent(EntityPosition, -7, -12, 14, 12, 8); + + var stateIdle = new AiState(UpdateIdle); + stateIdle.Trigger.Add(_teleportCooldown = new AiTriggerTimer(300)); + var stateSpawn = new AiState(UpdateSpawn); + var statePreDespawn = new AiState(); + statePreDespawn.Trigger.Add(new AiTriggerCountdown(200, null, ToDespawn)); + var stateDespawn = new AiState(UpdateDespawn); + var stateHidden = new AiState(); + stateHidden.Trigger.Add(new AiTriggerCountdown(600, null, ToSpawning)); + + _aiComponent = new AiComponent(); + _aiComponent.Trigger.Add(_shootCountdown = new AiTriggerCountdown(400, null, Shoot)); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("spawn", stateSpawn); + _aiComponent.States.Add("preDespawn", statePreDespawn); + _aiComponent.States.Add("despawn", stateDespawn); + _aiComponent.States.Add("hidden", stateHidden); + _damageState = new AiDamageState(this, _body, _aiComponent, _sprite, 2, false) { OnBurn = () => _animator.Pause() }; + _aiStunnedState = new AiStunnedState(_aiComponent, animationComponent, 3300, 900); + new AiFallState(_aiComponent, _body, OnHoleAbsorb); + + var hittableBox = new CBox(EntityPosition, -7, -14, 14, 14, 8); + + AddComponent(BodyComponent.Index, _body); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, _shadowComponent = new DrawShadowCSpriteComponent(_sprite)); + + ToIdle(); + // do not shoot directly after spawning + _shootCountdown.Stop(); + } + + private void ToSpawning() + { + _aiComponent.ChangeState("spawn"); + _animator.Play("spawn"); + _sprite.IsVisible = true; + _body.Velocity = Vector3.Zero; + + // set the new position to be at the opposite side of the room + var directionToCenter = _centerPosition - EntityPosition.Position; + + // clamp the offset to not move too fare from the center + if (directionToCenter.Length() > 48) + { + directionToCenter.Normalize(); + directionToCenter *= 56; + } + + var newPosition = _centerPosition + directionToCenter; + EntityPosition.Set(newPosition); + } + + private void UpdateSpawn() + { + // finished spawn animation? + if (!_animator.IsPlaying) + ToIdle(); + } + + private void ToIdle() + { + _aiComponent.ChangeState("idle"); + _animator.Play("idle"); + _damageState.IsActive = true; + _shadowComponent.IsActive = true; + _body.IsActive = true; + _shootCountdown.OnInit(); + } + + private void UpdateIdle() + { + if (!_teleportCooldown.State) + return; + + var playerDistance = _body.BodyBox.Box.Center - MapManager.ObjLink.BodyRectangle.Center; + + if (playerDistance.Length() < 46) + _aiComponent.ChangeState("preDespawn"); + } + + private void Shoot() + { + if (!_fieldRectangle.Contains(MapManager.ObjLink.BodyRectangle.Center)) + return; + + var projectile = new EnemyPairoddProjectile(Map, new Vector2(EntityPosition.X, EntityPosition.Y - 8), 1.5f); + Map.Objects.SpawnObject(projectile); + } + + private void ToDespawn() + { + // do not despawn if the enemy is dead + if (_damageState.CurrentLives <= 0 && _damageState.DamageTrigger.CurrentTime > 0) + return; + + Game1.GameManager.PlaySoundEffect("D360-60-3C"); + + _aiComponent.ChangeState("despawn"); + _animator.Play("despawn"); + _damageState.IsActive = false; + _shadowComponent.IsActive = false; + _body.IsActive = false; + } + + private void UpdateDespawn() + { + // finished spawn animation? + if (!_animator.IsPlaying) + ToHidden(); + } + + private void ToHidden() + { + _aiComponent.ChangeState("hidden"); + _sprite.IsVisible = false; + } + + private void OnHoleAbsorb() + { + _animator.Play("idle"); + _animator.SpeedMultiplier = 4f; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (!_damageState.IsActive) + return false; + + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X * 1.75f, direction.Y * 1.75f, _body.Velocity.Z); + + return true; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (!_damageState.IsActive || _damageState.IsInDamageState()) + return Values.HitCollision.None; + + if (damageType == HitType.Boomerang) + { + _damageState.SetDamageState(false); + + _body.Velocity.X += direction.X * 2.5f; + _body.Velocity.Y += direction.Y * 2.5f; + + _aiStunnedState.StartStun(); + _animator.Pause(); + + return Values.HitCollision.Enemy; + } + + if (damageType == HitType.Bomb) + damage = 1; + + return _damageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyPairoddProjectile.cs b/InGame/GameObjects/Enemies/EnemyPairoddProjectile.cs new file mode 100644 index 0000000..0e97214 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyPairoddProjectile.cs @@ -0,0 +1,75 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyPairoddProjectile : GameObject + { + public EnemyPairoddProjectile(Map.Map map, Vector2 position, float speed) : base(map) + { + Tags = Values.GameObjectTag.Damage; + + EntityPosition = new CPosition(position.X, position.Y, 0); + EntitySize = new Rectangle(-7, -7, 14, 14); + + var animator = AnimatorSaveLoad.LoadAnimator("Enemies/pairodd projectile"); + animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(animator, sprite, Vector2.Zero); + + var body = new BodyComponent(EntityPosition, -2, -2, 4, 4, 8) + { + IgnoresZ = true, + IgnoreHoles = true, + CollisionTypes = Values.CollisionTypes.Normal, + MoveCollision = OnCollision + }; + + var velocity = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (velocity != Vector2.Zero) + velocity.Normalize(); + body.VelocityTarget = velocity * speed; + + var damageCollider = new CBox(EntityPosition, -3, -3, 0, 6, 6, 4); + + AddComponent(PushableComponent.Index, new PushableComponent(body.BodyBox, OnPush)); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 2) { OnDamagedPlayer = DamagedPlayer }); + AddComponent(BodyComponent.Index, body); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerPlayer)); + } + + private void DamagedPlayer() + { + Despawn(); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType pushType) + { + Despawn(); + + return true; + } + + private void OnCollision(Values.BodyCollision collision) + { + Despawn(); + } + + private void Despawn() + { + // spawn despawn effect + var animation = new ObjAnimator(Map, (int)EntityPosition.X, (int)EntityPosition.Y, Values.LayerTop, "Particles/swordPoke", "run", true); + Map.Objects.SpawnObject(animation); + + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyPeahat.cs b/InGame/GameObjects/Enemies/EnemyPeahat.cs new file mode 100644 index 0000000..1ee0a96 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyPeahat.cs @@ -0,0 +1,196 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyPeahat : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly AiTriggerCountdown _flyCounter; + private readonly AiDamageState _damageState; + + private const int StartTime = 2500; + private const int FlyTime = 7500; + private const int LandTime = 1500; + + private float _flyState; + private float _turnSpeed; + private int _dir = 1; + + public EnemyPeahat() : base("peahat") { } + + public EnemyPeahat(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -32, 16, 32); + + _turnSpeed = 0.02f; + _flyState = (float)Math.PI / 2 * Game1.RandomNumber.Next(0, 4); + _dir = Game1.RandomNumber.Next(0, 2) * 2 - 1; + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/peahat"); + _animator.SpeedMultiplier = 0; + _animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animatorComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -16)); + + var fieldRectangle = map.GetField(posX, posY, 8); + + _body = new BodyComponent(EntityPosition, -6, -12, 12, 10, 8) + { + MoveCollision = OnCollision, + IgnoresZ = true, + FieldRectangle = fieldRectangle, + MaxJumpHeight = 4 + }; + + _aiComponent = new AiComponent(); + + var stateStart = new AiState(); + stateStart.Trigger.Add(new AiTriggerCountdown(StartTime, StartTick, ToFlying)); + var stateFly = new AiState(UpdateFlying); + stateFly.Trigger.Add(new AiTriggerRandomTime(ChangeFlyingDirection, 500, 1500)); + stateFly.Trigger.Add(_flyCounter = new AiTriggerCountdown(FlyTime, null, ToLand)); + var stateLand = new AiState(); + stateLand.Trigger.Add(new AiTriggerCountdown(LandTime, LandTick, ToIdle)); + var stateIdle = new AiState(); + stateIdle.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("start"), 3000, 6000)); + var stateStunned = new AiState(); + stateStunned.Trigger.Add(new AiTriggerCountdown(200, null, EndStunned)); + + _aiComponent.States.Add("start", stateStart); + _aiComponent.States.Add("fly", stateFly); + _aiComponent.States.Add("land", stateLand); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("stunned", stateStunned); + _damageState = new AiDamageState(this, _body, _aiComponent, sprite, 1, false); + + _aiComponent.ChangeState("start"); + + var hittableBox = new CBox(EntityPosition, -6, -14, 0, 12, 14, 8, true); + var damageBox = new CBox(EntityPosition, -6, -14, 0, 12, 14, 4, true); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(PushableComponent.Index, new PushableComponent(damageBox, OnPush)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animatorComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer) { DeepWaterOutline = true }); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite)); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + if (_aiComponent.CurrentStateId == "stunned") + return Values.HitCollision.None; + + if (_animator.SpeedMultiplier > 0.25f) + { + _aiComponent.ChangeState("stunned"); + _animator.SpeedMultiplier = 0; + _body.VelocityTarget = Vector2.Zero; + + return Values.HitCollision.RepellingParticle; + } + + return _damageState.OnHit(originObject, direction, type, damage, pieceOfPower); + } + + private void OnCollision(Values.BodyCollision collision) + { + // speed up the collision time + _flyState += (_dir == -1 ? -1 : 1) * MathF.PI * 0.025f * Game1.TimeMultiplier; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X * 1.5f, direction.Y * 1.5f, _body.Velocity.Z); + + return true; + } + + private void EndStunned() + { + _aiComponent.ChangeState(_aiComponent.LastStateId, true); + } + + private void StartTick(double count) + { + // speed up animation + var mult = (StartTime - (float)count + 250f) / 1500f; + mult = Math.Clamp(mult, 0, 1); + _animator.SpeedMultiplier = mult; + + // start moving up + if (count < StartTime - 1250) + EntityPosition.Z = (float)(1 - count / (StartTime - 1250)) * 16; + } + + private void ToFlying() + { + _aiComponent.ChangeState("fly"); + EntityPosition.Z = 16; + } + + private void ChangeFlyingDirection() + { + _dir = Game1.RandomNumber.Next(0, 3) - 1; + } + + private void UpdateFlying() + { + _animator.SpeedMultiplier = 1; + + _flyState += _dir * _turnSpeed * Game1.TimeMultiplier; + var vecDirection = new Vector2((float)Math.Sin(_flyState), (float)Math.Cos(_flyState)); + + // speeds up / slows down + float speedMult; + if (_flyCounter.CurrentTime >= FlyTime - 250) + speedMult = Math.Clamp((float)(FlyTime - _flyCounter.CurrentTime) / 250, 0, 1); + else + speedMult = Math.Min(1, (float)_flyCounter.CurrentTime / 250); + + // fly + _body.VelocityTarget = vecDirection * 0.5f * speedMult; + } + + private void ToLand() + { + _aiComponent.ChangeState("land"); + _body.VelocityTarget = Vector2.Zero; + } + + private void LandTick(double count) + { + // speed up animation + var mult = (float)count / LandTime; + mult = Math.Clamp(mult, 0, 1); + _animator.SpeedMultiplier = mult; + + // move down + var posZ = (float)((count - 500) / (LandTime - 500)); + posZ = Math.Clamp(posZ, 0, 1); + EntityPosition.Z = posZ * 16; + } + + private void ToIdle() + { + _aiComponent.ChangeState("idle"); + EntityPosition.Z = 0; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyPincer.cs b/InGame/GameObjects/Enemies/EnemyPincer.cs new file mode 100644 index 0000000..7526400 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyPincer.cs @@ -0,0 +1,226 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyPincer : GameObject + { + private readonly CSprite _sprite; + private readonly Animator _animator; + private readonly AiComponent _aiComponent; + private readonly DamageFieldComponent _damageField; + private readonly BodyComponent _body; + private readonly AiStunnedState _stunnedState; + + private readonly AiDamageState _damageState; + private readonly Rectangle _tailRectangle = new Rectangle(184, 124, 8, 8); + + private readonly Vector2 _spawnPosition; + private Vector2 _direction; + private Vector2 _attackOffset; + private Vector2 _retractStartPosition; + + private float _attackCounter; + private int _dirIndex; + + public EnemyPincer() : base("pincer") { } + + public EnemyPincer(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 8, 0); + EntitySize = new Rectangle(-32, -32, 64, 64); + + _spawnPosition = new Vector2(EntityPosition.X, EntityPosition.Y); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/pincer"); + _animator.Play("eyes"); + + _sprite = new CSprite(EntityPosition) { IsVisible = false }; + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-8, -8)); + + _body = new BodyComponent(EntityPosition, -6, -6, 12, 12, 8) + { + CollisionTypes = Values.CollisionTypes.None, + Drag = 0.75f, + IgnoreHoles = true + }; + + var stateWaiting = new AiState(UpdateWaiting); + var stateSpawning = new AiState(null); + stateSpawning.Trigger.Add(new AiTriggerCountdown(1000, null, ToAttack)); + var stateAttacking = new AiState(UpdateAttack); + var stateAttackWait = new AiState(null); + stateAttackWait.Trigger.Add(new AiTriggerCountdown(1000, null, ToRetract)); + var stateRetract = new AiState(UpdateRetract); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("waiting", stateWaiting); + _aiComponent.States.Add("spawning", stateSpawning); + _aiComponent.States.Add("attacking", stateAttacking); + _aiComponent.States.Add("attackWait", stateAttackWait); + _aiComponent.States.Add("retract", stateRetract); + _damageState = new AiDamageState(this, _body, _aiComponent, _sprite, 2, false) { HitMultiplierX = 1.5f, HitMultiplierY = 1.5f }; + _stunnedState = new AiStunnedState(_aiComponent, animationComponent, 3300, 900); + + _aiComponent.ChangeState("waiting"); + + var damageBox = new CBox(EntityPosition, -5, -5, 0, 10, 10, 4); + var hittableBox = new CBox(EntityPosition, -7, -7, 14, 14, 8); + + AddComponent(PushableComponent.Index, new PushableComponent(hittableBox, OnPush)); + AddComponent(BodyComponent.Index, _body); + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageBox, HitType.Enemy, 2) { IsActive = false }); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact && + (_aiComponent.CurrentStateId == "attacking" || + _aiComponent.CurrentStateId == "attackWait" || + _aiComponent.CurrentStateId == "retract" || + _stunnedState.IsStunned())) + { + if (_aiComponent.CurrentStateId == "attacking") + _aiComponent.ChangeState("attackWait"); + + var mult = 1.5f; + _body.Velocity = new Vector3(direction.X * mult, direction.Y * mult, 0); + return true; + } + + return false; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (damageType == HitType.MagicPowder) + { + _stunnedState.StartStun(); + return Values.HitCollision.Enemy; + } + + // can only attack while the enemy is attacking + if (_aiComponent.CurrentStateId != "attacking" && + _aiComponent.CurrentStateId != "attackWait" && + _aiComponent.CurrentStateId != "retract" && + !_stunnedState.IsStunned()) + return Values.HitCollision.None; + + if (_aiComponent.CurrentStateId == "attacking") + _aiComponent.ChangeState("attackWait"); + + _damageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + + // make sure to not fly away like for other enemies + if (pieceOfPower) + _body.Drag = 0.75f; + + return Values.HitCollision.Enemy; + } + + private void ToWaiting() + { + _aiComponent.ChangeState("waiting"); + _sprite.IsVisible = false; + _damageField.IsActive = false; + } + + private void UpdateWaiting() + { + _direction = MapManager.ObjLink.EntityPosition.Position - new Vector2(EntityPosition.Position.X, EntityPosition.Position.Y - 4); + if (_direction.Length() < 42) + { + _aiComponent.ChangeState("spawning"); + + EntityPosition.Set(_spawnPosition); + + _sprite.IsVisible = true; + _animator.Play("eyes"); + } + } + + private void ToAttack() + { + _damageField.IsActive = true; + _aiComponent.ChangeState("attacking"); + GetAttackDirection(); + } + + private void UpdateAttack() + { + _attackCounter += (Game1.TimeMultiplier * 2) / 35.0f; + if (_attackCounter > 1) + _attackCounter = 1; + + _attackOffset = _direction * _attackCounter * 35.0f; + EntityPosition.Set(_spawnPosition + _attackOffset); + + if (_attackCounter >= 1) + _aiComponent.ChangeState("attackWait"); + } + + private void ToRetract() + { + _aiComponent.ChangeState("retract"); + _retractStartPosition = EntityPosition.Position - _spawnPosition; + _attackCounter = 1; + } + + private void UpdateRetract() + { + _attackCounter -= (Game1.TimeMultiplier * 1.25f) / 35.0f; + if (_attackCounter < 0) + _attackCounter = 0; + + _attackOffset = Vector2.Lerp(_retractStartPosition, Vector2.Zero, 1 - _attackCounter); + EntityPosition.Set(_spawnPosition + _attackOffset); + + if (_attackCounter <= 0) + ToWaiting(); + } + + private void Draw(SpriteBatch spriteBatch) + { + // draw the body + if (_sprite.IsVisible && _aiComponent.CurrentStateId != "spawning") + for (var i = 0; i < 3; i++) + { + var position = + _spawnPosition + (EntityPosition.Position - _spawnPosition) * (0.15f + (i / 2f) * 0.5f) - new Vector2(4, 4); + + spriteBatch.Draw(Resources.SprEnemies, position, _tailRectangle, Color.White); + } + + // draw the head + _sprite.Draw(spriteBatch); + } + + private void GetAttackDirection() + { + _direction = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + + if (_direction != Vector2.Zero) + _direction.Normalize(); + + var degree = MathHelper.ToDegrees((float)Math.Atan2(-_direction.Y, -_direction.X)) + 360; + + _dirIndex = (int)((degree + 22.5f) / 45) % 8; + + _animator.Play(_dirIndex.ToString()); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyPiranhaPlant.cs b/InGame/GameObjects/Enemies/EnemyPiranhaPlant.cs new file mode 100644 index 0000000..8b3f683 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyPiranhaPlant.cs @@ -0,0 +1,112 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyPiranhaPlant : GameObject + { + private readonly CSprite _sprite; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _aiDamageState; + private readonly Animator _animator; + private readonly DamageFieldComponent _damageField; + + private readonly CPosition _headPosition; + private readonly CBox _headBox; + + public EnemyPiranhaPlant() : base("piranha plant") { } + + public EnemyPiranhaPlant(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -32, 16, 32); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/piranha plant"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-8, -16)); + + _body = new BodyComponent(EntityPosition, -6, -11, 12, 11, 8); + + var stateHidden = new AiState(); + stateHidden.Trigger.Add(new AiTriggerCountdown(2500, null, ToIdle)); + var stateIdle = new AiState(UpdateIdle); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("hidden", stateHidden); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.ChangeState("hidden"); + + _headPosition = new CPosition(posX + 8, posY, 0); + _headBox = new CBox(_headPosition, -7, 0, 14, 14, 8); + + _aiDamageState = new AiDamageState(this, _body, _aiComponent, _sprite, 1) + { + MoveBody = false, + OnBurn = () => _animator.Pause() + }; + + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(_headBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(_headBox, _aiDamageState.OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerBottom)); + + Deactivate(); + } + + private void ToIdle() + { + // check if the player is standing next to the plant -> stay hidden + var distance = EntityPosition.Position.X - MapManager.ObjLink.EntityPosition.Position.X; + if (Math.Abs(distance) < 16) + { + _aiComponent.ChangeState("hidden"); + return; + } + + _animator.Play("spawn"); + _aiComponent.ChangeState("idle"); + Activate(); + } + + private void UpdateIdle() + { + // update the head position + _headPosition.Set(new Vector2(_headPosition.X, _sprite.Position.Y + _sprite.DrawOffset.Y)); + _aiDamageState.ExplosionOffsetY = (int)(_headPosition.Y - EntityPosition.Y) + 16; + _aiDamageState.FlameOffset.Y = _aiDamageState.ExplosionOffsetY; + + if (!_animator.IsPlaying) + { + _aiComponent.ChangeState("hidden"); + Deactivate(); + } + } + + private void Activate() + { + _sprite.IsVisible = true; + _damageField.IsActive = true; + _aiDamageState.IsActive = true; + } + + private void Deactivate() + { + _sprite.IsVisible = false; + _damageField.IsActive = false; + _aiDamageState.IsActive = false; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyPodoboo.cs b/InGame/GameObjects/Enemies/EnemyPodoboo.cs new file mode 100644 index 0000000..f063bb0 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyPodoboo.cs @@ -0,0 +1,124 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using Microsoft.Xna.Framework.Graphics; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyPodoboo : GameObject + { + private readonly BodyComponent _body; + private readonly AnimationComponent _animationComponent; + private readonly AiComponent _aiComponent; + private readonly DamageFieldComponent _damageField; + private readonly CSprite _sprite; + + private Vector2 _startPosition; + + public EnemyPodoboo() : base("podoboo") { } + + public EnemyPodoboo(Map.Map map, int posX, int posY, int timeOffset) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-32, -8 - 32, 64, 64); + + _startPosition = EntityPosition.Position; + + var animator = AnimatorSaveLoad.LoadAnimator("Enemies/podoboo"); + animator.Play("idle"); + + _sprite = new CSprite(EntityPosition); + _animationComponent = new AnimationComponent(animator, _sprite, new Vector2(0, -8)); + + _body = new BodyComponent(EntityPosition, -5, -8 - 5, 10, 10, 8) + { + Gravity2D = 0.05f, + CollisionTypes = Values.CollisionTypes.None, + SplashEffect = false + }; + + _aiComponent = new AiComponent(); + + var stateFlying = new AiState(UpdateFlying) { Init = InitFlying }; + stateFlying.Trigger.Add(new AiTriggerCountdown(250, null, SpawnParticle) { ResetAfterEnd = true }); + var stateHidden = new AiState() { Init = InitHidden }; + var hiddenCountdown = new AiTriggerCountdown(2000, null, () => _aiComponent.ChangeState("flying")); + stateHidden.Trigger.Add(hiddenCountdown); + + _aiComponent.States.Add("flying", stateFlying); + _aiComponent.States.Add("hidden", stateHidden); + + var damageCollider = new CBox(EntityPosition, -5, -8 - 5, 0, 10, 10, 4); + + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageCollider, HitType.Enemy, 2)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, _animationComponent); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerBottom)); + AddComponent(LightDrawComponent.Index, new LightDrawComponent(DrawLight)); + + _aiComponent.ChangeState("hidden"); + hiddenCountdown.CurrentTime = timeOffset; + } + + private void InitFlying() + { + _sprite.IsVisible = true; + _damageField.IsActive = true; + _body.IsActive = true; + _body.Velocity.Y = -2.7f; + + SpawnSplash(); + } + + private void UpdateFlying() + { + _sprite.SpriteShader = Game1.TotalGameTime % (8000 / 60f) >= (4000 / 60f) ? Resources.DamageSpriteShader0 : null; + + if (_body.Velocity.Y > 0 && !_animationComponent.MirroredV) + { + _animationComponent.MirroredV = true; + } + + if (EntityPosition.Y > _startPosition.Y) + { + SpawnSplash(); + _aiComponent.ChangeState("hidden"); + } + } + + private void InitHidden() + { + EntityPosition.Set(_startPosition); + _body.IsActive = false; + _sprite.IsVisible = false; + _damageField.IsActive = false; + _animationComponent.MirroredV = false; + } + + private void SpawnParticle() + { + var particle = new EnemyPodobooParticle(Map, new Vector2(EntityPosition.X, EntityPosition.Y), _animationComponent.MirroredV); + Map.Objects.SpawnObject(particle); + } + + private void SpawnSplash() + { + // left splash + Map.Objects.SpawnObject(new EnemyPodobooSplash(Map, new Vector2(_startPosition.X, _startPosition.Y), new Vector2(-0.5f, -0.85f))); + // right splash + Map.Objects.SpawnObject(new EnemyPodobooSplash(Map, new Vector2(_startPosition.X, _startPosition.Y), new Vector2(0.5f, -0.85f))); + } + + private void DrawLight(SpriteBatch spriteBatch) + { + DrawHelper.DrawLight(spriteBatch, new Rectangle((int)EntityPosition.X - 32, (int)EntityPosition.Y - 32, 64, 64), new Color(255, 200, 200) * 0.75f); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyPodobooParticle.cs b/InGame/GameObjects/Enemies/EnemyPodobooParticle.cs new file mode 100644 index 0000000..0e85942 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyPodobooParticle.cs @@ -0,0 +1,44 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyPodobooParticle : GameObject + { + private readonly Animator _animator; + private readonly CSprite _sprite; + + public EnemyPodobooParticle(Map.Map map, Vector2 position, bool mirrored) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(position.X, position.Y - 5, 0); + EntitySize = new Rectangle(-5, 0, 10, 10); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/podoboo"); + _animator.Play("particle"); + + _sprite = new CSprite(EntityPosition) { Color = Color.White * 0.85f }; + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(0, 5)); + animationComponent.MirroredV = mirrored; + + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerBottom)); + } + + private void Update() + { + // 4 frame blink effect + _sprite.SpriteShader = Game1.TotalGameTime % (8000 / 60f) >= (4000 / 60f) ? Resources.DamageSpriteShader0 : null; + + // delete after finishing the animation + if (!_animator.IsPlaying) + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyPodobooSplash.cs b/InGame/GameObjects/Enemies/EnemyPodobooSplash.cs new file mode 100644 index 0000000..1dd2289 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyPodobooSplash.cs @@ -0,0 +1,64 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using ProjectZ.InGame.GameObjects.Base.Components.AI; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyPodobooSplash : GameObject + { + private readonly BodyComponent _body; + private readonly AnimationComponent _animationComponent; + private readonly AiComponent _aiComponent; + private readonly CSprite _sprite; + + public EnemyPodobooSplash(Map.Map map, Vector2 position, Vector2 velocity) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(position.X, position.Y, 0); + EntitySize = new Rectangle(-5, -5, 10, 10); + + var animator = AnimatorSaveLoad.LoadAnimator("Enemies/podoboo"); + animator.Play("splash"); + + _sprite = new CSprite(EntityPosition); + _animationComponent = new AnimationComponent(animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -5, -5, 10, 10, 8) + { + Gravity2D = 0.065f, + CollisionTypes = Values.CollisionTypes.None, + Velocity = new Vector3(velocity.X, velocity.Y, 0), + SplashEffect = false + }; + + _aiComponent = new AiComponent(); + + var stateFlying = new AiState(); + stateFlying.Trigger.Add(new AiTriggerCountdown(500, DespawnTick, () => Map.Objects.DeleteObjects.Add(this))); + + _aiComponent.States.Add("flying", stateFlying); + + _aiComponent.ChangeState("flying"); + + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, _animationComponent); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerBottom)); + } + + private void DespawnTick(double time) + { + // 4 frame blink effect + _sprite.SpriteShader = Game1.TotalGameTime % (8000 / 60f) >= (4000 / 60f) ? Resources.DamageSpriteShader0 : null; + + // fade out + if (time < 75) + _sprite.Color = Color.White * (float)(time / 75); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyPokey.cs b/InGame/GameObjects/Enemies/EnemyPokey.cs new file mode 100644 index 0000000..7e5a816 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyPokey.cs @@ -0,0 +1,178 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyPokey : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _aiDamageState; + private readonly CSprite _sprite; + + private readonly DictAtlasEntry _spriteHead; + private readonly DictAtlasEntry _spriteBody; + + private float _moveSpeed = 1 / 3f; + private int _direction; + private int _state; + + public EnemyPokey() : base("pokey") { } + + public EnemyPokey(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-10, -48, 20, 48); + + _spriteHead = Resources.GetSprite("pokey"); + _spriteBody = Resources.GetSprite("pokey body"); + + _sprite = new CSprite("pokey body", EntityPosition); + _body = new BodyComponent(EntityPosition, -7, -14, 14, 14, 8) + { + CollisionTypes = Values.CollisionTypes.Normal | + Values.CollisionTypes.Enemy, + AvoidTypes = Values.CollisionTypes.Hole | Values.CollisionTypes.NPCWall, + FieldRectangle = map.GetField(posX, posY), + Gravity = -0.15f, + Bounciness = 0.35f, + Drag = 0.8f, + DragAir = 0.8f, + MaxJumpHeight = 4f, + IgnoreHeight = true + }; + + var stateMoving = new AiState { Init = InitWalking }; + stateMoving.Trigger.Add(new AiTriggerRandomTime(ChangeDirection, 550, 850)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("moving", stateMoving); + new AiFallState(_aiComponent, _body, null); + _aiDamageState = new AiDamageState(this, _body, _aiComponent, _sprite, 4); + + _aiComponent.ChangeState("moving"); + + var damageBox = new CBox(EntityPosition, -7, -14, 0, 14, 14, 16); + var hittableBox = new CBox(EntityPosition, -7, -14, 14, 14, 24); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _sprite) { ShadowWidth = 10, ShadowHeight = 5 }); + } + + private void InitWalking() + { + ChangeDirection(); + } + + private void ChangeDirection() + { + // random new direction + _direction = Game1.RandomNumber.Next(0, 4); + _body.VelocityTarget = AnimationHelper.DirectionOffset[_direction] * _moveSpeed; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_aiDamageState.IsInDamageState()) + return Values.HitCollision.None; + + if (damageType == HitType.Bomb || damageType == HitType.Bow) + damage /= 2; + + if ((damageType & HitType.Sword2) != 0 || + damageType == HitType.Hookshot || + damageType == HitType.MagicPowder || + damageType == HitType.MagicRod || + pieceOfPower) + damage *= 2; + + var hitType = _aiDamageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + + if (_aiDamageState.CurrentLives > 0) + { + _state += 1; + if (_state <= 2) + { + EntityPosition.Z = 14; + _body.Velocity.Z = -0.5f; + + var bodyPart = new EnemyPokeyPart(Map, EntityPosition.X, EntityPosition.Y, direction * 2f, _body.Velocity); + Map.Objects.SpawnObject(bodyPart); + } + } + + if (_state == 2) + _sprite.SetSprite(_spriteHead); + + return hitType; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X, direction.Y, _body.Velocity.Z); + + return true; + } + + private void Draw(SpriteBatch spriteBatch) + { + // change the draw effect + if (_sprite.SpriteShader != null) + { + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, _sprite.SpriteShader); + } + + // draw the body + var posY = EntityPosition.Y - EntityPosition.Z; + if (_state == 0) + { + DrawHelper.DrawNormalized(spriteBatch, _spriteBody, new Vector2(EntityPosition.X, posY), _sprite.Color); + posY -= 12; + } + + var offsetX = 0.0f; + if (_state <= 1) + { + // dont wobble at the floor + if (_state == 0) + offsetX = (float)Math.Sin(Game1.TotalGameTime * 0.0125); + + DrawHelper.DrawNormalized(spriteBatch, _spriteBody, new Vector2(EntityPosition.X + offsetX, posY), _sprite.Color); + posY -= 12; + } + + // draw the head + offsetX = -(float)Math.Sin(Game1.TotalGameTime * 0.0125) * (_state == 0 ? 2 : 1); + DrawHelper.DrawNormalized(spriteBatch, _spriteHead, new Vector2(EntityPosition.X + offsetX, posY), _sprite.Color); + + // make sure to also move the shadow + if (_state >= 2) + _sprite.DrawOffset.X = offsetX; + + // change the draw effect + // this would not be very efficient if a lot of sprite used effects + if (_sprite.SpriteShader != null) + { + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, null); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyPokeyPart.cs b/InGame/GameObjects/Enemies/EnemyPokeyPart.cs new file mode 100644 index 0000000..d71a327 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyPokeyPart.cs @@ -0,0 +1,109 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyPokeyPart : GameObject + { + private readonly AiComponent _aiComponent; + private readonly DamageFieldComponent _damageField; + private readonly BodyComponent _body; + private readonly AiDamageState _aiDamageState; + + private int _collisionCount; + + public EnemyPokeyPart(Map.Map map, float posX, float posY, Vector2 velocityTarget, Vector3 velocity) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(-7, -14, 14, 14); + + var sprite = new CSprite(Resources.SprEnemies, EntityPosition, new Rectangle(18, 369, 14, 14), new Vector2(-7, -14)); + + _body = new BodyComponent(EntityPosition, -7, -14, 14, 14, 8) + { + CollisionTypes = Values.CollisionTypes.Normal, + MoveCollision = OnCollision, + Velocity = velocity, + VelocityTarget = velocityTarget, + Drag = 0.8f, + DragAir = 0.8f, + IgnoreHeight = true, + IgnoresZ = true, + }; + + var stateSpawning = new AiState(); + stateSpawning.Trigger.Add(new AiTriggerCountdown(500, null, ToMoving)); + var stateMoving = new AiState(); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("spawning", stateSpawning); + _aiComponent.States.Add("moving", stateMoving); + _aiDamageState = new AiDamageState(this, _body, _aiComponent, sprite, 1) { IsActive = false }; + _aiComponent.ChangeState("spawning"); + + var damageCollider = new CBox(EntityPosition, -6, -13, 0, 12, 12, 4, true); + + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageCollider, HitType.Enemy, 2) { OnDamage = OnDamage }); + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, _aiDamageState.OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush) { RepelMultiplier = 0.2f }); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new ShadowBodyDrawComponent(EntityPosition)); + } + + private void ToMoving() + { + _aiComponent.ChangeState("moving"); + _aiDamageState.IsActive = true; + } + + private bool OnDamage() + { + Despawn(); + return _damageField.DamagePlayer(); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + Despawn(); + + return true; + } + + private void OnCollision(Values.BodyCollision direction) + { + if ((direction & Values.BodyCollision.Horizontal) != 0) + { + _body.VelocityTarget.X = -_body.VelocityTarget.X; + _body.Velocity = Vector3.Zero; + _collisionCount++; + } + else if ((direction & Values.BodyCollision.Vertical) != 0) + { + _body.VelocityTarget.Y = -_body.VelocityTarget.Y; + _body.Velocity = Vector3.Zero; + _collisionCount++; + } + + // despawn + if (_collisionCount > 2) + { + Despawn(); + } + } + + private void Despawn() + { + Map.Objects.DeleteObjects.Add(this); + Map.Objects.SpawnObject(new ObjAnimator(Map, (int)EntityPosition.X - 8, (int)EntityPosition.Y - 16, Values.LayerPlayer, "Particles/spawn", "run", true)); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyPolsVoice.cs b/InGame/GameObjects/Enemies/EnemyPolsVoice.cs new file mode 100644 index 0000000..16eaaae --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyPolsVoice.cs @@ -0,0 +1,174 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyPolsVoice : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly AiDamageState _damageState; + private readonly AiStunnedState _stunnedState; + + private float _jumpVelocity = 1.0f; + + public EnemyPolsVoice() : base("pols voice") { } + + public EnemyPolsVoice(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/pols voice"); + _animator.Play("jump"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -16)); + + _body = new BodyComponent(EntityPosition, -6, -10, 12, 10, 8) + { + AvoidTypes = Values.CollisionTypes.Hole | Values.CollisionTypes.NPCWall, + FieldRectangle = map.GetField(posX, posY), + MaxJumpHeight = 8f, + Gravity = -0.05f, + Drag = 0.75f, + DragAir = 0.8f + }; + + var stateWaiting = new AiState { Init = InitWaiting }; + stateWaiting.Trigger.Add(new AiTriggerRandomTime(EndWaiting, 500, 750)); + var stateJumping = new AiState(UpdateJumping) { Init = InitJump }; + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("waiting", stateWaiting); + _aiComponent.States.Add("jumping", stateJumping); + _damageState = new AiDamageState(this, _body, _aiComponent, sprite, 4, true, false); + new AiFallState(_aiComponent, _body, null, null, 100); + _stunnedState = new AiStunnedState(_aiComponent, animationComponent, 3300, 900); + + _aiComponent.ChangeState("jumping"); + + var damageBox = new CBox(EntityPosition, -7, -11, 0, 14, 11, 4); + var hittableBox = new CBox(EntityPosition, -6, -12, 0, 12, 12, 8, true); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 1)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite) { ShadowWidth = 10 }); + } + + private void InitWaiting() + { + _body.VelocityTarget = Vector2.Zero; + _animator.Play("stand"); + } + + private void EndWaiting() + { + var distance = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + if (distance.Length() < 64 && _body.FieldRectangle.Intersects(MapManager.ObjLink.BodyRectangle)) + _aiComponent.ChangeState("jumping"); + } + + private void InitJump() + { + _animator.Play("jump"); + + // start jumping + _body.Velocity.Z = _jumpVelocity; + _body.Bounciness = 0f; + + var jumpDirection = Vector2.Zero; + + if (Game1.RandomNumber.Next(0, 3) == 0) + { + // jump towards the player + var direction = new Vector2( + MapManager.ObjLink.PosX - EntityPosition.X, + MapManager.ObjLink.PosY - EntityPosition.Y); + + if (direction != Vector2.Zero) + { + direction.Normalize(); + jumpDirection = direction; + } + } + else + { + var randomDirection = Game1.RandomNumber.Next(0, 100) / 100f * Math.PI * 2; + jumpDirection = new Vector2((float)Math.Sin(randomDirection), (float)Math.Cos(randomDirection)); + } + + _body.VelocityTarget = jumpDirection * 0.75f; + } + + private void UpdateJumping() + { + // finished jumping? + if (_body.IsGrounded) + { + _animator.Play("stand"); + _aiComponent.ChangeState("waiting"); + } + } + + private void StartStun() + { + if (_body.Velocity.Z > 0) + _body.Velocity.Z = 0; + _body.VelocityTarget = Vector2.Zero; + _body.Bounciness = 0.65f; + _stunnedState.StartStun(); + _animator.Play("jump"); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_damageState.IsInDamageState()) + return Values.HitCollision.None; + + if (damageType == HitType.Bow || damageType == HitType.MagicRod) + return _damageState.OnHit(gameObject, direction, damageType, 1, pieceOfPower); + if (damageType == HitType.ThrownObject || damageType == HitType.Bomb) + return _damageState.OnHit(gameObject, direction, damageType, 4, pieceOfPower); + + if (damageType == HitType.MagicPowder || damageType == HitType.Hookshot || damageType == HitType.Boomerang) + { + direction *= 0.25f; + StartStun(); + } + + _damageState.HitKnockBack(gameObject, direction, damageType, pieceOfPower, false); + + // play sound effect + Game1.GameManager.PlaySoundEffect("D360-03-03"); + + return Values.HitCollision.Repelling; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + { + _body.VelocityTarget = Vector2.Zero; + _body.Velocity = new Vector3(direction.X * 2f, direction.Y * 2f, _body.Velocity.Z); + } + + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyRaven.cs b/InGame/GameObjects/Enemies/EnemyRaven.cs new file mode 100644 index 0000000..05c81e5 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyRaven.cs @@ -0,0 +1,154 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyRaven : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly AiDamageState _damageState; + private readonly AiTriggerTimer _followTimer; + + private readonly Box _activationBox; + + private double _dirRadius; + private int _dirIndex; + + public EnemyRaven() : base("raven") { } + + public EnemyRaven(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 12, 0); + EntitySize = new Rectangle(-8, -32, 16, 32); + + _activationBox = new Box(posX + 8 - 20, posY - 32, 0, 40, 90, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/raven"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-7, -16)); + + _body = new BodyComponent(EntityPosition, -6, -14, 12, 14, 8) + { + CollisionTypes = Values.CollisionTypes.None, + IgnoreHoles = true, + IgnoresZ = true + }; + + var stateWaiting = new AiState(UpdateWaiting); + var stateStart = new AiState(UpdateStart); + var stateFlying = new AiState(UpdateFlying); + stateFlying.Trigger.Add(_followTimer = new AiTriggerTimer(1000)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("waiting", stateWaiting); + _aiComponent.States.Add("start", stateStart); + _aiComponent.States.Add("flying", stateFlying); + _damageState = new AiDamageState(this, _body, _aiComponent, sprite, 2, true, false); + + _aiComponent.ChangeState("waiting"); + + // the player can jump over the enemy... + var damageCollider = new CBox(EntityPosition, -6, -14, 0, 12, 14, 8, true); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(damageCollider, OnHit)); + AddComponent(PushableComponent.Index, new PushableComponent(damageCollider, OnPush)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerTop)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite)); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (damageType == HitType.MagicPowder) + return Values.HitCollision.None; + + if (damageType == HitType.Bow || damageType == HitType.MagicRod) + damage /= 2; + + // start attacking? + if (_aiComponent.CurrentStateId == "waiting" && (damageType == HitType.Bomb || damageType == HitType.ThrownObject)) + { + _aiComponent.ChangeState("start"); + + return Values.HitCollision.None; + } + + return _damageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + } + + private void UpdateWaiting() + { + _dirIndex = MapManager.ObjLink.PosX < EntityPosition.X ? 0 : 1; + + _animator.Play("idle_" + _dirIndex); + + // activate the crow + if (MapManager.ObjLink._body.BodyBox.Box.Intersects(_activationBox)) + { + _aiComponent.ChangeState("start"); + } + } + + private void UpdateStart() + { + _animator.Play("fly_" + _dirIndex); + + EntityPosition.Set(new Vector3( + EntityPosition.X, + EntityPosition.Y, + EntityPosition.Z + 0.5f * Game1.TimeMultiplier)); + + if (EntityPosition.Z >= 15) + { + EntityPosition.Z = 15; + _aiComponent.ChangeState("flying"); + _dirRadius = Math.Atan2(MapManager.ObjLink.PosY - EntityPosition.Y, MapManager.ObjLink.PosX - EntityPosition.X); + } + } + + private void UpdateFlying() + { + var direction = MapManager.ObjLink.EntityPosition.Position - new Vector2(EntityPosition.X, EntityPosition.Y - EntityPosition.Z); + var directionRadius = Math.Atan2(direction.Y, direction.X); + + if (direction.Length() < 80) + { + var followSpeed = 0.02f; + if (directionRadius < _dirRadius - followSpeed || _followTimer.State) + _dirRadius -= followSpeed * Game1.TimeMultiplier; + else if (directionRadius > _dirRadius + followSpeed) + _dirRadius += followSpeed * Game1.TimeMultiplier; + } + + var velocity = new Vector2((float)Math.Cos(_dirRadius), (float)Math.Sin(_dirRadius)); + _body.VelocityTarget = velocity * 1.25f; + + _dirIndex = velocity.X < 0 ? 0 : 1; + _animator.Play("fly_" + _dirIndex); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction * 1.75f, _body.Velocity.Z); + + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyRedZol.cs b/InGame/GameObjects/Enemies/EnemyRedZol.cs new file mode 100644 index 0000000..f08fe71 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyRedZol.cs @@ -0,0 +1,215 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyRedZol : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly AiDamageState _damageState; + private readonly AnimationComponent _animationComponent; + + private readonly EnemyGel _gel0; + private readonly EnemyGel _gel1; + + private float _jumpAcceleration = 1.5f; + + private bool _spawnSmallZols = true; + + public EnemyRedZol() : base("red zol") { } + + public EnemyRedZol(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 13, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/red zol"); + _animator.Play("walk_1"); + + var sprite = new CSprite(EntityPosition); + _animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-6, -16)); + + _body = new BodyComponent(EntityPosition, -6, -10, 12, 10, 8) + { + MoveCollision = OnCollision, + // Values.CollisionTypes.Hole can not ignore holes because they need to walk into one in dungeon 4 + AvoidTypes = Values.CollisionTypes.NPCWall | + Values.CollisionTypes.DeepWater, + FieldRectangle = map.GetField(posX, posY), + Gravity = -0.15f, + Bounciness = 0.25f, + Drag = 0.85f + }; + + var stateWaiting = new AiState { Init = InitWaiting }; + stateWaiting.Trigger.Add(new AiTriggerRandomTime(EndWaiting, 200, 200)); + var stateWalking = new AiState(StateWalking) { Init = InitWalking }; + stateWalking.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("waiting"), 132, 132)); + var stateShaking = new AiState(); + stateShaking.Trigger.Add(new AiTriggerCountdown(1000, TickShake, ShakeEnd)); + var stateJumping = new AiState { Init = InitJumping }; + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("waiting", stateWaiting); + _aiComponent.States.Add("walking", stateWalking); + _aiComponent.States.Add("shaking", stateShaking); + _aiComponent.States.Add("jumping", stateJumping); + _damageState = new AiDamageState(this, _body, _aiComponent, sprite, 1) + { + OnDeath = OnDeath + }; + new AiFallState(_aiComponent, _body, null, null, 100); + new AiDeepWaterState(_body); + + _aiComponent.ChangeState("waiting"); + + var damageBox = new CBox(EntityPosition, -6, -11, 0, 12, 11, 4); + var hittableBox = new CBox(EntityPosition, -6, -11, 12, 11, 8); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(BaseAnimationComponent.Index, _animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite)); + + // spawn two gels inactive (needed for the enemy trigger) + _gel0 = new EnemyGel(Map, posX, posY) { IsActive = false }; + Map.Objects.SpawnObject(_gel0); + + _gel1 = new EnemyGel(Map, posX, posY) { IsActive = false }; + Map.Objects.SpawnObject(_gel1); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + // spawn small zols if the damage is not over 1 + if (damage > 1) + { + ((HittableComponent)Components[HittableComponent.Index]).IsActive = false; + _spawnSmallZols = false; + } + else + { + _damageState.SpawnItems = false; + _damageState.DeathAnimation = false; + } + + return _damageState.OnHit(originObject, direction, type, damage, pieceOfPower); + } + + private void InitWaiting() + { + _body.VelocityTarget = Vector2.Zero; + _animator.Play("idle"); + } + + private void EndWaiting() + { + var distance = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + if (distance.Length() > 80 || !_body.FieldRectangle.Intersects(MapManager.ObjLink.BodyRectangle)) + return; + + if (Game1.RandomNumber.Next(0, 10) == 0) + _aiComponent.ChangeState("shaking"); + else + _aiComponent.ChangeState("walking"); + } + + private void InitWalking() + { + _animator.Play("walk"); + } + + private void StateWalking() + { + // walk to the player + MoveToPlayer(0.4f); + } + + private void TickShake(double time) + { + _animationComponent.SpriteOffset.X = -6 + (float)Math.Sin(time / 25f); + _animationComponent.UpdateSprite(); + } + + private void ShakeEnd() + { + _animationComponent.SpriteOffset.X = -6; + _animationComponent.UpdateSprite(); + + _aiComponent.ChangeState("jumping"); + } + + private void InitJumping() + { + _animator.Play("walk"); + + _body.Velocity.Z = _jumpAcceleration; + + // move to the player + MoveToPlayer(1.25f); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X, direction.Y, _body.Velocity.Z); + + return true; + } + + private void OnCollision(Values.BodyCollision type) + { + // hit the floor after a jump + if ((type & Values.BodyCollision.Floor) != 0) + _aiComponent.ChangeState("waiting"); + } + + private void MoveToPlayer(float speed) + { + var vecDirection = new Vector2( + MapManager.ObjLink.PosX - EntityPosition.X, + MapManager.ObjLink.PosY - EntityPosition.Y); + + if (vecDirection == Vector2.Zero) + return; + + vecDirection.Normalize(); + _body.VelocityTarget = vecDirection * speed; + } + + private void OnDeath(bool pieceOfPower) + { + _damageState.BaseOnDeath(pieceOfPower); + + if (!_spawnSmallZols) + { + Map.Objects.DeleteObjects.Add(_gel0); + Map.Objects.DeleteObjects.Add(_gel1); + return; + } + + // positions are set so that the gels are inside of the body to not collide with stuff + _gel0.EntityPosition.Set(new Vector2(EntityPosition.X - 1.9f - Game1.RandomNumber.Next(0, 2), EntityPosition.Y - Game1.RandomNumber.Next(0, 2))); + _gel0.IsActive = true; + _gel0.InitSpawn(); + _gel1.EntityPosition.Set(new Vector2(EntityPosition.X + 2.9f + Game1.RandomNumber.Next(0, 2), EntityPosition.Y - Game1.RandomNumber.Next(0, 2))); + _gel1.IsActive = true; + _gel1.InitSpawn(); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyRiverZora.cs b/InGame/GameObjects/Enemies/EnemyRiverZora.cs new file mode 100644 index 0000000..5818995 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyRiverZora.cs @@ -0,0 +1,172 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyRiverZora : GameObject + { + private readonly AiComponent _aiComponent; + private readonly AiDamageState _damageState; + private readonly BodyComponent _body; + private readonly Animator _animator; + private readonly CSprite _sprite; + + private readonly Rectangle _fieldPosition; + + private float _floatCount; + + public EnemyRiverZora() : base("river zora") { } + + public EnemyRiverZora(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY - 2 + 8, 0); + EntitySize = new Rectangle(-8, -8, 16, 16); + + _fieldPosition = map.GetField(posX, posY); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/river zora"); + _animator.Play("idle"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-8, -8)); + + _body = new BodyComponent(EntityPosition, -6, -5, 12, 10, 8) { DragWater = 0.9f }; + + var stateWaiting = new AiState(); + stateWaiting.Trigger.Add(new AiTriggerCountdown(4000, null, () => _aiComponent.ChangeState("positioning"))); + var statePositioning = new AiState(UpdatePositioning); + var stateSpawning = new AiState() { Init = InitSpawning }; + stateSpawning.Trigger.Add(new AiTriggerCountdown(2000, null, ToIdle)); + var stateIdle = new AiState(UpdateIdle); + stateIdle.Trigger.Add(new AiTriggerCountdown(500, null, ToAttacking)); + var stateAttacking = new AiState(UpdateAttacking); + stateAttacking.Trigger.Add(new AiTriggerCountdown(600, null, ToDespawning)); + var stateDespawning = new AiState(UpdateDespawning); + stateDespawning.Trigger.Add(new AiTriggerCountdown(500, null, ToWait)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("waiting", stateWaiting); + _aiComponent.States.Add("positioning", statePositioning); + _aiComponent.States.Add("spawning", stateSpawning); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("attacking", stateAttacking); + _aiComponent.States.Add("despawning", stateDespawning); + _damageState = new AiDamageState(this, _body, _aiComponent, _sprite, 1) { HitMultiplierX = 1.5f, HitMultiplierY = 1.5f, FlameOffset = new Point(0, 2) }; + + ToWait(); + + AddComponent(BodyComponent.Index, _body); + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, _damageState.OnHit)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer) { WaterOutline = false }); + } + + private void ToWait() + { + _aiComponent.ChangeState("waiting"); + + _floatCount = 0; + _sprite.DrawOffset.Y = -8; + + _sprite.IsVisible = false; + _body.IsGrounded = false; + _damageState.IsActive = false; + + // splash effect + var splashAnimator = new ObjAnimator(Map, 0, 0, 0, 3, Values.LayerPlayer, "Particles/splash", "idle", true); + splashAnimator.EntityPosition.Set(new Vector2( + _body.Position.X + _body.OffsetX + _body.Width / 2f, + _body.Position.Y + _body.OffsetY + _body.Height - _body.Position.Z - 3)); + Map.Objects.SpawnObject(splashAnimator); + } + + private void UpdatePositioning() + { + // try to find a new position + for (var i = 0; i < 25; i++) + { + // find new position + var newPosition = new Vector2( + _fieldPosition.X + Game1.RandomNumber.Next(0, 10) * 16 + 8, + _fieldPosition.Y + Game1.RandomNumber.Next(0, 8) * 16 + 8 - 2); + + var fieldState = Map.GetFieldState(newPosition); + if ((fieldState & MapStates.FieldStates.DeepWater) != 0) + { + EntityPosition.Set(newPosition); + _aiComponent.ChangeState("spawning"); + return; + } + } + } + + private void InitSpawning() + { + _sprite.IsVisible = true; + _animator.Play("spawn"); + } + + private void ToIdle() + { + _aiComponent.ChangeState("idle"); + + _animator.Play("idle"); + _damageState.IsActive = true; + } + + private void UpdateIdle() + { + UpdateOffset(); + } + + private void ToAttacking() + { + var distance = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + if (distance.Length() > 90) + { + ToDespawning(); + return; + } + + _aiComponent.ChangeState("attacking"); + _animator.Play("attack"); + + // spawn a fireball + Map.Objects.SpawnObject(new EnemyFireball(Map, (int)EntityPosition.X, (int)EntityPosition.Y, 1.5f)); + } + + private void UpdateAttacking() + { + UpdateOffset(); + } + + private void ToDespawning() + { + _aiComponent.ChangeState("despawning"); + + _animator.Play("idle"); + } + + private void UpdateDespawning() + { + UpdateOffset(); + } + + private void UpdateOffset() + { + _floatCount += Game1.DeltaTime; + _sprite.DrawOffset.Y = -8 - (float)Math.Sin(_floatCount / 200f); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyRock.cs b/InGame/GameObjects/Enemies/EnemyRock.cs new file mode 100644 index 0000000..a5b1c83 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyRock.cs @@ -0,0 +1,89 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyRock : GameObject + { + private readonly CSprite _sprite; + private readonly BodyComponent _body; + private readonly Vector2 _spawnPosition; + + private double _liveTime = 125; + + public EnemyRock(Map.Map map, Vector2 position) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(position.X, position.Y, Game1.RandomNumber.Next(8, 24)); + EntitySize = new Rectangle(-8, -40, 16, 48); + + _spawnPosition = EntityPosition.Position; + + var animator = AnimatorSaveLoad.LoadAnimator("Enemies/rock"); + animator.Play("idle"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -5, -5, 10, 10, 8) + { + Gravity = -0.125f, + CollisionTypes = Values.CollisionTypes.None + }; + + var damageBox = new CBox(EntityPosition, -6, -6, 0, 12, 12, 8, true); + var hittableBox = new CBox(EntityPosition, -7, -7, 0, 14, 14, 8, true); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(BodyComponent.Index, _body); + AddComponent(PushableComponent.Index, new PushableComponent(damageBox, OnPush)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerTop)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _sprite) { ShadowWidth = 10, ShadowHeight = 6 }); + } + + private void Update() + { + // start despawning + if (EntityPosition.Y > _spawnPosition.Y + 128) + { + _liveTime -= Game1.DeltaTime; + + // fade out + _sprite.Color = Color.White * ((float)_liveTime / 125f); + if (_liveTime < 0) + Map.Objects.DeleteObjects.Add(this); + } + + // bounce in a random direction + if (_body.IsGrounded) + { + Game1.GameManager.PlaySoundEffect("D360-32-20", true, EntityPosition.Position); + + _body.Velocity.Z = Game1.RandomNumber.Next(150, 250) / 100f; + + var length = Game1.RandomNumber.Next(75, 150) / 150f; + var direction = (-100 + Game1.RandomNumber.Next(0, 200)) / 100f; + _body.VelocityTarget = new Vector2(MathF.Sin(direction), MathF.Cos(direction)) * length; + } + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + return Values.HitCollision.Enemy | Values.HitCollision.RepellingParticle; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyRockSpawner.cs b/InGame/GameObjects/Enemies/EnemyRockSpawner.cs new file mode 100644 index 0000000..60bafdd --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyRockSpawner.cs @@ -0,0 +1,47 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Map; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyRockSpawner : GameObject + { + private readonly Rectangle _field; + + private float _spawnCounter; + + public EnemyRockSpawner() : base("rock") { } + + public EnemyRockSpawner(Map.Map map, int posX, int posY, int width, int height) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, width, height); + + _field = new Rectangle(posX, posY, width, height); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + private void Update() + { + if (_field.Contains(MapManager.ObjLink.EntityPosition.Position)) + { + _spawnCounter -= Game1.DeltaTime; + + if (_spawnCounter < 0) + { + _spawnCounter += Game1.RandomNumber.Next(750, 1500); + + var playerPosition = MathHelper.Clamp(MapManager.ObjLink.EntityPosition.X, _field.Left + 80, _field.Right - 80); + + // spawn the rocks around the player inside the field + var posX = playerPosition - 80 + Game1.RandomNumber.Next(0, 160); + var posY = _field.Y - Game1.RandomNumber.Next(0, 16); + var objRock = new EnemyRock(Map, new Vector2(posX, posY)); + Map.Objects.SpawnObject(objRock); + } + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyRope.cs b/InGame/GameObjects/Enemies/EnemyRope.cs new file mode 100644 index 0000000..197a890 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyRope.cs @@ -0,0 +1,156 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyRope : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + + private const float WalkSpeed = 0.5f; + private const float RunSpeed = 1.0f; + + private int _animationDirection; + private int _direction; + + public EnemyRope() : base("rope") { } + + public EnemyRope(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/rope"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -6, -10, 12, 10, 8) + { + MoveCollision = OnCollision, + AbsorbPercentage = 0.9f, + CollisionTypes = + Values.CollisionTypes.Normal | + Values.CollisionTypes.Enemy, + AvoidTypes = + Values.CollisionTypes.Hole | + Values.CollisionTypes.NPCWall | + Values.CollisionTypes.DeepWater, + FieldRectangle = map.GetField(posX, posY), + Drag = 0.85f, + }; + + var stateIdle = new AiState { Init = InitIdle }; + stateIdle.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("walk"), 250, 500)); + var stateWalk = new AiState(UpdateWalk) { Init = InitWalk }; + stateWalk.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("idle"), 750, 1000)); + var stateRun = new AiState { Init = InitRun }; + stateRun.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("idle"), 650, 750)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("walk", stateWalk); + _aiComponent.States.Add("run", stateRun); + new AiFallState(_aiComponent, _body, OnHoleAbsorb, null); + new AiDeepWaterState(_body); + var damageState = new AiDamageState(this, _body, _aiComponent, sprite, 1) { OnBurn = () => _animator.Pause() }; + + _aiComponent.ChangeState("walk"); + + var damageBox = new CBox(EntityPosition, -8, -14, 0, 16, 14, 4); + var hittableBox = new CBox(EntityPosition, -8, -15, 0, 16, 15, 8); + var pushableBox = new CBox(EntityPosition, -7, -14, 0, 14, 14, 8); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, damageState.OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite) { Height = 1.0f, Rotation = 0.1f }); + } + + private void InitIdle() + { + _body.VelocityTarget = new Vector2(0, 0); + _animator.Pause(); + } + + private void InitWalk() + { + // random new direction + _direction = Game1.RandomNumber.Next(0, 4); + _body.VelocityTarget = AnimationHelper.DirectionOffset[_direction] * WalkSpeed; + + SetAnimation(_direction); + } + + private void SetAnimation(int moveDirection) + { + _animator.SpeedMultiplier = 1; + + // look to the left or to the right + if (moveDirection == 0) + _animationDirection = -1; + else if (moveDirection == 2) + _animationDirection = 1; + + _animator.Play("move_" + _animationDirection); + } + + private void UpdateWalk() + { + // is the player on the same line horizontally or vertically? + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDirection.Length() < 64 && + (Math.Abs(playerDirection.X) < 4 || Math.Abs(playerDirection.Y) < 4)) + { + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + + _direction = AnimationHelper.GetDirection(playerDirection); + _body.VelocityTarget = AnimationHelper.DirectionOffset[_direction] * RunSpeed; + + _aiComponent.ChangeState("run"); + } + } + + private void InitRun() + { + SetAnimation(_direction); + _animator.SpeedMultiplier = 2; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X * 1.75f, direction.Y * 1.75f, _body.Velocity.Z); + + return true; + } + + private void OnCollision(Values.BodyCollision direction) + { + if (_aiComponent.CurrentStateId == "walk") + _aiComponent.ChangeState("idle"); + } + + private void OnHoleAbsorb() + { + _animator.SpeedMultiplier = 3f; + _animator.Continue(); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemySeaUrchin.cs b/InGame/GameObjects/Enemies/EnemySeaUrchin.cs new file mode 100644 index 0000000..e80f9b2 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemySeaUrchin.cs @@ -0,0 +1,98 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemySeaUrchin : GameObject + { + private readonly BodyComponent _body; + + private readonly float _moveSpeed = 0.25f; + private readonly int _collisionDamage = 2; + + private Vector2 _lastPosition; + + private float _soundCounter; + + public EnemySeaUrchin() : base("sea urchin") { } + + public EnemySeaUrchin(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _body = new BodyComponent(EntityPosition, -8, -14, 16, 14, 8) + { + Bounciness = 0.25f, + Drag = 0.85f, + CollisionTypes = + Values.CollisionTypes.Normal | + Values.CollisionTypes.Player + }; + + var sprite = new CSprite(EntityPosition); + var animator = AnimatorSaveLoad.LoadAnimator("Enemies/sea urchin"); + animator.Play("idle"); + + // randomize the start frame + animator.SetFrame(Game1.RandomNumber.Next(0, animator.CurrentAnimation.Frames.Length)); + + var animatorComponent = new AnimationComponent(animator, sprite, new Vector2(-8, -16)); + + var aiComponent = new AiComponent(); + aiComponent.States.Add("idle", new AiState()); + var damageState = new AiDamageState(this, _body, aiComponent, sprite, 1) { OnBurn = () => animator.Pause() }; + aiComponent.ChangeState("idle"); + + var hittableBox = new CBox(EntityPosition, -8, -16, 0, 16, 16, 8, true); + + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animatorComponent); + AddComponent(AiComponent.Index, aiComponent); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, damageState.OnHit)); + AddComponent(CollisionComponent.Index, new BodyCollisionComponent(_body, Values.CollisionTypes.Enemy)); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush) { CooldownTime = 0 }); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite) { Height = 1.0f, Rotation = 0.1f }); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type != PushableComponent.PushType.Continues) + return false; + + // push the enemy away if the player is holding a shield in the push direction + if (MapManager.ObjLink.CurrentState == ObjLink.State.Blocking && + AnimationHelper.GetDirection(direction) == MapManager.ObjLink.Direction) + { + _body.Velocity = new Vector3(direction.X, direction.Y, 0) * _moveSpeed; + + // play sound effect + if (_lastPosition != EntityPosition.Position) + { + _soundCounter -= Game1.DeltaTime; + if (_soundCounter < 0) + { + Game1.GameManager.PlaySoundEffect("D360-62-3E", false); + _soundCounter += 75; + } + } + + _lastPosition = EntityPosition.Position; + + return true; + } + + MapManager.ObjLink.HitPlayer(-direction, HitType.Enemy, _collisionDamage, true); + return false; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyShroudedStalfos.cs b/InGame/GameObjects/Enemies/EnemyShroudedStalfos.cs new file mode 100644 index 0000000..7e34392 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyShroudedStalfos.cs @@ -0,0 +1,162 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyShroudedStalfos : GameObject + { + private readonly Animator _animator; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Rectangle _fieldRectangle; + + private readonly Vector2[] _shotOffset = + { + new Vector2(-8, -1),new Vector2(0, -3), + new Vector2(8, -1),new Vector2(0, 2) + }; + + private float _moveSpeed = 0.5f; + private int _direction; + + public EnemyShroudedStalfos() : base("shrouded stalfos") { } + + public EnemyShroudedStalfos(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/shrouded stalfos"); + _animator.Play("walk_1"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -16)); + + _fieldRectangle = map.GetField(posX, posY); + + _body = new BodyComponent(EntityPosition, -6, -10, 12, 10, 8) + { + MoveCollision = OnCollision, + CollisionTypes = Values.CollisionTypes.Normal | + Values.CollisionTypes.Enemy, + AvoidTypes = Values.CollisionTypes.Hole | Values.CollisionTypes.NPCWall, + FieldRectangle = map.GetField(posX, posY), + Bounciness = 0.25f, + Drag = 0.85f + }; + + var walkingState = new AiState { Init = InitWalking }; + walkingState.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("idle"), 550, 850)); + var idleState = new AiState { Init = InitIdle }; + idleState.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("walking"), 300, 500)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("walking", walkingState); + _aiComponent.States.Add("idle", idleState); + new AiFallState(_aiComponent, _body, OnHoleAbsorb); + var damageState = new AiDamageState(this, _body, _aiComponent, sprite, 2) { OnBurn = () => _animator.Pause() }; + + // start randomly idle or walking facing a random direction + _direction = Game1.RandomNumber.Next(0, 4); + _aiComponent.ChangeState(Game1.RandomNumber.Next(0, 2) == 0 ? "walking" : "idle"); + + var damageBox = new CBox(EntityPosition, -8, -12, 0, 16, 12, 4); + var hittabelBox = new CBox(EntityPosition, -7, -15, 14, 15, 8); + var pushableBox = new CBox(EntityPosition, -7, -11, 0, 14, 11, 4); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittabelBox, damageState.OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + } + + private void InitIdle() + { + _animator.Pause(); + _body.VelocityTarget = Vector2.Zero; + + ThrowSpear(); + } + + private void InitWalking() + { + ChangeDirection(); + } + + private void ChangeDirection() + { + // random new direction + _direction = Game1.RandomNumber.Next(0, 4); + _animator.Play("walk_" + _direction); + _body.VelocityTarget = AnimationHelper.DirectionOffset[_direction] * _moveSpeed; + } + + private void ThrowSpear() + { + if (Game1.RandomNumber.Next(0, 2) == 0 || + !_fieldRectangle.Contains(MapManager.ObjLink.EntityPosition.Position)) + return; + + // shoot if the player is in the range and in the right direction + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDirection.Length() < 128) + { + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + var direction = AnimationHelper.GetDirection(playerDirection); + if (direction == _direction) + { + var box = Box.Empty; + if (!Map.Objects.Collision(new Box( + EntityPosition.X + _shotOffset[_direction].X - 4, + EntityPosition.Y + _shotOffset[_direction].Y - 4, 0, 8, 8, 8), + Box.Empty, Values.CollisionTypes.Normal, 0, _body.Level, ref box)) + { + // shoot + var shot = new EnemySpear(Map, new Vector3( + EntityPosition.X + _shotOffset[_direction].X, + EntityPosition.Y + _shotOffset[_direction].Y, 3), + AnimationHelper.DirectionOffset[_direction] * 2f); + Map.Objects.SpawnObject(shot); + } + } + } + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X, direction.Y, _body.Velocity.Z); + + return true; + } + + private void OnCollision(Values.BodyCollision direction) + { + if (_aiComponent.CurrentStateId != "walking") + return; + + // stop walking + _aiComponent.ChangeState("idle"); + } + + private void OnHoleAbsorb() + { + _animator.SpeedMultiplier = 3f; + _animator.Play("walk_" + _direction); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemySpark.cs b/InGame/GameObjects/Enemies/EnemySpark.cs new file mode 100644 index 0000000..8c3db88 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemySpark.cs @@ -0,0 +1,166 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Dungeon; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemySpark : GameObject + { + private readonly BodyComponent _body; + + private readonly Color _lightColor = new Color(255, 255, 255); + + private Vector2 _lastPosition; + private string _destructionKey; + + private double _directionChangeTime; + private float _lightState; + private float _lightCount; + private int _moveDir; + private bool _goingClockwise; + private bool _wasTouchingWall; + private bool _gettingDestroyed; + private bool _init; + + public EnemySpark() : base("spark") { } + + public EnemySpark(Map.Map map, int posX, int posY, int direction, bool clockwise, string destructionKey) : base(map) + { + // maybe create a new tag for enemies that should be ignored by the enemy trigger + Tags = Values.GameObjectTag.Damage; + + EntityPosition = new CPosition(posX + 8, posY + 8, 0); + EntitySize = new Rectangle(-32, -32, 64, 64); + + _lastPosition = EntityPosition.Position; + + _moveDir = direction; + _goingClockwise = clockwise; + _destructionKey = destructionKey; + + var animator = AnimatorSaveLoad.LoadAnimator("Enemies/spark"); + animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(animator, sprite, new Vector2(-8, -8)); + + _body = new BodyComponent(EntityPosition, -4, -4, 8, 8, 8) + { + FieldRectangle = map.GetField(posX, posY), + MoveCollision = OnCollision, + IgnoreHeight = true, + IgnoresZ = true, + CollisionTypes = + Values.CollisionTypes.Normal | + Values.CollisionTypes.Hole | + Values.CollisionTypes.NPCWall + }; + + var damageBox = new CBox(EntityPosition, -8, -8, 0, 16, 16, 4); + var hittableBox = new CBox(EntityPosition, -6, -6, 12, 12, 8); + + if (!string.IsNullOrEmpty(destructionKey)) + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChanged)); + + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer) { WaterOutline = false }); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + AddComponent(LightDrawComponent.Index, new LightDrawComponent(DrawLight)); + } + + public override void Init() + { + _init = true; + base.Init(); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (damageType == HitType.Boomerang) + { + Game1.GameManager.PlaySoundEffect("D360-03-03"); + Destroy(); + return Values.HitCollision.Enemy; + } + + return Values.HitCollision.Blocking; + } + + private void OnKeyChanged() + { + if (_gettingDestroyed || !_init) + return; + + var keyState = Game1.GameManager.SaveManager.GetString(_destructionKey); + if (keyState == "1") + Destroy(); + } + + private void Destroy() + { + _gettingDestroyed = true; + + // remove the enemy + Map.Objects.DeleteObjects.Add(this); + + // spawn explosion effect that ends in a fairy spawning + var animationExplosion = new ObjAnimator(Map, (int)EntityPosition.X - 8, (int)EntityPosition.Y - 8, Values.LayerTop, "Particles/spawn", "run", true); + animationExplosion.Animator.OnAnimationFinished = () => + { + // remove the explosion animation + animationExplosion.Map.Objects.DeleteObjects.Add(animationExplosion); + // spawn fairy + animationExplosion.Map.Objects.SpawnObject(new ObjDungeonFairy(animationExplosion.Map, (int)EntityPosition.X, (int)EntityPosition.Y + 4, 0)); + }; + + Map.Objects.SpawnObject(animationExplosion); + } + + private void OnCollision(Values.BodyCollision collider) + { + if ((collider & Values.BodyCollision.Vertical) != 0 && AnimationHelper.DirectionOffset[_moveDir].Y != 0 || + (collider & Values.BodyCollision.Horizontal) != 0 && AnimationHelper.DirectionOffset[_moveDir].X != 0) + _moveDir = (_moveDir + (_goingClockwise ? 3 : 1)) % 4; + } + + private void Update() + { + _lightCount += Game1.DeltaTime; + _lightState = (int)(Math.Sin(_lightCount / 10f) + 1.5); + + // if the body is not sliding on the wall anymore change the direction + var positionChange = (EntityPosition.Position - _lastPosition) * AnimationHelper.DirectionOffset[(_moveDir + 1) % 4]; + if (positionChange.Length() > 0.0f && (_directionChangeTime + 250 <= Game1.TotalGameTime || _wasTouchingWall)) + { + _directionChangeTime = Game1.TotalGameTime; + _moveDir = (_moveDir + (_goingClockwise ? 1 : 3)) % 4; + } + + _wasTouchingWall = positionChange.Length() == 0.0f; + + var moveVelocity = new Vector2( + AnimationHelper.DirectionOffset[_moveDir].X + AnimationHelper.DirectionOffset[(_moveDir + (_goingClockwise ? 1 : 3)) % 4].X * 0.25f, + AnimationHelper.DirectionOffset[_moveDir].Y + AnimationHelper.DirectionOffset[(_moveDir + (_goingClockwise ? 1 : 3)) % 4].Y * 0.25f); + _body.VelocityTarget = moveVelocity; + + _lastPosition = EntityPosition.Position; + } + + private void DrawLight(SpriteBatch spriteBatch) + { + DrawHelper.DrawLight(spriteBatch, new Rectangle((int)EntityPosition.X - 32, (int)EntityPosition.Y - 32, 64, 64), + _lightColor * (0.125f + _lightState * 0.25f)); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemySpear.cs b/InGame/GameObjects/Enemies/EnemySpear.cs new file mode 100644 index 0000000..f9429f6 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemySpear.cs @@ -0,0 +1,166 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemySpear : GameObject + { + private readonly Animator _animator; + private readonly AiComponent _aiComponent; + private readonly DamageFieldComponent _damageField; + private readonly BodyComponent _body; + private readonly CSprite _drawComponent; + private readonly BodyDrawComponent _bodyDrawComponent; + private readonly ShadowBodyDrawComponent _shadowBody; + + private Vector2 _startPosition; + + private float _despawnPercentage = 1; + private int _despawnTime = 500; + private int dir; + + private Point[] _collisionBoxSize = { new Point(12, 4), new Point(4, 12), new Point(12, 4), new Point(4, 12) }; + + public EnemySpear(Map.Map map, Vector3 position, Vector2 velocity) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(position); + EntitySize = new Rectangle(-8, -8, 16, 16); + + _startPosition = EntityPosition.Position; + + dir = AnimationHelper.GetDirection(velocity); + _animator = AnimatorSaveLoad.LoadAnimator("Objects/spear"); + _animator.Play(dir.ToString()); + + _drawComponent = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _drawComponent, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, + -_collisionBoxSize[dir].X / 2, -_collisionBoxSize[dir].Y / 2, + _collisionBoxSize[dir].X, _collisionBoxSize[dir].Y, 8) + { + CollisionTypes = Values.CollisionTypes.Normal, + MoveCollision = OnCollision, + VelocityTarget = velocity, + Bounciness = 0.35f, + Drag = 0.75f, + IgnoreHeight = true, + IgnoresZ = true, + }; + + var damageCollider = new CBox(EntityPosition, -5, -5, 0, 10, 10, 4, true); + + var stateDespawn = new AiState() { Init = InitDespawn }; + stateDespawn.Trigger.Add(new AiTriggerCountdown(_despawnTime, TickDespawn, () => TickDespawn(0))); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", new AiState(UpdateIdle)); + _aiComponent.States.Add("despawn", stateDespawn); + _aiComponent.ChangeState("idle"); + + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageCollider, HitType.Enemy, 2) { OnDamage = OnDamage }); + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush) { RepelMultiplier = 0.2f }); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, _bodyDrawComponent = new BodyDrawComponent(_body, _drawComponent, Values.LayerPlayer) { Gras = false }); + AddComponent(DrawShadowComponent.Index, _shadowBody = new ShadowBodyDrawComponent(EntityPosition)); + } + + public override void Init() + { + Game1.GameManager.PlaySoundEffect("D378-10-0A"); + } + + private void UpdateIdle() + { + // start falling down? + var distance = _startPosition - EntityPosition.Position; + if (MathF.Abs(distance.X) > 112 || Math.Abs(distance.Y) > 96) + _body.IgnoresZ = false; + } + + private void InitDespawn() + { + _body.IgnoresZ = false; + _damageField.IsActive = false; + _bodyDrawComponent.Gras = true; + + _animator.Play("rotate"); + _animator.SetFrame((dir + 1) % 4); + + Game1.GameManager.PlaySoundEffect("D360-07-07"); + } + + private void TickDespawn(double time) + { + _despawnPercentage = (float)(time / (_despawnTime / 2)); + if (_despawnPercentage > 1) + _despawnPercentage = 1; + + _drawComponent.Color = Color.White * _despawnPercentage; + _shadowBody.Transparency = _despawnPercentage; + + if (time <= 0) + Map.Objects.DeleteObjects.Add(this); + } + + private bool OnDamage() + { + Map.Objects.DeleteObjects.Add(this); + return _damageField.DamagePlayer(); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (_despawnPercentage < 1) + return false; + + if (_aiComponent.CurrentStateId != "despawn") + _aiComponent.ChangeState("despawn"); + + _body.Velocity = new Vector3(direction.X * 0.25f, direction.Y * 0.25f, 1.5f); + _body.VelocityTarget = Vector2.Zero; + + return true; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_despawnPercentage < 1) + return Values.HitCollision.None; + + if (_aiComponent.CurrentStateId != "despawn") + _aiComponent.ChangeState("despawn"); + + _body.Velocity = new Vector3(direction.X, direction.Y, 1.5f); + _body.VelocityTarget = Vector2.Zero; + + return Values.HitCollision.Enemy; + } + + private void OnCollision(Values.BodyCollision direction) + { + if (_aiComponent.CurrentStateId == "despawn") + return; + + _aiComponent.ChangeState("despawn"); + + if ((direction & Values.BodyCollision.Floor) != 0) + _body.Velocity = new Vector3(_body.VelocityTarget.X * 0.75f, _body.VelocityTarget.Y * 0.75f, 1.5f); + else + _body.Velocity = new Vector3(-_body.VelocityTarget.X * 0.25f, -_body.VelocityTarget.Y * 0.25f, 1.5f); + + _body.VelocityTarget = Vector2.Zero; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemySpikedBeetle.cs b/InGame/GameObjects/Enemies/EnemySpikedBeetle.cs new file mode 100644 index 0000000..8ef489d --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemySpikedBeetle.cs @@ -0,0 +1,260 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemySpikedBeetle : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly AnimationComponent _animationComponent; + private readonly AiDamageState _damageState; + + private Vector2 _velocityTarget; + + private float _walkSpeed = 0.5f; + private float _runSpeed = 1.5f; + + private bool _playerInsideField; + + public EnemySpikedBeetle() : base("spiked beetle") { } + + public EnemySpikedBeetle(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/spiked beetle"); + _animator.Play("walk"); + + var sprite = new CSprite(EntityPosition); + _animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -16)); + + var fieldRectangle = map.GetField(posX, posY); + + _body = new BodyComponent(EntityPosition, -6, -10, 12, 9, 8) + { + MoveCollision = OnCollision, + Drag = 0.8f, + Gravity = -0.1f, + Bounciness = 0.5f, + CollisionTypes = Values.CollisionTypes.Normal, + AvoidTypes = Values.CollisionTypes.Hole | + Values.CollisionTypes.NPCWall | + Values.CollisionTypes.DeepWater, + FieldRectangle = fieldRectangle + }; + + var stateWalking = new AiState(UpdateAttack); + stateWalking.Trigger.Add(new AiTriggerRandomTime(ToWaiting, 750, 1000)); + var stateWaiting = new AiState(UpdateAttack); + stateWaiting.Trigger.Add(new AiTriggerRandomTime(ToWalking, 750, 1000)); + var stateBack = new AiState(); + stateBack.Trigger.Add(new AiTriggerCountdown(5000, BackTick, BackEnd)); + var stateRushing = new AiState(); + var stateStunned = new AiState(); + stateStunned.Trigger.Add(new AiTriggerCountdown(1000, null, ToWalking)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("walking", stateWalking); + _aiComponent.States.Add("rushing", stateRushing); + _aiComponent.States.Add("waiting", stateWaiting); + _aiComponent.States.Add("stunned", stateStunned); + _aiComponent.States.Add("back", stateBack); + _damageState = new AiDamageState(this, _body, _aiComponent, sprite, 2); + new AiFallState(_aiComponent, _body, OnAbsorption, null, 250); + new AiDeepWaterState(_body); + + // random start position/state + ToWalking(); + + var damageBox = new CBox(EntityPosition, -8, -12, 0, 16, 12, 4); + var hittableBox = new CBox(EntityPosition, -8, -14, 16, 14, 8); + var pushableBox = new CBox(EntityPosition, -7, -13, 14, 13, 8); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(BaseAnimationComponent.Index, _animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite) { ShadowWidth = 10, ShadowHeight = 5 }); + } + + private void Update() + { + if (_body.FieldRectangle.Contains(MapManager.ObjLink.BodyRectangle)) + _playerInsideField = true; + } + + private void ToWaiting() + { + _animator.Play("walk"); + _animator.IsPlaying = false; + + _aiComponent.ChangeState("waiting"); + _velocityTarget = Vector2.Zero; + _body.VelocityTarget = Vector2.Zero; + } + + private void ToWalking() + { + _animator.Play("walk"); + _aiComponent.ChangeState("walking"); + + var dir = Game1.RandomNumber.Next(0, 4); + _velocityTarget = AnimationHelper.DirectionOffset[dir] * _walkSpeed; + } + + private void ToBack() + { + _animator.Play("back"); + _aiComponent.ChangeState("back"); + _body.VelocityTarget = Vector2.Zero; + _velocityTarget = Vector2.Zero; + } + + private void BackTick(double time) + { + // start shaking + if (time <= 2000) + { + _animationComponent.SpriteOffset.X = -8 + (float)Math.Sin(time / 25f); + _animationComponent.UpdateSprite(); + } + } + + private void BackEnd() + { + _animationComponent.SpriteOffset.X = -8; + _animationComponent.UpdateSprite(); + + _body.Velocity.Z = 1.5f; + ToWalking(); + } + + private void ToRushing(int direction) + { + _body.VelocityTarget = AnimationHelper.DirectionOffset[direction] * _runSpeed; + _aiComponent.ChangeState("rushing"); + _animator.Play("walk"); + } + + private void UpdateAttack() + { + var oldPercentage = (float)Math.Pow(0.9f, Game1.TimeMultiplier); + _body.VelocityTarget = _body.VelocityTarget * oldPercentage + + _velocityTarget * (1 - oldPercentage); + + if (!_playerInsideField) + return; + + var collisionRectangles = new RectangleF[4]; + collisionRectangles[0] = new RectangleF(EntityPosition.X - 128, EntityPosition.Y - 5, 128, 2); + collisionRectangles[1] = new RectangleF(EntityPosition.X, EntityPosition.Y - 128, 2, 128); + collisionRectangles[2] = new RectangleF(EntityPosition.X, EntityPosition.Y - 5, 128, 2); + collisionRectangles[3] = new RectangleF(EntityPosition.X, EntityPosition.Y, 2, 128); + + for (var i = 0; i < collisionRectangles.Length; i++) + if (collisionRectangles[i].Intersects(MapManager.ObjLink.BodyRectangle)) + { + ToRushing(i); + break; + } + + _playerInsideField = false; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_damageState.IsInDamageState()) + return Values.HitCollision.None; + + _body.DragAir = 0.9f; + + if (_aiComponent.CurrentStateId == "back") + return _damageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + + if (damageType == HitType.ThrownObject) + { + _body.Velocity = new Vector3(direction.X * 0.5f, direction.Y * 0.5f, 1.0f); + ToBack(); + + return Values.HitCollision.Enemy; + } + + if (_aiComponent.CurrentStateId == "stunned") + { + _damageState.SetDamageState(false); + _body.Velocity = new Vector3(direction.X * 2.5f, direction.Y * 2.5f, 0); + return Values.HitCollision.RepellingParticle; + } + + _aiComponent.ChangeState("stunned"); + + _body.Velocity = new Vector3(direction.X * 2.5f, direction.Y * 2.5f, 0); + _body.VelocityTarget = Vector2.Zero; + _velocityTarget = Vector2.Zero; + + _animator.IsPlaying = false; + + return Values.HitCollision.RepellingParticle; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + { + _body.DragAir = 0.975f; + if (_aiComponent.CurrentStateId != "back") + { + _body.Velocity = new Vector3(direction.X * 0.75f, direction.Y * 0.75f, 1.5f); + ToBack(); + } + else + { + _body.Velocity = new Vector3(direction.X * 1.0f, direction.Y * 1.0f, _body.Velocity.Z); + } + } + + return true; + } + + private void OnCollision(Values.BodyCollision direction) + { + if (_aiComponent.CurrentStateId == "stunned") + return; + + // stop rushing + if (_aiComponent.CurrentStateId == "rushing") + { + _aiComponent.ChangeState("waiting"); + return; + } + + // collide with a wall + if ((direction & Values.BodyCollision.Horizontal) != 0 && Math.Sign(_body.VelocityTarget.X) == Math.Sign(_velocityTarget.X)) + _velocityTarget.X = -_velocityTarget.X; + else if ((direction & Values.BodyCollision.Vertical) != 0 && Math.Sign(_body.VelocityTarget.Y) == Math.Sign(_velocityTarget.Y)) + _velocityTarget.Y = -_velocityTarget.Y; + } + + private void OnAbsorption() + { + _animator.SpeedMultiplier = 1.5f; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemySpikedThwomp.cs b/InGame/GameObjects/Enemies/EnemySpikedThwomp.cs new file mode 100644 index 0000000..8f87d40 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemySpikedThwomp.cs @@ -0,0 +1,189 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Base.Systems; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class EnemySpikedThwomp : GameObject + { + private readonly List _collidingObjects = new List(); + + private readonly Animator _animator; + private readonly AiComponent _aiComponent; + private readonly BodyComponent _body; + + private readonly CBox _collisionBox; + + private readonly Vector2 _startPosition; + + private Box _lastCollisionBox; + + public EnemySpikedThwomp() : base("spiked thwomp") { } + + public EnemySpikedThwomp(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX + 16, posY + 16, 0); + EntitySize = new Rectangle(-16, -16, 32, 32); + + _startPosition = EntityPosition.Position; + + _body = new BodyComponent(EntityPosition, -16, -16, 32, 31, 8) + { + Gravity2D = 0.175f, + IgnoresZ = true, + CollisionTypes = + Values.CollisionTypes.Normal | Values.CollisionTypes.NPCWall, + MoveCollision = OnCollision + }; + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/spiked thwomp"); + _animator.Play("attack"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-16, -16)); + + var stateIdle = new AiState(UpdateIdle); + var stateAttack = new AiState(); + var stateAttackCooldown = new AiState(); + stateAttackCooldown.Trigger.Add(new AiTriggerCountdown(1000, null, ToGoingUp)); // 800 closer to the actual value + var stateGoingUp = new AiState(UpdateGoingUp); + var stateUpWaiting = new AiState(); + stateUpWaiting.Trigger.Add(new AiTriggerCountdown(600, null, ToIdle)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("attack", stateAttack); + _aiComponent.States.Add("attackCooldown", stateAttackCooldown); + _aiComponent.States.Add("goingUp", stateGoingUp); + _aiComponent.States.Add("upWaiting", stateUpWaiting); + + _aiComponent.ChangeState("idle"); + + var damageBox = new CBox(EntityPosition, -14, -16, 28, 32, 4); + var hittableBox = new CBox(EntityPosition, -14, -16, 28, 32, 8); + _collisionBox = new CBox(EntityPosition, -16, -16, 32, 4, 8); + + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(_collisionBox, Values.CollisionTypes.Enemy)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerBottom)); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + return Values.HitCollision.RepellingParticle; + } + + private void ToIdle() + { + _aiComponent.ChangeState("idle"); + } + + private void UpdateIdle() + { + // look at the player + var lookDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + + var radiant = MathF.Atan2(lookDirection.X, -lookDirection.Y); + + var clampedValue = Math.Clamp((Math.Abs(radiant) - 0.75f) / (MathF.PI - 1.25f), 0, 2); + var animationDir = (int)(clampedValue * 3) + 1; + + if (animationDir <= 3) + _animator.Play((radiant < 0 ? "l" : "r") + animationDir); + else + _animator.Play("down"); + + // start attacking? + if (Math.Abs(lookDirection.X) < 22) + { + ToAttacking(); + } + } + + private void ToAttacking() + { + _aiComponent.ChangeState("attack"); + _animator.Play("attack"); + _body.IgnoresZ = false; + Game1.GameManager.PlaySoundEffect("D360-08-08"); + } + + private void ToGoingUp() + { + _aiComponent.ChangeState("goingUp"); + _body.IgnoresZ = true; + _body.Velocity.Y = 0; + } + + private void UpdateGoingUp() + { + _lastCollisionBox = _collisionBox.Box; + + EntityPosition.Move(new Vector2(0, -0.5f)); + if (EntityPosition.Y < _startPosition.Y) + { + EntityPosition.Set(new Vector2(EntityPosition.X, _startPosition.Y)); + _aiComponent.ChangeState("upWaiting"); + } + + MoveBodies(); + } + + private void OnCollision(Values.BodyCollision collision) + { + if ((collision & Values.BodyCollision.Bottom) != 0 && + _aiComponent.CurrentStateId == "attack") + { + HitGround(); + } + } + + private void HitGround() + { + // shake the screen + Game1.GameManager.ShakeScreen(750, 0, 2, 2f, 5.5f); + + Game1.GameManager.PlaySoundEffect("D378-12-0C"); + + _aiComponent.ChangeState("attackCooldown"); + } + + private void MoveBodies() + { + // check for colliding bodies and push them forward + _collidingObjects.Clear(); + Map.Objects.GetComponentList(_collidingObjects, + (int)_lastCollisionBox.Left, (int)_lastCollisionBox.Back - 8, + (int)_lastCollisionBox.Width, (int)_lastCollisionBox.Height, BodyComponent.Mask); + + foreach (var collidingObject in _collidingObjects) + { + var body = (BodyComponent)collidingObject.Components[BodyComponent.Index]; + + // the enemy move into the body that was on top of him + if (body.BodyBox.Box.Front <= _lastCollisionBox.Back && + body.BodyBox.Box.Front >= _collisionBox.Box.Back && + body.BodyBox.Box.Intersects(_collisionBox.Box)) + { + // move the body up + var offset = new Vector2(0, _collisionBox.Box.Back - body.BodyBox.Box.Front - 0.001f); + SystemBody.MoveBody(body, offset, body.CollisionTypes, false, false, false); + body.Position.NotifyListeners(); + } + } + } + } +} diff --git a/InGame/GameObjects/Enemies/EnemySpinyBeetle.cs b/InGame/GameObjects/Enemies/EnemySpinyBeetle.cs new file mode 100644 index 0000000..d74dcf7 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemySpinyBeetle.cs @@ -0,0 +1,261 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemySpinyBeetle : GameObject + { + public override bool IsActive + { + set + { + base.IsActive = value; + _carriedObject.IsActive = value; + } + } + + private readonly GameObject _carriedObject; + private readonly CarriableComponent _carriableComponent; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly CSprite _sprite; + private readonly AiDamageState _aiDamageState; + private readonly AiTriggerTimer _hiddenTimer; + private readonly DamageFieldComponent _damageField; + + private Rectangle _fieldRectangle; + + // 0: grass + // 1: stone + // 2: skull + private readonly int _type; + + private bool _bushDestroyed; + + public EnemySpinyBeetle() : base("spiny beetle") { } + + public EnemySpinyBeetle(Map.Map map, int posX, int posY, int type) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 7, 0); + EntitySize = new Rectangle(-8, -7, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/spiny beetle"); + _animator.Play("idle"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-8, -4)); + + _fieldRectangle = map.GetField(posX, posY); + + _body = new BodyComponent(EntityPosition, -7, -2, 14, 10, 8) + { + MoveCollision = OnCollision, + HoleAbsorb = OnHoleAbsorb, + Drag = 0.8f, + AvoidTypes = Values.CollisionTypes.Hole | + Values.CollisionTypes.NPCWall, + FieldRectangle = _fieldRectangle + }; + + // spawn a bush carried by the beetle + if (type == 0) + _carriedObject = new ObjBush(map, posX, posY, null, "bush_0", true, true, false, Values.LayerPlayer, null) { RespawnGras = false }; + else if (type == 1) + _carriedObject = new ObjStone(map, posX, posY, "stone_0", null, null, null, false, false); + else + _carriedObject = new ObjStone(map, posX, posY, "skull", null, null, null, false, false); + + _type = type; + + // deactivate physics + var body = (BodyComponent)_carriedObject.Components[BodyComponent.Index]; + if (body != null) + { + body.IsActive = false; + } + + _carriableComponent = (CarriableComponent)_carriedObject.Components[CarriableComponent.Index]; + + var stateInit = new AiState(); + stateInit.Trigger.Add(new AiTriggerCountdown(1500, null, () => _aiComponent.ChangeState("hiding"))); + var stateHiding = new AiState(UpdateHiding); + stateHiding.Trigger.Add(_hiddenTimer = new AiTriggerTimer(500)); + var stateMoving = new AiState(); + stateMoving.Trigger.Add(new AiTriggerRandomTime(ToHide, 550, 850)); + var stateRunning = new AiState(); + stateRunning.Trigger.Add(new AiTriggerRandomTime(ChangeDirection, 550, 850)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("init", stateInit); + _aiComponent.States.Add("hiding", stateHiding); + _aiComponent.States.Add("moving", stateMoving); + _aiComponent.States.Add("running", stateRunning); + new AiFallState(_aiComponent, _body); + _aiDamageState = new AiDamageState(this, _body, _aiComponent, _sprite, 1); + + _aiComponent.ChangeState("moving"); + + var damageCollider = new CBox(EntityPosition, -7, -4, 0, 14, 10, 4); + var hittableRectangle = new CBox(EntityPosition, -6, -4, 12, 10, 8); + + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageCollider, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableRectangle, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(_sprite)); + + EntityPosition.AddPositionListener(typeof(EnemySpinyBeetle), UpdateObjPosition); + map.Objects.SpawnObject(_carriedObject); + UpdateObjPosition(EntityPosition); + + ToHide(); + + _aiComponent.ChangeState("init"); + } + + private void UpdateObjPosition(CPosition newPosition) + { + if (_aiComponent.CurrentStateId != "hiding" && _aiComponent.CurrentStateId != "moving") + return; + + var offset = _aiComponent.CurrentStateId == "hiding" ? 0 : 4; + var offsetY = _type == 0 ? 1 : 6; + _carriedObject.EntityPosition.Set(new CPosition(newPosition.X, newPosition.Y + offsetY, newPosition.Z + offset)); + } + + private int PlayerDirection() + { + var distance = MapManager.ObjLink.EntityPosition.Position - (EntityPosition.Position + new Vector2(0, 9)); + + if (_fieldRectangle.Contains(MapManager.ObjLink.PosX, MapManager.ObjLink.PosY)) + { + // horizontally + if (Math.Abs(distance.Y) < 8 && distance.Length() < 64) + return Math.Sign(distance.X) < 0 ? 0 : 2; + // down + if (Math.Abs(distance.X) < 8 && distance.Y > 0 && distance.Y < 32) + return 3; + } + + return -1; + } + + private void ToHide() + { + if (_aiComponent.CurrentStateId != "moving" || (PlayerDirection() >= 0 && _body.LastVelocityCollision == 0)) + return; + + _damageField.IsActive = false; + _body.VelocityTarget = Vector2.Zero; + _sprite.IsVisible = false; + _aiComponent.ChangeState("hiding"); + + UpdateObjPosition(EntityPosition); + } + + private void UpdateHiding() + { + var playerDirection = PlayerDirection(); + if (playerDirection >= 0 && _hiddenTimer.State) + { + ToWalk(); + _body.VelocityTarget = AnimationHelper.DirectionOffset[playerDirection]; + } + + // object was destroyed or picked up? + if (_carriedObject.IsDead || (_carriableComponent != null && _carriableComponent.IsPickedUp)) + { + ToRunning(); + _body.VelocityTarget = Vector2.Zero; + } + } + + private void Show() + { + _sprite.IsVisible = true; + _damageField.IsActive = true; + } + + private void ToWalk() + { + Show(); + UpdateObjPosition(EntityPosition); + _aiComponent.ChangeState("moving"); + } + + private void ToRunning() + { + Show(); + ChangeDirection(); + _aiComponent.ChangeState("running"); + } + + private void ChangeDirection() + { + var randomDir = Game1.RandomNumber.Next(0, 100); + var directionRadius = (float)(Math.PI * 2 * (randomDir / 100.0f)); + _body.VelocityTarget = new Vector2((float)Math.Cos(directionRadius), (float)Math.Sin(directionRadius)); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X * 1.5f, direction.Y * 1.5f, _body.Velocity.Z); + + return true; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (!_bushDestroyed && _type == 0) + { + _bushDestroyed = true; + + if (!_carriedObject.IsDead) + ((ObjBush)_carriedObject).DestroyBush(direction); + + if (damageType == HitType.Bomb || damageType == HitType.Bow || damageType == HitType.Hookshot) + return Values.HitCollision.Blocking; + } + + // gets repelled by the stone/skull + if (_type > 0 && _aiComponent.CurrentStateId != "running") + { + _body.Velocity = new Vector3(direction.X * 0.25f, direction.Y * 0.25f, _body.Velocity.Z); + return Values.HitCollision.RepellingParticle; + } + + _sprite.IsVisible = true; + + return _aiDamageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + } + + private void OnCollision(Values.BodyCollision direction) + { + // collided with a wall? + if ((direction & (Values.BodyCollision.Horizontal | Values.BodyCollision.Vertical)) != 0) + { + ToHide(); + } + } + + private void OnHoleAbsorb() + { + _animator.SpeedMultiplier = 2.0f; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyStalfosGreen.cs b/InGame/GameObjects/Enemies/EnemyStalfosGreen.cs new file mode 100644 index 0000000..76fe3c3 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyStalfosGreen.cs @@ -0,0 +1,224 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyStalfosGreen : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly AnimationComponent _animatorComponent; + + private readonly Rectangle _fieldRectangle; + + private float _walkSpeed = 0.5f; + private float _changeDirCount; + private int _dir; + + private bool _jumpMoving; + + public EnemyStalfosGreen() : base("stalfos green") { } + + public EnemyStalfosGreen(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -40, 16, 40); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/stalfos green"); + _animator.Play("walk"); + + var sprite = new CSprite(EntityPosition); + _animatorComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -16)); + + _fieldRectangle = map.GetField(posX, posY); + + _body = new BodyComponent(EntityPosition, -6, -10, 11, 10, 8) + { + MoveCollision = OnCollision, + Gravity = -0.075f, + AvoidTypes = Values.CollisionTypes.Hole | Values.CollisionTypes.NPCWall, + FieldRectangle = _fieldRectangle + }; + + _aiComponent = new AiComponent(); + + var stateWalking = new AiState(UpdateWalking); + var stateMoveUp = new AiState(UpdateMoveUp); + var stateWait = new AiState(); + stateWait.Trigger.Add(new AiTriggerCountdown(250, null, ToMoveDown)); + var stateMoveDown = new AiState(UpdateMoveDown); + var stateWaitFloor = new AiState(); + stateWaitFloor.Trigger.Add(new AiTriggerCountdown(250, null, ToWalk)); + + _aiComponent.States.Add("walking", stateWalking); + _aiComponent.States.Add("moveUp", stateMoveUp); + _aiComponent.States.Add("wait", stateWait); + _aiComponent.States.Add("moveDown", stateMoveDown); + _aiComponent.States.Add("waitFloor", stateWaitFloor); + new AiFallState(_aiComponent, _body, null, null, 300); + var damageState = new AiDamageState(this, _body, _aiComponent, sprite, 2) { OnBurn = () => _animator.Pause() }; + _aiComponent.ChangeState("walking"); + + var damageBox = new CBox(EntityPosition, -7, -15, 2, 13, 15, 4); + var hittableBox = new CBox(EntityPosition, -7, -15, 2, 13, 15, 8); + var pushableBox = new CBox(EntityPosition, -6, -14, 2, 12, 14, 4); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, damageState.OnHit)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, _animatorComponent); + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite) { ShadowWidth = 10 }); + } + + public void SetAirPosition(int posZ) + { + EntityPosition.SetZ(posZ); + _animator.Play("jump"); + ToMoveDown(); + + // randomize the walk speed so that when two are spawned at the same position they will not + // stay at the same position + _walkSpeed = Game1.RandomNumber.Next(45, 55) / 100f; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X * 1.75f, direction.Y * 1.75f, _body.Velocity.Z); + + return true; + } + + private void ToWalk() + { + _aiComponent.ChangeState("walking"); + } + + private void UpdateWalking() + { + _animator.Play("walk"); + + // jump away when the player is pressing the use key + var direction = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + var distance = direction.Length(); + + if (_fieldRectangle.Contains(MapManager.ObjLink.EntityPosition.Position) && distance < 56) + { + if (distance < 24) + ToJumping(); + else if (distance < 56) + { + // move towards the player + direction.Normalize(); + _body.VelocityTarget = direction * _walkSpeed; + } + } + else + { + _changeDirCount -= Game1.DeltaTime; + + // change direction + if (_changeDirCount <= 0) + ChangeDirection(); + } + } + + private void ToJumping() + { + _aiComponent.ChangeState("moveUp"); + + Game1.GameManager.PlaySoundEffect("D360-36-24"); + + _animator.Play("jump"); + + _body.Velocity.Z = 2; + _jumpMoving = true; + } + + private void UpdateMoveUp() + { + // start waiting in the air + if (EntityPosition.Z > 26 || _body.Velocity.Z <= 0) + { + ToWait(); + return; + } + + // move towards the player + if (_jumpMoving) + { + var vecDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (vecDirection.Length() < 2) + { + _jumpMoving = false; + return; + } + + vecDirection.Normalize(); + _body.VelocityTarget = vecDirection * _walkSpeed * 2; + } + } + + private void ToWait() + { + _aiComponent.ChangeState("wait"); + + _body.VelocityTarget = Vector2.Zero; + _body.IgnoresZ = true; + } + + private void ToMoveDown() + { + _aiComponent.ChangeState("moveDown"); + + _body.Velocity.Z = -3.5f; + _body.IgnoresZ = false; + } + + private void UpdateMoveDown() + { + if (_body.IsGrounded) + ToWaitFloor(); + } + + private void ToWaitFloor() + { + _aiComponent.ChangeState("waitFloor"); + + Game1.GameManager.PlaySoundEffect("D360-07-07"); + + // this is green in the original + var animation = new ObjAnimator(Map, 0, 0, Values.LayerTop, "Particles/swordPoke", "run", true); + animation.EntityPosition.Set(new Vector2(EntityPosition.X, EntityPosition.Y + 4)); + Map.Objects.SpawnObject(animation); + } + + private void OnCollision(Values.BodyCollision collision) + { + if ((collision & Values.BodyCollision.Floor) != 0 && _aiComponent.CurrentStateId == "moveDown") + ToWaitFloor(); + if ((collision & (Values.BodyCollision.Horizontal | Values.BodyCollision.Vertical)) != 0) + ChangeDirection(); + } + + private void ChangeDirection() + { + _changeDirCount = Game1.RandomNumber.Next(200, 600); + _dir = Game1.RandomNumber.Next(0, 4); + _body.VelocityTarget = AnimationHelper.DirectionOffset[_dir] * _walkSpeed; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyStalfosKnight.cs b/InGame/GameObjects/Enemies/EnemyStalfosKnight.cs new file mode 100644 index 0000000..c4e6319 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyStalfosKnight.cs @@ -0,0 +1,218 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyStalfosKnight : GameObject + { + public BodyComponent Body; + + private readonly EnemyStalfosKnightSword _sword; + private readonly Animator _animator; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _damageState; + private readonly CSprite _sprite; + + private Rectangle _fieldRectangle; + + private const float MoveSpeed = 0.5f; + private const float AttackSpeed = 0.55f; + private const int AttackRange = 80; + + private int _direction; + + private bool _isActive = true; + public override bool IsActive + { + set + { + _sword.IsActive = value; + _isActive = value; + } + get => _isActive; + } + + public EnemyStalfosKnight(Map.Map map, int posX, int posY) : base(map) + { + SprEditorImage = Resources.SprEnemies; + EditorIconSource = new Rectangle(168, 272, 18, 23); + + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/stalfos knight"); + _animator.Play("walk_1"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-8, -16)); + + _fieldRectangle = map.GetField(posX, posY); + + Body = new BodyComponent(EntityPosition, -6, -10, 12, 10, 8) + { + MoveCollision = OnCollision, + CollisionTypes = Values.CollisionTypes.Normal | + Values.CollisionTypes.Enemy, + AvoidTypes = Values.CollisionTypes.Hole | Values.CollisionTypes.NPCWall, + FieldRectangle = _fieldRectangle, + Bounciness = 0.25f, + AbsorbPercentage = 0.9f, + Drag = 0.85f + }; + + var stateIdle = new AiState { Init = InitIdle }; + stateIdle.Trigger.Add(new AiTriggerRandomTime(EndIdle, 300, 500)); + var stateWalk = new AiState { Init = InitWalking }; + stateWalk.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("idle"), 550, 850)); + var stateAttack = new AiState(StateAttack); + + _aiComponent = new AiComponent(); + _aiComponent.Trigger.Add(new AiTriggerUpdate(UpdateDamageTick)); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("walking", stateWalk); + _aiComponent.States.Add("attack", stateAttack); + new AiFallState(_aiComponent, Body, OnHoleAbsorb, OnAbsorbDeath); + _damageState = new AiDamageState(this, Body, _aiComponent, _sprite, 2) + { + OnDeath = OnDeath, + OnBurn = OnBurn + }; + + var damageBox = new CBox(EntityPosition, -8, -12, 0, 16, 12, 4); + var hittableBox = new CBox(EntityPosition, -4, -14, 8, 12, 8); + var pushableBox = new CBox(EntityPosition, -7, -11, 0, 14, 11, 4); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, _damageState.OnHit)); + AddComponent(BodyComponent.Index, Body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(Body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(_sprite)); + + _sword = new EnemyStalfosKnightSword(Map, this); + } + + public override void Init() + { + // add the sword to the map + Map.Objects.SpawnObject(_sword); + + // start randomly idle or walking facing a random direction + _direction = Game1.RandomNumber.Next(0, 4); + _aiComponent.ChangeState(Game1.RandomNumber.Next(0, 2) == 0 ? "walking" : "idle"); + } + + private void OnBurn() + { + _animator.Pause(); + _sword.Animator.Pause(); + } + + private void UpdateDamageTick() + { + _sword.Sprite.SpriteShader = _sprite.SpriteShader; + } + + private void InitIdle() + { + _animator.Play("stand_" + _direction); + _sword.Animator.Play("stand_" + _direction); + Body.VelocityTarget = Vector2.Zero; + } + + private void EndIdle() + { + var distance = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + + if (_fieldRectangle.Contains(MapManager.ObjLink.PosX, MapManager.ObjLink.PosY) && distance.Length() < AttackRange) + _aiComponent.ChangeState("attack"); + else + _aiComponent.ChangeState("walking"); + } + + private void InitWalking() + { + ChangeDirection(); + } + + private void StateAttack() + { + var direction = (MapManager.ObjLink.EntityPosition.Position + AnimationHelper.DirectionOffset[_direction] * 3) - EntityPosition.Position; + + if (!_fieldRectangle.Contains(MapManager.ObjLink.PosX, MapManager.ObjLink.PosY) || + direction.Length() > AttackRange) + { + _aiComponent.ChangeState("idle"); + return; + } + + if (direction != Vector2.Zero) + direction.Normalize(); + + Body.VelocityTarget = direction * AttackSpeed; + + _direction = AnimationHelper.GetDirection(direction); + _animator.Play("walk_" + _direction); + _sword.Animator.Play("walk_" + _direction); + + _animator.SpeedMultiplier = 2f; + _sword.Animator.SpeedMultiplier = 2f; + } + + private void ChangeDirection() + { + // random new direction + _direction = Game1.RandomNumber.Next(0, 4); + _animator.Play("walk_" + _direction); + _sword.Animator.Play("walk_" + _direction); + Body.VelocityTarget = AnimationHelper.DirectionOffset[_direction] * MoveSpeed; + } + + private void OnDeath(bool pieceOfPower) + { + _damageState.BaseOnDeath(pieceOfPower); + + Map.Objects.DeleteObjects.Add(_sword); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + Body.Velocity = new Vector3(direction.X, direction.Y, Body.Velocity.Z); + + return true; + } + + private void OnCollision(Values.BodyCollision direction) + { + if (_aiComponent.CurrentStateId != "walking") + return; + + // stop walking + _aiComponent.ChangeState("idle"); + } + + private void OnHoleAbsorb() + { + _animator.SpeedMultiplier = 3f; + _animator.Play("walk_" + _direction); + _sword.Animator.SpeedMultiplier = 3f; + _sword.Animator.Play("walk_" + _direction); + } + + private void OnAbsorbDeath() + { + Map.Objects.DeleteObjects.Add(_sword); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyStalfosKnightSword.cs b/InGame/GameObjects/Enemies/EnemyStalfosKnightSword.cs new file mode 100644 index 0000000..d3cf44e --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyStalfosKnightSword.cs @@ -0,0 +1,87 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyStalfosKnightSword : GameObject + { + public readonly Animator Animator; + public readonly CSprite Sprite; + + private readonly EnemyStalfosKnight _owner; + private readonly CBox _collisionBox; + + private double _lastHitTime; + + public EnemyStalfosKnightSword(Map.Map map, EnemyStalfosKnight owner) : base(map) + { + _owner = owner; + _owner.EntityPosition.AddPositionListener(typeof(EnemyStalfosKnightSword), PositionChange); + + EntityPosition = new CPosition(owner.EntityPosition.X, owner.EntityPosition.Y - 1, owner.EntityPosition.Z); + EntitySize = new Rectangle(-22, -8 - 24, 44, 48); + + Animator = AnimatorSaveLoad.LoadAnimator("Enemies/stalfos knight sword"); + + Sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(Animator, Sprite, new Vector2(-8, -15)); + + _collisionBox = new CBox(0, 0, 0, 0, 0, 4); + UpdateCollisionBox(); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(_collisionBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(_collisionBox, OnHit)); + AddComponent(PushableComponent.Index, new PushableComponent(_collisionBox, OnPush) { RepelParticle = true }); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(Sprite, Values.LayerPlayer)); + } + + private void PositionChange(CPosition position) + { + EntityPosition.Set(new Vector2(position.X, position.Y - position.Z - 1)); + } + + private void Update() + { + UpdateCollisionBox(); + } + + private void UpdateCollisionBox() + { + _collisionBox.Box.X = EntityPosition.X - 8 + Animator.CollisionRectangle.X; + _collisionBox.Box.Y = EntityPosition.Y - 15 + Animator.CollisionRectangle.Y; + _collisionBox.Box.Width = Animator.CollisionRectangle.Width; + _collisionBox.Box.Height = Animator.CollisionRectangle.Height; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + { + _owner.Body.Velocity.X = direction.X * 1.5f; + _owner.Body.Velocity.Y = direction.Y * 1.5f; + } + + return true; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (damageType == HitType.MagicRod || damageType == HitType.MagicPowder || damageType == HitType.Bow || damageType == HitType.Hookshot || damageType == HitType.Boomerang || + (_lastHitTime != 0 && Game1.TotalGameTime - _lastHitTime < 250)) + return Values.HitCollision.None; + + _lastHitTime = Game1.TotalGameTime; + + _owner.Body.Velocity.X = direction.X * 1.5f; + _owner.Body.Velocity.Y = direction.Y * 1.5f; + + return Values.HitCollision.RepellingParticle; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyStalfosOrange.cs b/InGame/GameObjects/Enemies/EnemyStalfosOrange.cs new file mode 100644 index 0000000..8a0510d --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyStalfosOrange.cs @@ -0,0 +1,163 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyStalfosOrange : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly AiTriggerTimer _jumpSwitch; + + private readonly bool _isBoneThrower; + + private float _acceleration = 1.75f; + private float _walkSpeed = 0.5f; + private float _changeDirCount; + private int _dir; + + private float _throwCounter; + private bool _throwBone; + + public EnemyStalfosOrange() : base("stalfos orange") { } + + public EnemyStalfosOrange(Map.Map map, int posX, int posY, bool isBoneThrower) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + _isBoneThrower = isBoneThrower; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -32, 16, 32); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/stalfos orange"); + _animator.Play("walk"); + + var sprite = new CSprite(EntityPosition); + var animatorComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -16)); + + var fieldRectangle = map.GetField(posX, posY); + + _body = new BodyComponent(EntityPosition, -6, -10, 11, 10, 8) + { + MoveCollision = OnCollision, + Gravity = -0.1f, + CollisionTypes = Values.CollisionTypes.Normal | Values.CollisionTypes.NPCWall, + AvoidTypes = Values.CollisionTypes.Hole | Values.CollisionTypes.NPCWall, + FieldRectangle = fieldRectangle + }; + + _aiComponent = new AiComponent(); + + var stateWalking = new AiState(UpdateWalking); + stateWalking.Trigger.Add(_jumpSwitch = new AiTriggerTimer(75)); + var stateJumping = new AiState(UpdateJumping); + + _aiComponent.States.Add("walking", stateWalking); + _aiComponent.States.Add("jumping", stateJumping); + new AiFallState(_aiComponent, _body, null, null, 200); + var damageState = new AiDamageState(this, _body, _aiComponent, sprite, 2) { OnBurn = () => _animator.Pause() }; + _aiComponent.ChangeState("walking"); + + var damageBox = new CBox(EntityPosition, -7, -15, 2, 13, 15, 4); + var hittableBox = new CBox(EntityPosition, -7, -15, 2, 13, 15, 8); + var pushableBox = new CBox(EntityPosition, -6, -14, 2, 12, 14, 4); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, damageState.OnHit)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animatorComponent); + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite) { ShadowWidth = 10 }); + } + + private void UpdateWalking() + { + _animator.Play("walk"); + + if (_throwBone) + { + _throwCounter -= Game1.DeltaTime; + if (_throwCounter < 0) + { + _throwBone = false; + + // throw a bone towards the player + Map.Objects.SpawnObject(new EnemyBone(Map, (int)EntityPosition.X, (int)EntityPosition.Y - 8, 1.5f)); + } + } + + // jump away when the player is pressing the use key + var distance = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + if (_jumpSwitch.State && distance.Length() < 48) + for (var i = 0; i < 4; i++) + if (ControlHandler.ButtonPressed((CButtons)((int)CButtons.A * Math.Pow(2, i)))) + { + ToJumping(); + break; + } + + _changeDirCount -= Game1.DeltaTime; + + // change direction + if (_changeDirCount <= 0) + ChangeDirection(); + } + + private void ToJumping() + { + Game1.GameManager.PlaySoundEffect("D360-36-24"); + + _aiComponent.ChangeState("jumping"); + + // jump away from the player + var vecDirection = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + vecDirection.Normalize(); + _body.Velocity = new Vector3(0, 0, _acceleration); + _body.VelocityTarget = new Vector2(vecDirection.X, vecDirection.Y); + + _throwBone = _isBoneThrower; + _throwCounter = 300; + } + + private void UpdateJumping() + { + _animator.Play("jump"); + + if (_body.IsGrounded) + _aiComponent.ChangeState("walking"); + } + + private void ChangeDirection() + { + _changeDirCount = Game1.RandomNumber.Next(200, 600); + _dir = Game1.RandomNumber.Next(0, 4); + _body.VelocityTarget = AnimationHelper.DirectionOffset[_dir] * _walkSpeed; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X * 1.75f, direction.Y * 1.75f, _body.Velocity.Z); + + return true; + } + + private void OnCollision(Values.BodyCollision collision) + { + if (_aiComponent.CurrentStateId == "walking") + ChangeDirection(); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyStar.cs b/InGame/GameObjects/Enemies/EnemyStar.cs new file mode 100644 index 0000000..bff4e1d --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyStar.cs @@ -0,0 +1,85 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyStar : GameObject + { + private readonly BodyComponent _body; + + public EnemyStar() : base("star") { } + + public EnemyStar(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + var animator = AnimatorSaveLoad.LoadAnimator("Enemies/star"); + animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(animator, sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -6, -11, 12, 10, 8) + { + FieldRectangle = map.GetField(posX, posY), + MoveCollision = OnCollision, + CollisionTypes = + Values.CollisionTypes.Normal | + Values.CollisionTypes.Hole | + Values.CollisionTypes.NPCWall + }; + _body.VelocityTarget = new Vector2(-1, 1) * (3 / 4.0f); + + var aiComponent = new AiComponent(); + aiComponent.States.Add("idle", new AiState()); + var damageState = new AiDamageState(this, _body, aiComponent, sprite, 1, false) { OnBurn = () => animator.Pause() }; + + aiComponent.ChangeState("idle"); + + var damageBox = new CBox(EntityPosition, -7, -14, 0, 14, 13, 4); + var hittableBox = new CBox(EntityPosition, -7, -14, 0, 14, 13, 8); + var pushableBox = new CBox(EntityPosition, -6, -13, 0, 12, 12, 8); + + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, damageState.OnHit)); + AddComponent(AiComponent.Index, aiComponent); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + { + _body.Velocity = new Vector3(direction.X * 1.5f, direction.Y * 1.5f, _body.Velocity.Z); + + var dir = AnimationHelper.GetDirection(direction); + if (dir % 2 == 0) + _body.VelocityTarget.X = -_body.VelocityTarget.X; + else + _body.VelocityTarget.Y = -_body.VelocityTarget.Y; + } + + return true; + } + + private void OnCollision(Values.BodyCollision collider) + { + if ((collider & Values.BodyCollision.Horizontal) != 0) + _body.VelocityTarget.X = -_body.VelocityTarget.X; + if ((collider & Values.BodyCollision.Vertical) != 0) + _body.VelocityTarget.Y = -_body.VelocityTarget.Y; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyTektite.cs b/InGame/GameObjects/Enemies/EnemyTektite.cs new file mode 100644 index 0000000..5deb4d9 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyTektite.cs @@ -0,0 +1,127 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyTektite : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + + private readonly Rectangle _fieldRectangle; + + public EnemyTektite() : base("tektite") { } + + public EnemyTektite(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -32, 16, 32); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/tektite"); + _animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animatorComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -16)); + + _fieldRectangle = map.GetField(posX, posY); + + _body = new BodyComponent(EntityPosition, -6, -10, 12, 10, 8) + { + Gravity = -0.05f, + DragAir = 0.85f, + CollisionTypes = Values.CollisionTypes.Normal | Values.CollisionTypes.NPCWall, + AvoidTypes = Values.CollisionTypes.Hole | Values.CollisionTypes.NPCWall, + FieldRectangle = _fieldRectangle + }; + + _aiComponent = new AiComponent(); + + var stateIdle = new AiState() { Init = InitIdle }; + stateIdle.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("jumping"), 750, 1250)); + var stateJumping = new AiState(UpdateJumping) { Init = InitJumping }; + + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("jumping", stateJumping); + new AiFallState(_aiComponent, _body, null, null, 300); + var damageState = new AiDamageState(this, _body, _aiComponent, sprite, 2) { OnBurn = OnBurn }; + _aiComponent.ChangeState("idle"); + + var damageBox = new CBox(EntityPosition, -6, -12, 0, 12, 12, 4); + var hittableBox = new CBox(EntityPosition, -7, -12, 0, 14, 12, 8, true); + var pushableBox = new CBox(EntityPosition, -7, -12, 0, 14, 12, 8, true); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, damageState.OnHit)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animatorComponent); + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite) { ShadowWidth = 10 }); + } + + private void OnBurn() + { + _body.Bounciness = 0.45f; + _animator.Pause(); + } + + private void InitIdle() + { + _body.VelocityTarget = Vector2.Zero; + _animator.Play("idle"); + } + + private void InitJumping() + { + Game1.GameManager.PlaySoundEffect("D360-36-24", true, EntityPosition.Position); + + _animator.Play("jump"); + + // jump towards the player if he is in the range + Vector2 vecDirection; + if (_fieldRectangle.Contains(MapManager.ObjLink.PosX, MapManager.ObjLink.PosY) || + !_fieldRectangle.Contains(EntityPosition.X, EntityPosition.Y)) + { + vecDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + vecDirection.Normalize(); + vecDirection *= 1.25f; + } + else + { + var randomDir = Game1.RandomNumber.Next(0, 100) / 100.0f; + var directionRadius = (float)(Math.PI * 2 * randomDir); + vecDirection = new Vector2((float)Math.Cos(directionRadius), (float)Math.Sin(directionRadius)); + vecDirection *= 0.75f; + } + + _body.VelocityTarget = vecDirection; + _body.Velocity.Z = 1.0f; + } + + private void UpdateJumping() + { + // finished jumping + if (_body.IsGrounded) + _aiComponent.ChangeState("idle"); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X * 1.75f, direction.Y * 1.75f, _body.Velocity.Z); + + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyThwimp.cs b/InGame/GameObjects/Enemies/EnemyThwimp.cs new file mode 100644 index 0000000..c62ecdc --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyThwimp.cs @@ -0,0 +1,127 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyThwimp : GameObject + { + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly BodyComponent _body; + + private const float ResturnSpeed = 0.5f; + + public EnemyThwimp() : base("thwimp") { } + + public EnemyThwimp(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Damage; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -64, 16, 114); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/thwimp"); + _animator.Play("idle"); + + _body = new BodyComponent(EntityPosition, -7, -16, 14, 16, 8) + { + MoveCollision = OnCollision, + Drag = 0.8f, + IgnoresZ = true, + Gravity2D = 0.165f + }; + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -16)); + + var stateIdle = new AiState(UpdateIdle); + var stateFall = new AiState { Init = InitFall }; + var stateWait = new AiState { Init = InitWait }; + stateWait.Trigger.Add(new AiTriggerCountdown(700, null, () => _aiComponent.ChangeState("return"))); + var stateReturn = new AiState { Init = InitReturn }; + var stateReturned = new AiState { Init = InitReturned }; + stateReturned.Trigger.Add(new AiTriggerCountdown(550, null, () => _aiComponent.ChangeState("idle"))); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("fall", stateFall); + _aiComponent.States.Add("wait", stateWait); + _aiComponent.States.Add("return", stateReturn); + _aiComponent.States.Add("returned", stateReturned); + _aiComponent.ChangeState("idle"); + + var damageBox = new CBox(EntityPosition, -5, -10, 0, 10, 8, 4); + var hittableBox = new CBox(EntityPosition, -5, -10, 0, 10, 8, 8); + + AddComponent(BodyComponent.Index, _body); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerBottom)); + } + + private void UpdateIdle() + { + // trigger trap + var distance = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + var distanceH = Math.Abs(distance.X); + + var angry = distanceH < 40; + _animator.Play(angry ? "angry" : "idle"); + + if (distanceH < 22) + { + _aiComponent.ChangeState("fall"); + } + } + + private void InitFall() + { + // start falling down + _body.IgnoresZ = false; + _animator.Play("angry"); + + Game1.GameManager.PlaySoundEffect("D360-08-08"); + } + + private void InitWait() + { + _animator.Play("idle"); + + Game1.GameManager.PlaySoundEffect("D360-09-09"); + Game1.GameManager.ShakeScreen(75, 0, 1, 0, 500); + } + + private void InitReturn() + { + _body.IgnoresZ = true; + _body.VelocityTarget.Y = -ResturnSpeed; + } + + private void InitReturned() + { + _body.VelocityTarget.Y = 0; + } + + private void OnCollision(Values.BodyCollision collision) + { + if ((collision & Values.BodyCollision.Bottom) != 0 && _aiComponent.CurrentStateId == "fall") + _aiComponent.ChangeState("wait"); + else if ((collision & Values.BodyCollision.Top) != 0 && _aiComponent.CurrentStateId == "return") + _aiComponent.ChangeState("returned"); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + return Values.HitCollision.RepellingParticle; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyTorchTrap.cs b/InGame/GameObjects/Enemies/EnemyTorchTrap.cs new file mode 100644 index 0000000..888d942 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyTorchTrap.cs @@ -0,0 +1,59 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + class EnemyTorchTrap : GameObject + { + private readonly Rectangle _fieldRectangle; + private readonly string _key; + + private float _fireballCounter; + private const int FireballTime = 3000; + private bool _isActive; + + public EnemyTorchTrap() : base("torch trap") { } + + public EnemyTorchTrap(Map.Map map, int posX, int posY, string key) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 8, 0); + EntitySize = new Rectangle(-8, -8, 16, 16); + + _fieldRectangle = map.GetField(posX, posY, 16); + + _key = key; + + if (!string.IsNullOrEmpty(_key)) + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChanged)); + else + _isActive = true; + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + private void OnKeyChanged() + { + _isActive = Game1.GameManager.SaveManager.GetString(_key) != "1"; + } + + private void Update() + { + if (!_isActive || !_fieldRectangle.Contains(MapManager.ObjLink.EntityPosition.Position)) + return; + + _fireballCounter += Game1.DeltaTime; + if (_fireballCounter < FireballTime) + return; + + _fireballCounter -= FireballTime; + + // spawn a fireball? + var distance = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + if (distance.Length() < 106) + Map.Objects.SpawnObject(new EnemyFireball(Map, (int)EntityPosition.X, (int)EntityPosition.Y, 1.25f)); + } + } +} diff --git a/InGame/GameObjects/Enemies/EnemyVacuum.cs b/InGame/GameObjects/Enemies/EnemyVacuum.cs new file mode 100644 index 0000000..c12dc87 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyVacuum.cs @@ -0,0 +1,197 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyVacuum : GameObject + { + private readonly List _collidingObjects = new List(); + + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly AiDamageState _damageState; + + private Box _absorbBox; + private Box _rangeBox; + private Rectangle _fieldRectangle; + + private readonly string _roomName; + private readonly string _entryId; + private readonly bool _isPusher; + + public EnemyVacuum() : base("vacuum") { } + + public EnemyVacuum(Map.Map map, int posX, int posY, string roomName, string entryId, bool isPusher) : base(map) + { + Tags = Values.GameObjectTag.Trap; + + EntityPosition = new CPosition(posX + 8, posY + 8, 0); + EntitySize = new Rectangle(-8, -8, 16, 16); + + _roomName = roomName; + _entryId = entryId; + + _isPusher = isPusher; + + _rangeBox = map.GetFieldBox(posX, posY, 64, isPusher ? 0 : 8); + _fieldRectangle = map.GetField(posX, posY); + _absorbBox = new Box(posX, posY, 0, 16, 16, 32); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/vacuum"); + _animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -8)); + + _body = new BodyComponent(EntityPosition, -7, -7, 14, 14, 8) + { + IgnoreHoles = true + }; + + var stateIdle = new AiState { Init = InitIdle }; + if (_isPusher) + stateIdle.Trigger.Add(new AiTriggerCountdown(1000, null, ToVacuum)); + else + stateIdle.Trigger.Add(new AiTriggerRandomTime(ToVacuum, 1000, 1500)); + var stateVacuum = new AiState(UpdateVacuum) { Init = InitVacuum }; + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("vacuum", stateVacuum); + _damageState = new AiDamageState(this, _body, _aiComponent, sprite, 1) + { + MoveBody = false, + ExplosionOffsetY = 4 + }; + + // random start position/state + _aiComponent.ChangeState("idle"); + + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + + if (!_isPusher) + { + // POLISH: center the player when he gets absorbed + AddComponent(CollisionComponent.Index, + new BoxCollisionComponent(new CBox(posX + 3, posY + 2, 0, 10, 12, 16), Values.CollisionTypes.Hole)); + AddComponent(ObjectCollisionComponent.Index, + new ObjectCollisionComponent(new Rectangle(posX + 6, posY + 6, 4, 4), OnCollision)); + } + + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerBottom)); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (damageType == HitType.Hookshot || + damageType == HitType.MagicRod || + damageType == HitType.MagicPowder || + damageType == HitType.Bow || + damageType == HitType.Boomerang) + return Values.HitCollision.None; + + // dont draw trail particle + return _damageState.OnHit(gameObject, direction, damageType, damage, false); + } + + private void OnCollision(GameObject gameObject) + { + MapManager.ObjLink.HoleResetRoom = _roomName; + MapManager.ObjLink.HoleResetEntryId = _entryId; + + MapManager.ObjLink.MapTransitionStart = null; + MapManager.ObjLink.MapTransitionEnd = null; + } + + private void ToVacuum() + { + // is the player in the current room? + if (_fieldRectangle.Contains(MapManager.ObjLink.EntityPosition.Position)) + _aiComponent.ChangeState("vacuum"); + else + _aiComponent.ChangeState("idle"); + } + + private void InitIdle() + { + _animator.Play("idle"); + } + + private void InitVacuum() + { + _animator.Play("vacuum"); + } + + private void UpdateVacuum() + { + if (!_animator.IsPlaying) + { + _aiComponent.ChangeState("idle"); + return; + } + + Game1.GameManager.PlaySoundEffect("D378-31-1F", false); + + _collidingObjects.Clear(); + Map.Objects.GetComponentList(_collidingObjects, (int)_rangeBox.X, (int)_rangeBox.Y, + (int)_rangeBox.Width, (int)_rangeBox.Height, BodyComponent.Mask); + + foreach (var collidingObject in _collidingObjects) + { + if (collidingObject == this) + continue; + + var body = (BodyComponent)collidingObject.Components[BodyComponent.Index]; + + // absorb enemies that fully collide with the box + if (collidingObject.Tags == Values.GameObjectTag.Enemy && _absorbBox.Contains(body.BodyBox.Box)) + { + Map.Objects.DeleteObjects.Add(collidingObject); + continue; + } + + if (body.IsAbsorbed || !_rangeBox.Contains(body.BodyBox.Box)) + continue; + + var direction = EntityPosition.Position - body.BodyBox.Box.Center; + + if (direction != Vector2.Zero) + direction.Normalize(); + + // push objects? + if (_isPusher) + { + var distance = (EntityPosition.Position - body.Position.Position).Length(); + var multiplier = Math.Clamp((112 - distance) / 16, 0, 1.5f); + + body.AdditionalMovementVT.X = -multiplier * direction.X; + body.AdditionalMovementVT.Y = -multiplier * direction.Y; + } + else + { + // rotate player + if (collidingObject is ObjLink) + MapManager.ObjLink.RotatePlayer(); + + body.AdditionalMovementVT.X = 0.5f * direction.X; + body.AdditionalMovementVT.Y = 0.5f * direction.Y; + } + + body.DisableVelocityTargetMultiplier = true; + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyVire.cs b/InGame/GameObjects/Enemies/EnemyVire.cs new file mode 100644 index 0000000..39a2b1c --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyVire.cs @@ -0,0 +1,354 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using ProjectZ.InGame.GameObjects.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyVire : GameObject + { + private readonly EnemyVireBat _batLeft; + private readonly EnemyVireBat _batRight; + + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly AiDamageState _damageState; + + private readonly Rectangle _roomRectangle; + private readonly Vector2 _roomCenter; + + private const float DashSpeed = 2.0f; + + private const int CircleWidth = 80; + private const int CircleHeight = 60; + private const int FlyHeight = 41; + + private Vector2 _targetPosition; + private int _circleDirection; + + public EnemyVire() : base("vire") { } + + public EnemyVire(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-12, -64, 24, 64); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/vire"); + _animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animatorComponent = new AnimationComponent(_animator, sprite, Vector2.Zero); + + var fieldRectangle = map.GetField(posX, posY, 8); + + _body = new BodyComponent(EntityPosition, -8, -15, 16, 15, 8) + { + IgnoresZ = true, + IgnoreHoles = true, + Gravity = -0.125f, + DragAir = 0.975f, + Bounciness = 0.25f, + CollisionTypes = Values.CollisionTypes.None + }; + + _roomRectangle = Map.GetField(posX, posY); + _roomCenter = new Vector2(fieldRectangle.Center.X, fieldRectangle.Center.Y); + + _aiComponent = new AiComponent(); + + var stateDebug = new AiState(); + var stateIdle = new AiState(UpdateIdle); + var stateFlying = new AiState(UpdateFlying) { Init = InitFlying }; + var stateCircling = new AiState(UpdateCircling) { Init = InitCircling }; + stateCircling.Trigger.Add(new AiTriggerCountdown(2000, null, RandomAttack)); + var statePreAttack = new AiState() { Init = InitPreAttack }; + statePreAttack.Trigger.Add(new AiTriggerCountdown(100, null, () => _aiComponent.ChangeState("attack"))); + var stateAttack = new AiState(UpdateAttack) { Init = InitAttack }; + var statePreDash = new AiState() { Init = InitPreDash }; + statePreDash.Trigger.Add(new AiTriggerCountdown(500, null, () => _aiComponent.ChangeState("dash"))); + var stateDash = new AiState(UpdateDash) { Init = InitDash }; + stateDash.Trigger.Add(new AiTriggerCountdown(750, null, () => _aiComponent.ChangeState("repelled"))); + var stateRepelled = new AiState(UpdateRepelled); + stateRepelled.Trigger.Add(new AiTriggerCountdown(750, null, () => _aiComponent.ChangeState("circling"))); + + _aiComponent.States.Add("debug", stateDebug); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("flying", stateFlying); + _aiComponent.States.Add("circling", stateCircling); + _aiComponent.States.Add("preAttack", statePreAttack); + _aiComponent.States.Add("attack", stateAttack); + _aiComponent.States.Add("preDash", statePreDash); + _aiComponent.States.Add("dash", stateDash); + _aiComponent.States.Add("repelled", stateRepelled); + _damageState = new AiDamageState(this, _body, _aiComponent, sprite, 3) { OnBurn = OnBurn }; + new AiFallState(_aiComponent, _body, null, null); + new AiDeepWaterState(_body); + + _aiComponent.ChangeState("idle"); + + var damageBox = new CBox(EntityPosition, -8, -15, 0, 16, 15, 8, true); + var hittableBox = new CBox(EntityPosition, -10, -15, 0, 20, 15, 8, true); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(PushableComponent.Index, new PushableComponent(damageBox, OnPush)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animatorComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer) { WaterOutline = false }); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite) { ShadowWidth = 10, ShadowHeight = 5 }); + + _batLeft = new EnemyVireBat(Map, EntityPosition.ToVector3(), new Vector2(-0.75f, 0)) { IsActive = false }; + _batRight = new EnemyVireBat(Map, EntityPosition.ToVector3(), new Vector2(0.75f, 0)) { IsActive = false }; + Map.Objects.SpawnObject(_batLeft); + Map.Objects.SpawnObject(_batRight); + } + + private void UpdateIdle() + { + var distVec = EntityPosition.Position - new Vector2(MapManager.ObjLink.PosX, MapManager.ObjLink.PosY + 16); + + // start flying if the player gets near + if (distVec.Length() < 60) + _aiComponent.ChangeState("flying"); + } + + private void RandomAttack() + { + if (!_roomRectangle.Contains(MapManager.ObjLink.EntityPosition.Position)) + return; + + if (Game1.RandomNumber.Next(0, 3) == 0) + _aiComponent.ChangeState("preDash"); + else + _aiComponent.ChangeState("preAttack"); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + if (type == HitType.Bow) + damage = 1; + + if (_aiComponent.CurrentStateId == "idle") + _aiComponent.ChangeState("flying"); + + var hitReturn = _damageState.OnHit(originObject, direction, type, damage, pieceOfPower); + + if (_damageState.CurrentLives <= 0) + SpawnBats(); + + return hitReturn; + } + + private void SpawnBats() + { + var spawnPosition = new Vector3(EntityPosition.X, EntityPosition.Y, EntityPosition.Z); + + // spawn the explosion effect + var splashAnimator = new ObjAnimator(Map, (int)spawnPosition.X - 8, + (int)spawnPosition.Y - (int)spawnPosition.Z - 16, 0, 0, Values.LayerTop, "Particles/spawn", "run", true); + Map.Objects.SpawnObject(splashAnimator); + + // spawn the bats + _batLeft.IsActive = true; + _batLeft.EntityPosition.Set(spawnPosition); + _batRight.IsActive = true; + _batRight.EntityPosition.Set(spawnPosition); + + Map.Objects.DeleteObjects.Add(this); + } + + private void OnBurn() + { + _body.IgnoresZ = false; + _animator.Pause(); + } + + private void UpdateRepelled() + { + // get repelled by the player + var playerDirection = new Vector2(EntityPosition.X, EntityPosition.Y - EntityPosition.Z) - + MapManager.ObjLink.EntityPosition.Position; + if (playerDirection != Vector2.Zero && playerDirection.Length() < 64) + { + playerDirection.Normalize(); + + // dodge to the side + var centerDirection = _roomCenter - new Vector2(EntityPosition.X, EntityPosition.Y - EntityPosition.Z); + if (centerDirection != Vector2.Zero) + centerDirection.Normalize(); + var moveDirection = new Vector2(centerDirection.Y, -centerDirection.X) * _circleDirection; + + _body.VelocityTarget = Vector2.Lerp(_body.VelocityTarget, moveDirection * 2f + playerDirection * 1.5f, 0.025f * Game1.TimeMultiplier); + } + else + { + _body.VelocityTarget = Vector2.Lerp(_body.VelocityTarget, Vector2.Zero, 0.05f * Game1.TimeMultiplier); + } + + // move up + if (EntityPosition.Z + 1 * Game1.TimeMultiplier < FlyHeight) + EntityPosition.Z += 1 * Game1.TimeMultiplier; + else + EntityPosition.Z = FlyHeight; + } + + private void InitPreDash() + { + _body.VelocityTarget = Vector2.Zero; + _animator.Play("attack"); + } + + private void InitDash() + { + _animator.Play("fly"); + + var playerDirection = MapManager.ObjLink.EntityPosition.Position - new Vector2(EntityPosition.X, EntityPosition.Y - 12); + if (playerDirection != Vector2.Zero) + { + playerDirection.Normalize(); + _body.VelocityTarget = playerDirection * DashSpeed; + } + } + + private void UpdateDash() + { + // move down + if (EntityPosition.Z - 1 * Game1.TimeMultiplier > 12) + EntityPosition.Z -= 1 * Game1.TimeMultiplier; + else + EntityPosition.Z = 12; + } + + private void InitPreAttack() + { + _animator.Play("attack"); + } + + private void InitAttack() + { + var startPosition = new Vector2(EntityPosition.X, EntityPosition.Y - EntityPosition.Z - 8); + var direction = MapManager.ObjLink.EntityPosition.Position - startPosition; + var radiant = MathF.Atan2(direction.Y, direction.X); + + var dist = 0.125f; + var vireball0 = new EnemyVireball(Map, startPosition, new Vector2(MathF.Cos(radiant - dist), MathF.Sin(radiant - dist) * 1.5f)); + Map.Objects.SpawnObject(vireball0); + var vireball1 = new EnemyVireball(Map, startPosition, new Vector2(MathF.Cos(radiant + dist), MathF.Sin(radiant + dist) * 1.5f)); + Map.Objects.SpawnObject(vireball1); + } + + private void UpdateAttack() + { + if (!_animator.IsPlaying) + { + _animator.Play("fly"); + _aiComponent.ChangeState("circling"); + } + } + + private void InitFlying() + { + var playerDirection = _roomCenter - MapManager.ObjLink.EntityPosition.Position; + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + + _targetPosition = _roomCenter + new Vector2(playerDirection.X * CircleWidth, playerDirection.Y * CircleHeight + FlyHeight + 16); + } + + private void UpdateFlying() + { + _animator.Play("fly"); + + var reachedTarget = true; + + // move towards the target position + var distVec = _targetPosition - EntityPosition.Position; + if (distVec.Length() > 0.5f * Game1.TimeMultiplier) + { + distVec.Normalize(); + _body.VelocityTarget = distVec * 0.5f; + reachedTarget = false; + } + else + { + _body.VelocityTarget = Vector2.Zero; + EntityPosition.Set(_targetPosition); + } + + // fly up + if (EntityPosition.Z + 0.5f * Game1.TimeMultiplier < FlyHeight) + { + EntityPosition.Z += 0.5f * Game1.TimeMultiplier; + reachedTarget = false; + } + else + { + EntityPosition.Z = FlyHeight; + } + + // finished flying up and moving towards the target? + if (reachedTarget) + { + _aiComponent.ChangeState("circling"); + } + } + + private void InitCircling() + { + _circleDirection = Game1.RandomNumber.Next(0, 1) * 2 - 1; + } + + private void UpdateCircling() + { + var playerDirection = new Vector2(EntityPosition.X, EntityPosition.Y - EntityPosition.Z) - + MapManager.ObjLink.EntityPosition.Position; + if (playerDirection.Length() < 40) + { + _aiComponent.ChangeState("repelled"); + } + + var centerDirection = _roomCenter - new Vector2(EntityPosition.X, EntityPosition.Y - EntityPosition.Z); + if (centerDirection != Vector2.Zero) + centerDirection.Normalize(); + + var moveDirection = new Vector2(centerDirection.Y, -centerDirection.X) * _circleDirection; + var angle = MathF.Atan2(centerDirection.Y, centerDirection.X); + + // distance to the ellipse + var e = MathF.Sqrt(1 - (float)(CircleHeight * CircleHeight) / (CircleWidth * CircleWidth)); + var distance = CircleHeight / MathF.Sqrt(1 - MathF.Pow(e * MathF.Cos(angle), 2)); + var circleVector = -centerDirection * distance; + + var targetPosition = _roomCenter + circleVector; + var entityPosition = new Vector2(EntityPosition.X, EntityPosition.Y - EntityPosition.Z); + var circleDirection = targetPosition - entityPosition; + + // slow down to not overshoot while moving towards the circle + if (circleDirection.Length() > 16) + circleDirection.Normalize(); + else + circleDirection /= 16; + + // move towards the circle/ around the circle + _body.VelocityTarget = Vector2.Lerp(_body.VelocityTarget, moveDirection * 0.5f + circleDirection, 0.1f * Game1.TimeMultiplier); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X * 1.75f, direction.Y * 1.75f, _body.Velocity.Z); + + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyVireBat.cs b/InGame/GameObjects/Enemies/EnemyVireBat.cs new file mode 100644 index 0000000..6303cea --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyVireBat.cs @@ -0,0 +1,131 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using System; +using ProjectZ.InGame.Map; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyVireBat : GameObject + { + private readonly BodyComponent _body; + private readonly CSprite _sprite; + private double _liveTime = 1250; + + private const float AttackSpeed = 2.0f; + + private bool _isAttackable; + + public EnemyVireBat(Map.Map map, Vector3 position, Vector2 direction) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(position.X, position.Y, position.Z); + EntitySize = new Rectangle(-8, -48, 16, 48); + + var animator = AnimatorSaveLoad.LoadAnimator("Enemies/vire bat"); + animator.Play("idle"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(animator, _sprite, Vector2.Zero); + + var _aiComponent = new AiComponent(); + + var stateMove = new AiState(); + stateMove.Trigger.Add(new AiTriggerCountdown(500, null, () => _aiComponent.ChangeState("wait"))); + var stateWait = new AiState() { Init = InitWait }; + stateWait.Trigger.Add(new AiTriggerCountdown(500, null, () => _aiComponent.ChangeState("attack"))); + var stateAttack = new AiState(UpdateAttack) { Init = InitAttack }; + + _aiComponent.States.Add("move", stateMove); + _aiComponent.States.Add("wait", stateWait); + // it would probably look better if we move down while attacking + _aiComponent.States.Add("attack", stateAttack); + + _aiComponent.ChangeState("move"); + + _body = new BodyComponent(EntityPosition, -5, -12, 10, 12, 8) + { + IgnoresZ = true, + IgnoreHoles = true, + VelocityTarget = direction, + CollisionTypes = Values.CollisionTypes.None + }; + + var damageCollider = new CBox(EntityPosition, -5, -6, 0, 10, 6, 8, true); + var hittableBox = new CBox(EntityPosition, -4, -12, 0, 8, 12, 8, true); + + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 2)); + AddComponent(BodyComponent.Index, _body); + AddComponent(PushableComponent.Index, new PushableComponent(damageCollider, OnPush)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _sprite)); + } + + private void InitAttack() + { + var playerDirection = MapManager.ObjLink.EntityPosition.Position - + new Vector2(EntityPosition.X, EntityPosition.Y - EntityPosition.Z); + if (playerDirection != Vector2.Zero) + { + playerDirection.Normalize(); + _body.VelocityTarget = playerDirection * AttackSpeed; + } + } + + private void UpdateAttack() + { + _liveTime -= Game1.DeltaTime; + + // fade out + if (_liveTime <= 100) + _sprite.Color = Color.White * ((float)_liveTime / 100f); + + if (_liveTime < 0) + Map.Objects.DeleteObjects.Add(this); + } + + private void InitWait() + { + _isAttackable = true; + _body.VelocityTarget = Vector2.Zero; + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + if (!_isAttackable) + return Values.HitCollision.None; + + OnDeath(); + + return Values.HitCollision.Enemy; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X * 1.75f, direction.Y * 1.75f, _body.Velocity.Z); + + return true; + } + + private void OnDeath() + { + var splashAnimator = new ObjAnimator(Map, 0, 0, 0, 0, Values.LayerTop, "Particles/spawn", "run", true); + splashAnimator.EntityPosition.Set(new Vector2(EntityPosition.X - 8, EntityPosition.Y - EntityPosition.Z - 16)); + Map.Objects.SpawnObject(splashAnimator); + + Game1.GameManager.PlaySoundEffect("D378-19-13"); + + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyVireball.cs b/InGame/GameObjects/Enemies/EnemyVireball.cs new file mode 100644 index 0000000..d646bcf --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyVireball.cs @@ -0,0 +1,87 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyVireball : GameObject + { + private readonly CSprite _sprite; + private double _liveTime = 2500; + + public EnemyVireball(Map.Map map, Vector2 position, Vector2 velocity) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(position.X, position.Y, 0); + EntitySize = new Rectangle(-5, -5, 10, 10); + + var animator = AnimatorSaveLoad.LoadAnimator("Enemies/vireball"); + animator.Play("idle"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(animator, _sprite, Vector2.Zero); + + var body = new BodyComponent(EntityPosition, -5, -5, 10, 10, 8) + { + IgnoresZ = true, + IgnoreHoles = true, + CollisionTypes = Values.CollisionTypes.None + }; + + body.VelocityTarget = velocity; + + var damageCollider = new CBox(EntityPosition, -3, -3, 0, 6, 6, 4); + var hittableBox = new CBox(EntityPosition, -4, -4, 0, 8, 8, 8); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 2)); + AddComponent(BodyComponent.Index, body); + AddComponent(PushableComponent.Index, new PushableComponent(body.BodyBox, OnPush)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerTop)); + } + + private void Update() + { + _liveTime -= Game1.DeltaTime; + + // fade out + if (_liveTime <= 100) + _sprite.Color = Color.White * ((float)_liveTime / 100f); + + if (_liveTime < 0) + Map.Objects.DeleteObjects.Add(this); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + OnDeath(); + + return Values.HitCollision.Enemy; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + OnDeath(); + + return true; + } + + private void OnDeath() + { + var splashAnimator = new ObjAnimator(Map, 0, 0, 0, 0, Values.LayerTop, "Particles/spawn", "run", true); + splashAnimator.EntityPosition.Set(EntityPosition.Position - new Vector2(8, 8)); + Map.Objects.SpawnObject(splashAnimator); + + // TODO: add sound effect + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyWaterTektite.cs b/InGame/GameObjects/Enemies/EnemyWaterTektite.cs new file mode 100644 index 0000000..fa78c46 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyWaterTektite.cs @@ -0,0 +1,131 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyWaterTektite : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiTriggerRandomTime _movementTimer; + + private float _currentSpeed; + private int _currentDir; + + public static Vector2[] Directions = + { + new Vector2(-1, -1), new Vector2(-1, 1), new Vector2(1, 1), new Vector2(1, -1) + }; + + public EnemyWaterTektite() : base("water tektite") { } + + public EnemyWaterTektite(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + var animator = AnimatorSaveLoad.LoadAnimator("Enemies/water tektite"); + animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(animator, sprite, new Vector2(-8, -16)); + + var fieldRectangle = map.GetField(posX, posY); + + _body = new BodyComponent(EntityPosition, -7, -14, 14, 12, 8) + { + MoveCollision = OnCollision, + CollisionTypes = + Values.CollisionTypes.Normal | + Values.CollisionTypes.Enemy | + Values.CollisionTypes.Player, + AvoidTypes = Values.CollisionTypes.Hole | + Values.CollisionTypes.NPCWall, + FieldRectangle = fieldRectangle, + Bounciness = 0.25f, + Drag = 0.85f, + IgnoreHeight = true, + }; + + var hittableBox = new CBox(EntityPosition, -7, -15, 14, 14, 8); + var damageBox = new CBox(EntityPosition, -7, -15, 0, 14, 13, 4); + + var stateMoving = new AiState(UpdateMoving); + stateMoving.Trigger.Add(_movementTimer = new AiTriggerRandomTime(ToStop, 400, 750)); + var stateWaiting = new AiState(); + stateWaiting.Trigger.Add(new AiTriggerRandomTime(ToMoving, 300, 500)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("moving", stateMoving); + _aiComponent.States.Add("waiting", stateWaiting); + var damageState = new AiDamageState(this, _body, _aiComponent, sprite, 1) { OnBurn = () => animator.Pause() };//, false); + + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, damageState.OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer) { WaterOutline = false }); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + + ToMoving(); + } + + private void OnCollision(Values.BodyCollision collision) + { + ToStop(); + } + + private void ToMoving() + { + _aiComponent.ChangeState("moving"); + + // TODO: should not be a constant velocity + _currentDir = Game1.RandomNumber.Next(0, 4); + } + + private void UpdateMoving() + { + // speed up or slow down + if (_movementTimer.CurrentTime > 100) + { + _currentSpeed += 0.05f * Game1.TimeMultiplier; + if (_currentSpeed > 0.75f) + _currentSpeed = 0.75f; + } + else + { + _currentSpeed -= 0.05f * Game1.TimeMultiplier; + if (_currentSpeed < 0) + _currentSpeed = 0; + } + + _body.VelocityTarget = Directions[_currentDir] * _currentSpeed; + } + + private void ToStop() + { + _currentSpeed = 0; + _body.VelocityTarget = Vector2.Zero; + + if (_aiComponent.CurrentStateId == "moving") + _aiComponent.ChangeState("waiting"); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X, direction.Y, _body.Velocity.Z); + + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyWizzrobe.cs b/InGame/GameObjects/Enemies/EnemyWizzrobe.cs new file mode 100644 index 0000000..64ea324 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyWizzrobe.cs @@ -0,0 +1,188 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyWizzrobe : GameObject + { + private readonly AiComponent _aiComponent; + private readonly AiDamageState _damageState; + private readonly BodyComponent _body; + private readonly Animator _animator; + private readonly CSprite _sprite; + private readonly PushableComponent _pushComponent; + private readonly AiTriggerTimer _hiddenTimer; + private readonly DamageFieldComponent _damageField; + private readonly AiStunnedState _aiStunnedState; + + private readonly Rectangle _fieldRectangle; + + private const int BlinkTime = 600; + private int _direction; + + public EnemyWizzrobe() : base("wizzrobe") { } + + public EnemyWizzrobe(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + Tags = Values.GameObjectTag.Enemy; + + _fieldRectangle = map.GetField(posX, posY); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/wizzrobe"); + _animator.Play("head"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-8, 0)); + + _body = new BodyComponent(EntityPosition, -6, -12, 12, 12, 8); + + var stateHidden = new AiState(UpdateHidden) { Init = InitHidden }; + // will be hidden for at lease x time + stateHidden.Trigger.Add(_hiddenTimer = new AiTriggerTimer(1000)); + var stateSpawn = new AiState { Init = InitSpawn }; + stateSpawn.Trigger.Add(new AiTriggerCountdown(BlinkTime, BlinkTick, () => _aiComponent.ChangeState("head"))); + var stateHead = new AiState { Init = InitHead }; + stateHead.Trigger.Add(new AiTriggerCountdown(400, null, () => _aiComponent.ChangeState("stand"))); + var stateStand = new AiState { Init = InitStand }; + stateStand.Trigger.Add(new AiTriggerCountdown(300, null, Shoot)); + stateStand.Trigger.Add(new AiTriggerCountdown(1000, null, () => _aiComponent.ChangeState("despawnHead"))); + var stateDespawnHead = new AiState { Init = InitHead }; + stateDespawnHead.Trigger.Add(new AiTriggerCountdown(400, null, () => _aiComponent.ChangeState("despawn"))); + var stateDespawn = new AiState(); + stateDespawn.Trigger.Add(new AiTriggerCountdown(BlinkTime, BlinkTick, () => _aiComponent.ChangeState("hidden"))); + + _aiComponent = new AiComponent(); + + _aiComponent.States.Add("hidden", stateHidden); + _aiComponent.States.Add("spawn", stateSpawn); + _aiComponent.States.Add("head", stateHead); + _aiComponent.States.Add("stand", stateStand); + _aiComponent.States.Add("despawn", stateDespawn); + _aiComponent.States.Add("despawnHead", stateDespawnHead); + _aiStunnedState = new AiStunnedState(_aiComponent, animationComponent, 3300, 900); + _damageState = new AiDamageState(this, _body, _aiComponent, _sprite, 4, false, false); + new AiFallState(_aiComponent, _body, null, null, 100); + + _aiComponent.ChangeState("hidden"); + + var hittableBox = new CBox(EntityPosition, -7, -15, 14, 15, 8); + var damageBox = new CBox(EntityPosition, -7, -14, 14, 14, 4); + var pushableBox = new CBox(EntityPosition, -6, -14, 12, 14, 8); + + AddComponent(BodyComponent.Index, _body); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageBox, HitType.Enemy, 4) { IsActive = false }); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(PushableComponent.Index, _pushComponent = new PushableComponent(pushableBox, OnPush) { IsActive = false }); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(_sprite)); + } + + private void InitSpawn() + { + _animator.Play("head"); + } + + private void BlinkTick(double timer) + { + var sinState = (float)((BlinkTime - timer) / BlinkTime); + var state = MathF.Sin(sinState * 9f * MathF.PI * 2); + + // blink + _sprite.IsVisible = state >= 0; + } + + private void InitHead() + { + _animator.Play("head"); + _sprite.IsVisible = true; + + _damageField.IsActive = false; + _pushComponent.IsActive = false; + } + + private void InitHidden() + { + _sprite.IsVisible = false; + } + + private void UpdateHidden() + { + // start spawning + if (_hiddenTimer.State && _fieldRectangle.Contains(MapManager.ObjLink.EntityPosition.Position)) + _aiComponent.ChangeState("spawn"); + } + + private void InitStand() + { + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + + _direction = AnimationHelper.GetDirection(playerDirection); + + _damageField.IsActive = true; + _pushComponent.IsActive = true; + + // look towards the player + _animator.Play("stand_" + _direction); + } + + private void Shoot() + { + var projectile = new EnemyWizzrobeProjectile(Map, new Vector2(EntityPosition.X, EntityPosition.Y - 7), _direction, 2.0f); + Map.Objects.SpawnObject(projectile); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + // can not hit the enemy while he is spawning or hidden + if (_damageState.CurrentLives <= 0 || _damageState.IsInDamageState() || + (_aiComponent.CurrentStateId != "stand" && !_aiStunnedState.IsStunned())) + return Values.HitCollision.None; + + if (type == HitType.Hookshot || type == HitType.Boomerang) + { + _aiStunnedState.StartStun(); + _damageField.IsActive = false; + } + + if (type == HitType.MagicPowder) + { + _aiStunnedState.StartStun(); + _damageState.SetDamageState(false); + _damageField.IsActive = false; + _body.Velocity.X = direction.X * 2.5f; + _body.Velocity.Y = direction.Y * 2.5f; + return Values.HitCollision.None; + } + + // @TODO: not sure if thrown object damage is right + if (type == HitType.Bomb || type == HitType.ThrownObject) + damage = 4; + else if (type == HitType.Bow || type == HitType.MagicRod) + damage = 1; + else + damage = 0; + + return _damageState.OnHit(originObject, direction, type, damage, pieceOfPower); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType pushType) + { + if (pushType == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction * 1.75f, _body.Velocity.Z); + + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyWizzrobeProjectile.cs b/InGame/GameObjects/Enemies/EnemyWizzrobeProjectile.cs new file mode 100644 index 0000000..c49930a --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyWizzrobeProjectile.cs @@ -0,0 +1,71 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyWizzrobeProjectile : GameObject + { + private readonly CSprite _sprite; + + public EnemyWizzrobeProjectile(Map.Map map, Vector2 position, int direction, float speed) : base(map) + { + EntityPosition = new CPosition(position.X, position.Y, 0); + EntitySize = new Rectangle(-6, -6, 12, 12); + + _sprite = new CSprite("wizzrobe shot", EntityPosition, Vector2.Zero); + _sprite.Center = new Vector2(6, 6); + _sprite.Rotation = MathF.PI / 2f * direction; + + var body = new BodyComponent(EntityPosition, -2, -2, 4, 4, 8) + { + IgnoresZ = true, + IgnoreHoles = true, + CollisionTypes = Values.CollisionTypes.Normal, + MoveCollision = OnCollision + }; + + body.VelocityTarget = AnimationHelper.DirectionOffset[direction] * speed; + + var damageCollider = new CBox(EntityPosition, -3, -3, 0, 6, 6, 4); + + AddComponent(BodyComponent.Index, body); + AddComponent(PushableComponent.Index, new PushableComponent(body.BodyBox, OnPush)); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 4)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerTop)); + } + + private void Update() + { + // blink + var blinkTime = 66.667f; + _sprite.SpriteShader = (Game1.TotalGameTime % (blinkTime * 2) < blinkTime) ? Resources.DamageSpriteShader0 : null; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType pushType) + { + Despawn(); + + return true; + } + + private void OnCollision(Values.BodyCollision collision) + { + Despawn(); + } + + private void Despawn() + { + // spawn despawn effect + var animation = new ObjAnimator(Map, (int)EntityPosition.X, (int)EntityPosition.Y, Values.LayerTop, "Particles/swordPoke", "run", true); + Map.Objects.SpawnObject(animation); + + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/EnemyZombie.cs b/InGame/GameObjects/Enemies/EnemyZombie.cs new file mode 100644 index 0000000..ddb0299 --- /dev/null +++ b/InGame/GameObjects/Enemies/EnemyZombie.cs @@ -0,0 +1,151 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class EnemyZombie : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly AiDamageState _damageState; + private readonly DamageFieldComponent _damageField; + + public EnemyZombie() : base("zombie") { } + + public EnemyZombie(Map.Map map, int posX, int posY) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Enemies/zombie"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -16)); + + _body = new BodyComponent(EntityPosition, -6, -10, 12, 10, 8) + { + MoveCollision = OnCollision, + HoleAbsorb = OnHoleAbsorb, + AvoidTypes = Values.CollisionTypes.Hole | Values.CollisionTypes.NPCWall, + Drag = 0.8f + }; + + // ai states + var stateSpawn = new AiState(UpdateSpawn) { Init = InitSpawn }; + var walkingState = new AiState() { Init = InitWalking }; + walkingState.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("despawn"), 1000, 4000)); + var stateDespawn = new AiState(UpdateDespawning) { Init = InitDespawning }; + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("spawn", stateSpawn); + _aiComponent.States.Add("walking", walkingState); + _aiComponent.States.Add("despawn", stateDespawn); + _damageState = new AiDamageState(this, _body, _aiComponent, sprite, 1) { OnBurn = () => _animator.Pause(), IsActive = false }; + new AiFallState(_aiComponent, _body, OnHoleAbsorb); + _aiComponent.ChangeState("spawn"); + + var hittableBox = new CBox(EntityPosition, -6, -15, 0, 12, 15, 8); + var damageBox = new CBox(EntityPosition, -6, -14, 0, 12, 14, 4); + var pushableBox = new CBox(EntityPosition, -6, -13, 0, 12, 13, 8); + + AddComponent(PushableComponent.Index, new PushableComponent(pushableBox, OnPush)); + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + } + + private void InitSpawn() + { + _animator.Play("spawn"); + } + + private void UpdateSpawn() + { + if (!_animator.IsPlaying) + _aiComponent.ChangeState("walking"); + } + + private void InitWalking() + { + if (_animator.CurrentFrameIndex > 0) + _damageState.IsActive = true; + + _damageField.IsActive = true; + + _animator.Play("walk"); + + // start walking towards the player + var walkDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + + if (walkDirection != Vector2.Zero) + walkDirection.Normalize(); + + _body.VelocityTarget = walkDirection * Game1.RandomNumber.Next(50, 80) / 100f; + } + + private void InitDespawning() + { + // start despawn animation and stop moving + _animator.Play("despawn"); + _body.Velocity = Vector3.Zero; + _body.VelocityTarget = Vector2.Zero; + _damageField.IsActive = false; + } + + private void UpdateDespawning() + { + if (_animator.CurrentFrameIndex > 0) + _damageState.IsActive = false; + + if (!_animator.IsPlaying) + Map.Objects.DeleteObjects.Add(this); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (_aiComponent.CurrentStateId == "despawn") + return false; + + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X * 1.75f, direction.Y * 1.75f, _body.Velocity.Z); + + return true; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + return _damageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + } + + private void OnCollision(Values.BodyCollision direction) + { + if (_aiComponent.CurrentStateId == "walking") + { + if ((direction & Values.BodyCollision.Horizontal) != 0 && + Math.Abs(_body.VelocityTarget.X) > Math.Abs(_body.VelocityTarget.Y) * 3 || + (direction & Values.BodyCollision.Vertical) != 0 && + Math.Abs(_body.VelocityTarget.Y) > Math.Abs(_body.VelocityTarget.X) * 3) + _aiComponent.ChangeState("despawn"); + } + } + + public void OnHoleAbsorb() + { + _animator.SpeedMultiplier = 2f; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/ObjBeetleSpawner.cs b/InGame/GameObjects/Enemies/ObjBeetleSpawner.cs new file mode 100644 index 0000000..1593005 --- /dev/null +++ b/InGame/GameObjects/Enemies/ObjBeetleSpawner.cs @@ -0,0 +1,56 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Enemies; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjBeetleSpawner : GameObject + { + private readonly List _enemyList = new List(); + private readonly Rectangle _triggerField; + + private const float SpawnTimer = 1250; + private float _spawnCounter = SpawnTimer; + + public ObjBeetleSpawner() : base("beetle") { } + + public ObjBeetleSpawner(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 8, 0); + EntitySize = new Rectangle(-16, -16, 32, 32); + + _triggerField = map.GetField(posX, posY); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + private void Update() + { + var playerDistance = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + + if (playerDistance.Length() < 36) + _spawnCounter -= Game1.DeltaTime; + + if (_spawnCounter <= 0) + { + _spawnCounter = SpawnTimer; + + // get the enemies the object should watch over + Map.Objects.GetGameObjectsWithTag(_enemyList, Values.GameObjectTag.Enemy, + _triggerField.X, _triggerField.Y, _triggerField.Width, _triggerField.Height); + + // spawn a new beetle there are no more than 3 enemies in the area + if (_enemyList.Count < 4) + { + var newBeetle = new EnemyBeetle(Map, (int)EntityPosition.X - 8, (int)EntityPosition.Y - 8); + Map.Objects.SpawnObject(newBeetle); + } + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Enemies/ObjZombieSpawner.cs b/InGame/GameObjects/Enemies/ObjZombieSpawner.cs new file mode 100644 index 0000000..dcb71f9 --- /dev/null +++ b/InGame/GameObjects/Enemies/ObjZombieSpawner.cs @@ -0,0 +1,62 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class ObjZombieSpawner : GameObject + { + private Rectangle _triggerField; + + private float _spawnTime; + private float _spawnCounter; + + public ObjZombieSpawner() : base("zombie") { } + + public ObjZombieSpawner(Map.Map map, int posX, int posY, int spawnTime) : base(map) + { + _triggerField = map.GetField(posX, posY); + _spawnTime = spawnTime; + _spawnCounter = spawnTime; + + EntityPosition = new CPosition(_triggerField.X, _triggerField.Y, 0); + EntitySize = new Rectangle(0, 0, _triggerField.Width, _triggerField.Height); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + private void Update() + { + // check if the player is standing in the field + if (_triggerField.Contains(new Point((int)MapManager.ObjLink.EntityPosition.X, (int)MapManager.ObjLink.EntityPosition.Y))) + _spawnCounter -= Game1.DeltaTime; + + if (_spawnCounter <= 0) + { + _spawnCounter = _spawnTime; + + // try to find a position for the new zombie + for (var i = 0; i < 10; i++) + { + var posX = _triggerField.X + Game1.RandomNumber.Next(0, 10) * Values.TileSize; + var posY = _triggerField.Y + Game1.RandomNumber.Next(0, 8) * Values.TileSize; + + // found a good position? + var collidingRectangle = Box.Empty; + if (!Map.Objects.Collision(new Box(posX, posY, 0, 16, 16, 8), Box.Empty, + Values.CollisionTypes.Normal | Values.CollisionTypes.Enemy | Values.CollisionTypes.Player, 0, 0, + ref collidingRectangle)) + { + var newZombie = new EnemyZombie(Map, posX, posY); + Map.Objects.SpawnObject(newZombie); + break; + } + } + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/GameObjectItem.cs b/InGame/GameObjects/GameObjectItem.cs new file mode 100644 index 0000000..7a020af --- /dev/null +++ b/InGame/GameObjects/GameObjectItem.cs @@ -0,0 +1,28 @@ +using System; + +namespace ProjectZ.InGame.GameObjects +{ + public class GameObjectItem : IComparable + { + public string Index; + public object[] Parameter; + + public GameObjectItem(string index, object[] parameter) + { + Index = index; + Parameter = parameter; + } + + public int CompareTo(object compareObject) + { + if (!(compareObject is GameObjectItem item)) return 0; + + if (item.Parameter.Length >= 3 && Parameter.Length >= 3) + return Index.CompareTo(item.Index) * 4 + + ((int)Parameter[1]).CompareTo((int)item.Parameter[1]) * 2 + + ((int)Parameter[2]).CompareTo((int)item.Parameter[2]); + + return Index.CompareTo(item.Index); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/GameObjectTemplate.cs b/InGame/GameObjects/GameObjectTemplate.cs new file mode 100644 index 0000000..1cdec3b --- /dev/null +++ b/InGame/GameObjects/GameObjectTemplate.cs @@ -0,0 +1,16 @@ +using System; + +namespace ProjectZ.InGame.GameObjects +{ + public class GameObjectTemplate + { + public Type ObjectType; + public object[] Parameter; + + public GameObjectTemplate(Type objectType, object[] parameter) + { + ObjectType = objectType; + Parameter = parameter; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/GameObjectTemplates.cs b/InGame/GameObjects/GameObjectTemplates.cs new file mode 100644 index 0000000..1879773 --- /dev/null +++ b/InGame/GameObjects/GameObjectTemplates.cs @@ -0,0 +1,751 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.Editor; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Bosses; +using ProjectZ.InGame.GameObjects.Dungeon; +using ProjectZ.InGame.GameObjects.Enemies; +using ProjectZ.InGame.GameObjects.MidBoss; +using ProjectZ.InGame.GameObjects.NPCs; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects +{ + class GameObjectTemplates + { + public static Dictionary ObjectTemplates = new Dictionary(); + public static Dictionary> ObjectSpawner = new Dictionary>(); + public static Dictionary GameObjectParameter = new Dictionary(); + + public static void SetUpGameObjects() + { + // collision boxes + var colliderColor = Color.OrangeRed * 0.65f; + ObjectTemplates.Add("c1", new GameObjectTemplate(typeof(ObjCollider), new object[] { colliderColor, Values.CollisionTypes.Normal, new[] { new Rectangle(0, 0, 16, 16) } })); + ObjectTemplates.Add("c2", new GameObjectTemplate(typeof(ObjCollider), new object[] { colliderColor, Values.CollisionTypes.Normal, new[] { new Rectangle(0, 8, 16, 8) } })); + ObjectTemplates.Add("c5", new GameObjectTemplate(typeof(ObjCollider), new object[] { colliderColor, Values.CollisionTypes.Normal, new[] { new Rectangle(0, 0, 16, 8) } })); + ObjectTemplates.Add("c3", new GameObjectTemplate(typeof(ObjCollider), new object[] { colliderColor, Values.CollisionTypes.Normal, new[] { new Rectangle(0, 0, 8, 16) } })); + ObjectTemplates.Add("c4", new GameObjectTemplate(typeof(ObjCollider), new object[] { colliderColor, Values.CollisionTypes.Normal, new[] { new Rectangle(8, 0, 8, 16) } })); + ObjectTemplates.Add("colliderL0", new GameObjectTemplate(typeof(ObjCollider), new object[] { colliderColor, Values.CollisionTypes.Normal, new[] { new Rectangle(0, 8, 8, 8), new Rectangle(0, 0, 16, 8) } })); + ObjectTemplates.Add("colliderL1", new GameObjectTemplate(typeof(ObjCollider), new object[] { colliderColor, Values.CollisionTypes.Normal, new[] { new Rectangle(8, 8, 8, 8), new Rectangle(0, 0, 16, 8) } })); + ObjectTemplates.Add("colliderL2", new GameObjectTemplate(typeof(ObjCollider), new object[] { colliderColor, Values.CollisionTypes.Normal, new[] { new Rectangle(0, 0, 8, 8), new Rectangle(0, 8, 16, 8) } })); + ObjectTemplates.Add("colliderL3", new GameObjectTemplate(typeof(ObjCollider), new object[] { colliderColor, Values.CollisionTypes.Normal, new[] { new Rectangle(8, 0, 8, 8), new Rectangle(0, 8, 16, 8) } })); + + var lowerColliderColor = Color.Green * 0.65f; + var lowerCollisionType = Values.CollisionTypes.Normal | Values.CollisionTypes.ThrowIgnore | Values.CollisionTypes.ThrowWeaponIgnore; + ObjectTemplates.Add("lowCollider16", new GameObjectTemplate(typeof(ObjCollider), new object[] { lowerColliderColor, lowerCollisionType, new[] { new Rectangle(0, 0, 16, 16) } })); + ObjectTemplates.Add("lowCollider0", new GameObjectTemplate(typeof(ObjCollider), new object[] { lowerColliderColor, lowerCollisionType, new[] { new Rectangle(0, 8, 16, 8) } })); + ObjectTemplates.Add("lowCollider1", new GameObjectTemplate(typeof(ObjCollider), new object[] { lowerColliderColor, lowerCollisionType, new[] { new Rectangle(0, 0, 16, 8) } })); + ObjectTemplates.Add("lowCollider2", new GameObjectTemplate(typeof(ObjCollider), new object[] { lowerColliderColor, lowerCollisionType, new[] { new Rectangle(0, 0, 8, 16) } })); + ObjectTemplates.Add("lowCollider3", new GameObjectTemplate(typeof(ObjCollider), new object[] { lowerColliderColor, lowerCollisionType, new[] { new Rectangle(8, 0, 8, 16) } })); + ObjectTemplates.Add("c13", new GameObjectTemplate(typeof(ObjCollider), new object[] { lowerColliderColor, lowerCollisionType, new[] { new Rectangle(0, 0, 8, 8) } })); + ObjectTemplates.Add("c6", new GameObjectTemplate(typeof(ObjCollider), new object[] { lowerColliderColor, lowerCollisionType, new[] { new Rectangle(8, 0, 8, 8) } })); + ObjectTemplates.Add("c7", new GameObjectTemplate(typeof(ObjCollider), new object[] { lowerColliderColor, lowerCollisionType, new[] { new Rectangle(0, 8, 8, 8) } })); + ObjectTemplates.Add("c8", new GameObjectTemplate(typeof(ObjCollider), new object[] { lowerColliderColor, lowerCollisionType, new[] { new Rectangle(8, 8, 8, 8) } })); + ObjectTemplates.Add("c9", new GameObjectTemplate(typeof(ObjCollider), new object[] { lowerColliderColor, lowerCollisionType, new[] { new Rectangle(0, 8, 8, 8), new Rectangle(0, 0, 16, 8) } })); + ObjectTemplates.Add("c10", new GameObjectTemplate(typeof(ObjCollider), new object[] { lowerColliderColor, lowerCollisionType, new[] { new Rectangle(8, 8, 8, 8), new Rectangle(0, 0, 16, 8) } })); + ObjectTemplates.Add("c11", new GameObjectTemplate(typeof(ObjCollider), new object[] { lowerColliderColor, lowerCollisionType, new[] { new Rectangle(0, 0, 8, 8), new Rectangle(0, 8, 16, 8) } })); + ObjectTemplates.Add("c12", new GameObjectTemplate(typeof(ObjCollider), new object[] { lowerColliderColor, lowerCollisionType, new[] { new Rectangle(8, 0, 8, 8), new Rectangle(0, 8, 16, 8) } })); + + ObjectTemplates.Add("enemyWall", new GameObjectTemplate(typeof(ObjCollider), new object[] { 32, new Rectangle(0, 0, 16, 16), Values.CollisionTypes.NPCWall, -1 })); + ObjectTemplates.Add("drownResetExclude", new GameObjectTemplate(typeof(ObjCollider), new object[] { 32, new Rectangle(0, 0, 16, 16), Values.CollisionTypes.DrownExclude, -1 })); + ObjectTemplates.Add("hookshotGrip", new GameObjectTemplate(typeof(ObjCollider), new object[] { 32, new Rectangle(0, 0, 16, 16), Values.CollisionTypes.Hookshot, -1 })); + + ObjectTemplates.Add("lowerLevelCollider", new GameObjectTemplate(typeof(ObjCollider), new object[] { 32, new Rectangle(0, 0, 16, 16), Values.CollisionTypes.Normal, 0 })); + ObjectTemplates.Add("lowerLevelCollider1", new GameObjectTemplate(typeof(ObjCollider), new object[] { 32, new Rectangle(0, 8, 16, 8), Values.CollisionTypes.Normal, 0 })); + ObjectTemplates.Add("lowerLevelCollider2", new GameObjectTemplate(typeof(ObjCollider), new object[] { 32, new Rectangle(0, 0, 8, 16), Values.CollisionTypes.Normal, 0 })); + ObjectTemplates.Add("colliderLevel1", new GameObjectTemplate(typeof(ObjCollider), new object[] { 32, new Rectangle(0, 0, 16, 16), Values.CollisionTypes.Normal, 1 })); + ObjectTemplates.Add("raftCollider", new GameObjectTemplate(typeof(ObjCollider), new object[] { 32, new Rectangle(0, 0, 16, 16), Values.CollisionTypes.RaftExit, 1 })); + + ObjectTemplates.Add("c1PushIgnore", new GameObjectTemplate(typeof(ObjCollider), new object[] { colliderColor, Values.CollisionTypes.Normal | Values.CollisionTypes.PushIgnore, new[] { new Rectangle(0, 0, 16, 16) } })); + + ObjectTemplates.Add("oneWayBridge2", new GameObjectTemplate(typeof(ObjColliderOneWay), new object[] { new Rectangle(15, 0, 1, 16), Values.CollisionTypes.Normal, 2 })); + ObjectTemplates.Add("oneWayBridge0", new GameObjectTemplate(typeof(ObjColliderOneWay), new object[] { new Rectangle(0, 0, 1, 16), Values.CollisionTypes.Normal, 0 })); + + + ObjectTemplates.Add("break_collider_end", null); + ObjectTemplates.Add("break_sprite_start", null); + + ObjectTemplates.Add("tree0", new GameObjectTemplate(typeof(ObjSprite), new object[] { "tree_0", new Vector2(16, 24), Values.LayerPlayer, "tree_0_shadow", new Rectangle(-16, -20, 32, 28), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("treeWoods", new GameObjectTemplate(typeof(ObjSprite), new object[] { "tree_7", new Vector2(16, 24), Values.LayerPlayer, "tree_0_shadow", new Rectangle(-16, -20, 32, 28), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("treeWoods2", new GameObjectTemplate(typeof(ObjSprite), new object[] { "tree_6", new Vector2(16, 24), Values.LayerPlayer, "tree_0_shadow", new Rectangle(-16, -20, 32, 27), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("tree1", new GameObjectTemplate(typeof(ObjSprite), new object[] { "tree_1", new Vector2(16, 24), Values.LayerPlayer, "tree_1_shadow", new Rectangle(-16, -20, 32, 28), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("tree2", new GameObjectTemplate(typeof(ObjSprite), new object[] { "tree_2", new Vector2(16, 24), Values.LayerPlayer, "tree_2_shadow", new Rectangle(-16, -20, 32, 28), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("tree3", new GameObjectTemplate(typeof(ObjSprite), new object[] { "tree_3", new Vector2(16, 24), Values.LayerPlayer, "tree_2_shadow", new Rectangle(-16, -20, 32, 28), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("tree4", new GameObjectTemplate(typeof(ObjSprite), new object[] { "tree_4", new Vector2(16, 24), Values.LayerPlayer, "tree_4_shadow", new Rectangle(-16, -20, 32, 28), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("tree5", new GameObjectTemplate(typeof(ObjSprite), new object[] { "tree_5", new Vector2(16, 24), Values.LayerPlayer, "tree_5_shadow", new Rectangle(-16, -20, 32, 28), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("stree", new GameObjectTemplate(typeof(ObjSprite), new object[] { "tree_8", new Vector2(8, 24), Values.LayerPlayer, "tree_8_shadow", new Rectangle(-8, -8, 16, 16), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("phonehouse", new GameObjectTemplate(typeof(ObjSprite), new object[] { "tree_phonehouse", new Vector2(24, 24), Values.LayerPlayer, "tree_phonehouse_shadow", new Rectangle(-24, -20, 48, 12), Values.CollisionTypes.Normal })); + + ObjectTemplates.Add("tree9", new GameObjectTemplate(typeof(ObjSprite), new object[] { "tree_9", new Vector2(16, 24), Values.LayerPlayer, "tree_9_shadow", new Rectangle(-16, -20, 32, 28), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("seashell_house", new GameObjectTemplate(typeof(ObjSprite), new object[] { "seashell_house", new Vector2(24, 24), Values.LayerPlayer, "seashell_house_shadow", new Rectangle(-24, -20, 48, 12), Values.CollisionTypes.Normal })); + + ObjectTemplates.Add("strandplant", new GameObjectTemplate(typeof(ObjSprite), new object[] { "strandPlant", new Vector2(8, 12), Values.LayerPlayer, "strandPlantShadow", new Rectangle(-8, -8, 15, 12), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("strandshell", new GameObjectTemplate(typeof(ObjSprite), new object[] { "strandShell", new Vector2(8, 12), Values.LayerPlayer, "strandShellShadow" })); + ObjectTemplates.Add("dungeonOneStatue", new GameObjectTemplate(typeof(ObjSprite), new object[] { "dungeonOneStatue", new Vector2(8, 28), Values.LayerPlayer, "dungeonOneStatue", new Rectangle(-8, -12, 16, 16), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("dungeonOneStatueKey", new GameObjectTemplate(typeof(ObjSprite), new object[] { "dungeonOneStatueKey", new Vector2(8, 28), Values.LayerPlayer, "dungeonOneStatueKey", new Rectangle(-8, -12, 16, 16), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("dungeonStatue", new GameObjectTemplate(typeof(ObjSprite), new object[] { "dungeonStatue_0", new Vector2(8, 13), Values.LayerPlayer, "dungeonStatue_0", new Rectangle(-8, -10, 16, 13), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("dungeonStatueGrey", new GameObjectTemplate(typeof(ObjSprite), new object[] { "dungeonStatue_1", new Vector2(8, 13), Values.LayerPlayer, "dungeonStatue_1", new Rectangle(-8, -10, 16, 13), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("dungeonStatueD7", new GameObjectTemplate(typeof(ObjSprite), new object[] { "dungeonStatue_2", new Vector2(8, 13), Values.LayerPlayer, "dungeonStatue_2", new Rectangle(-8, -10, 16, 13), Values.CollisionTypes.Normal })); + + ObjectTemplates.Add("caveFairyStatue", new GameObjectTemplate(typeof(ObjSprite), new object[] { "caveFairyStatue", new Vector2(8, 28), Values.LayerPlayer, "caveFairyStatue", new Rectangle(-8, -8, 16, 12), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("gravejardfence", new GameObjectTemplate(typeof(ObjSprite), new object[] { "gravejardFence", new Vector2(7, 12), Values.LayerPlayer, "gravejardFence", new Rectangle(-7, -8, 15, 12), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("desertpillar", new GameObjectTemplate(typeof(ObjSprite), new object[] { "desertPillar", new Vector2(8, 28), Values.LayerPlayer, "desertPillar", new Rectangle(-8, -20, 15, 24), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("phone", new GameObjectTemplate(typeof(ObjSprite), new object[] { "phone", new Vector2(8, 14), Values.LayerPlayer, "phone", new Rectangle(-8, -10, 16, 12), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("itemShop", new GameObjectTemplate(typeof(ObjSprite), new object[] { "itemShop", new Vector2(8, 14), Values.LayerPlayer, "itemShop", new Rectangle(-8, -10, 16, 12), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("armosStatue", new GameObjectTemplate(typeof(ObjSprite), new object[] { "armos", new Vector2(8, 14), Values.LayerPlayer, "armos", new Rectangle(-8, -10, 16, 12), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("armosDarkStatue", new GameObjectTemplate(typeof(ObjSprite), new object[] { "armos dark", new Vector2(8, 14), Values.LayerPlayer, "armos dark", new Rectangle(-8, -10, 16, 12), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("statueCastle", new GameObjectTemplate(typeof(ObjSprite), new object[] { "statueCastle", new Vector2(8, 14), Values.LayerPlayer, "statueCastle", new Rectangle(-8, -10, 16, 12), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("dungeon3Head", new GameObjectTemplate(typeof(ObjSprite), new object[] { "dungeon3Head", new Vector2(8, 12), Values.LayerPlayer, "dungeon3Head", new Rectangle(-8, -8, 16, 12), Values.CollisionTypes.Normal })); + + ObjectTemplates.Add("banana", new GameObjectTemplate(typeof(ObjSprite), new object[] { "bananas", new Vector2(8, 16), Values.LayerPlayer, "bananas", new Rectangle(-8, -14, 16, 14), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("npc_bag", new GameObjectTemplate(typeof(ObjSprite), new object[] { "npc_bag", new Vector2(8, 14), Values.LayerPlayer, "npc_bag", new Rectangle(-7, -8, 14, 10), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("statueD3", new GameObjectTemplate(typeof(ObjSprite), new object[] { "statue_d3", new Vector2(8, 30), Values.LayerPlayer, "statue_d3", new Rectangle(-8, -14, 16, 16), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("statueD3Key", new GameObjectTemplate(typeof(ObjSprite), new object[] { "statue_d3_key", new Vector2(8, 30), Values.LayerPlayer, "statue_d3_key", new Rectangle(-8, -14, 16, 16), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("statueMermaid", new GameObjectTemplate(typeof(ObjSprite), new object[] { "statue_mermaid", new Vector2(8, 28), Values.LayerPlayer, "statue_mermaid", new Rectangle(-8, -14, 16, 14), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("mountainStone", new GameObjectTemplate(typeof(ObjSprite), new object[] { "stone_mountain_0", new Vector2(8, 13), Values.LayerPlayer, "stone_mountain_0", new Rectangle(-8, -11, 16, 12), Values.CollisionTypes.Normal | Values.CollisionTypes.Hookshot })); + ObjectTemplates.Add("dungeon7_keyhole", new GameObjectTemplate(typeof(ObjSprite), new object[] { "dungeon7_keyhole", new Vector2(8, 14), Values.LayerPlayer, "dungeon7_keyhole", new Rectangle(-8, -12, 16, 14), Values.CollisionTypes.Normal })); + + ObjectTemplates.Add("overworldDonut", new GameObjectTemplate(typeof(ObjSprite), new object[] { + "overworldDonut", new Vector2(8, 0), Values.LayerPlayer, "overworldDonut", new Rectangle(-8, 0, 16, 16), Values.CollisionTypes.Normal | Values.CollisionTypes.Hookshot })); + + ObjectTemplates.Add("cave_table", new GameObjectTemplate(typeof(ObjSprite), new object[] { "cave_table", new Vector2(0, 1), Values.LayerPlayer, null, new Rectangle(0, -1, 32, 16), Values.CollisionTypes.Normal | Values.CollisionTypes.ThrowWeaponIgnore })); + ObjectTemplates.Add("cave_bed", new GameObjectTemplate(typeof(ObjSprite), new object[] { "cave_bed", new Vector2(0, 0), Values.LayerPlayer, null, new Rectangle(0, 0, 16, 32), Values.CollisionTypes.Normal | Values.CollisionTypes.ThrowWeaponIgnore })); + + ObjectTemplates.Add("vase_empty", new GameObjectTemplate(typeof(ObjSprite), new object[] { "vase_empty", new Vector2(8, 16), Values.LayerPlayer, "vase_empty" })); + ObjectTemplates.Add("vase_flower", new GameObjectTemplate(typeof(ObjSprite), new object[] { "vase_flower", new Vector2(8, 16), Values.LayerPlayer, "vase_flower" })); + + ObjectTemplates.Add("painting", new GameObjectTemplate(typeof(ObjSprite), new object[] { "painting", new Vector2(8, 16), Values.LayerPlayer, "painting", new Rectangle(-8, -12, 16, 12), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("owl_statue", new GameObjectTemplate(typeof(ObjSprite), new object[] { "owl_statue", new Vector2(0, 12), Values.LayerPlayer, "owl_statue_shadow", new Rectangle(0, -12, 16, 16), Values.CollisionTypes.Normal })); + ObjectTemplates.Add("photohouse_light", new GameObjectTemplate(typeof(ObjSprite), new object[] { "photohouse_light", new Vector2(0, 24), Values.LayerPlayer, "photohouse_light" })); + + ObjectTemplates.Add("castle_roof_0", new GameObjectTemplate(typeof(ObjSprite), new object[] { "castle_roof_0", new Vector2(0, 17), Values.LayerPlayer, null })); + ObjectTemplates.Add("castle_roof_1", new GameObjectTemplate(typeof(ObjSprite), new object[] { "castle_roof_1", new Vector2(0, 17), Values.LayerPlayer, null })); + ObjectTemplates.Add("castle_roof_2", new GameObjectTemplate(typeof(ObjSprite), new object[] { "castle_roof_2", new Vector2(0, 17), Values.LayerPlayer, null })); + ObjectTemplates.Add("castle_roof_3", new GameObjectTemplate(typeof(ObjSprite), new object[] { "castle_roof_3", new Vector2(0, 0), Values.LayerPlayer, null })); + ObjectTemplates.Add("castle_roof_4", new GameObjectTemplate(typeof(ObjSprite), new object[] { "castle_roof_4", new Vector2(0, 16), Values.LayerPlayer, null })); + ObjectTemplates.Add("castle_roof_5", new GameObjectTemplate(typeof(ObjSprite), new object[] { "castle_roof_5", new Vector2(0, 16), Values.LayerPlayer, null })); + + // roofs + ObjectTemplates.Add("roof01", new GameObjectTemplate(typeof(ObjSprite), new object[] { "roof_0", new Vector2(0, 18), Values.LayerPlayer, null })); + ObjectTemplates.Add("roof02", new GameObjectTemplate(typeof(ObjSprite), new object[] { "roof_1", new Vector2(0, 18), Values.LayerPlayer, null })); + ObjectTemplates.Add("roof03", new GameObjectTemplate(typeof(ObjSprite), new object[] { "roof_2", new Vector2(0, 18), Values.LayerPlayer, null })); + ObjectTemplates.Add("roof04", new GameObjectTemplate(typeof(ObjSprite), new object[] { "roof_3", new Vector2(0, 16), Values.LayerPlayer, null })); + ObjectTemplates.Add("roof05", new GameObjectTemplate(typeof(ObjSprite), new object[] { "roof_4", new Vector2(0, 18), Values.LayerPlayer, null })); + ObjectTemplates.Add("roof06", new GameObjectTemplate(typeof(ObjSprite), new object[] { "roof_5", new Vector2(0, 18), Values.LayerPlayer, null })); + + ObjectTemplates.Add("d5_entry", new GameObjectTemplate(typeof(ObjSprite), new object[] { "d5_entry", Vector2.Zero, Values.LayerPlayer, "d5_entry_shadow" })); + ObjectTemplates.Add("witch_house", new GameObjectTemplate(typeof(ObjSprite), new object[] { "witch_house", new Vector2(0, 30), Values.LayerPlayer, "witch_house_shadow" })); + + ObjectTemplates.Add("seashell_post", new GameObjectTemplate(typeof(ObjSprite), new object[] { "seashell_post", new Vector2(0, 0), Values.LayerTop, null })); + + ObjectTemplates.Add("stairsCastle", new GameObjectTemplate(typeof(ObjSprite), new object[] { "stairs_0", Vector2.Zero, Values.LayerBottom, null })); + ObjectTemplates.Add("stairsWoods", new GameObjectTemplate(typeof(ObjSprite), new object[] { "stairs_1", Vector2.Zero, Values.LayerBottom, null })); + ObjectTemplates.Add("dungeon_stairs", new GameObjectTemplate(typeof(ObjSprite), new object[] { "stairs_2", Vector2.Zero, Values.LayerBottom, null })); + ObjectTemplates.Add("dungeon_6_stairs", new GameObjectTemplate(typeof(ObjSprite), new object[] { "stairs_3", Vector2.Zero, Values.LayerBottom, null })); + + ObjectTemplates.Add("break_sprite_end", null); + + ObjectTemplates.Add("wave1", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "water_0", 8, 125, true, 0, Values.LayerBottom })); + ObjectTemplates.Add("wave2", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "water_2", 8, 125, true, 0, Values.LayerBottom })); + ObjectTemplates.Add("wave6", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "wave_6", 8, 125, true, 0, Values.LayerBottom })); + ObjectTemplates.Add("pondWoods", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "water_1", 8, 125, true, 0, Values.LayerBottom })); + ObjectTemplates.Add("water1", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "water_3", 8, 125, true, 0, Values.LayerBottom })); + ObjectTemplates.Add("wave3", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "wave_3", 8, 125, true, 0, Values.LayerBottom })); + ObjectTemplates.Add("wave4", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "wave_4", 8, 125, true, 0, Values.LayerBottom })); + ObjectTemplates.Add("wave5", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "wave_5", 8, 125, true, 0, Values.LayerBottom })); + ObjectTemplates.Add("water2", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "water_4", 8, 150, true, 0, Values.LayerBottom })); // cant set to layer background because of the waterfall + ObjectTemplates.Add("water3", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "water_5", 8, 150, true, 0, Values.LayerBottom })); + // used in dungeon 4 and the boss needs to be on top but not on the same layer as the player; so we need to put the water on the background or add a new layer + ObjectTemplates.Add("water4", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "water_6", 8, 150, true, 0, Values.LayerBackground })); + ObjectTemplates.Add("water5", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "water_7", 8, 150, true, 0, Values.LayerBackground })); + ObjectTemplates.Add("waterFall", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "water_8", 4, 100, true, 0, Values.LayerBottom })); // TOOD: does the raft waterfall move faster? + ObjectTemplates.Add("waterLeft", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "water_left", 4, 100, true, 0, Values.LayerBottom })); // in the game they take 5-6 frames + ObjectTemplates.Add("waterUp", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "water_up", 4, 100, true, 0, Values.LayerBottom })); + ObjectTemplates.Add("waterRight", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "water_right", 4, 100, true, 0, Values.LayerBottom })); + ObjectTemplates.Add("waterDown", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "water_down", 4, 100, true, 0, Values.LayerBottom })); + + ObjectTemplates.Add("flower", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "flower_0", 4, 120, false, 0, Values.LayerBottom })); + ObjectTemplates.Add("flowerforest", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "flower_1", 4, 250, false, 0, Values.LayerBottom })); + ObjectTemplates.Add("flowerforest2", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "flower_2", 4, 250, false, 0, Values.LayerBottom })); + ObjectTemplates.Add("flower2", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "flower_3", 4, 250, false, 0, Values.LayerBottom })); + ObjectTemplates.Add("flower3", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "flower_4", 4, 120, false, 0, Values.LayerBottom })); + + ObjectTemplates.Add("sand1", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "sand_0", 4, 175, true, 0, Values.LayerBackground })); + ObjectTemplates.Add("sand2", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "sand_1", 4, 175, true, 0, Values.LayerBackground })); + ObjectTemplates.Add("sand3", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "sand_2", 4, 175, true, 0, Values.LayerBackground })); + + ObjectTemplates.Add("2dPondWater", new GameObjectTemplate(typeof(ObjAnimatedShiftedTile), new object[] { Resources.SourceRectangle("water_2d_0"), -2, 0, 366, 0 })); + ObjectTemplates.Add("2dWaterDungeon", new GameObjectTemplate(typeof(ObjAnimatedShiftedTile), new object[] { Resources.SourceRectangle("water_2d_1"), -2, 0, 366, 0 })); + ObjectTemplates.Add("2dWaterDungeonDark", new GameObjectTemplate(typeof(ObjAnimatedShiftedTile), new object[] { Resources.SourceRectangle("water_2d_2"), -2, 0, 350, 0 })); + ObjectTemplates.Add("2dWater", new GameObjectTemplate(typeof(ObjAnimatedShiftedTile), new object[] { Resources.SourceRectangle("water_2d_3"), -2, 0, 366, 0 })); + ObjectTemplates.Add("2dWaterDungeon2", new GameObjectTemplate(typeof(ObjAnimatedShiftedTile), new object[] { Resources.SourceRectangle("water_2d_4"), -2, 0, 366, 0 })); + + ObjectTemplates.Add("colorTileRed", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "color_tile_red", 4, 200, true, 0, Values.LayerBottom })); + ObjectTemplates.Add("colorTileGreen", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "color_tile_green", 4, 200, true, 0, Values.LayerBottom })); + ObjectTemplates.Add("colorTileBlue", new GameObjectTemplate(typeof(ObjAnimatedTile), new object[] { "color_tile_blue", 4, 200, true, 0, Values.LayerBottom })); + + ObjectTemplates.Add("break_tile_end", null); + + ObjectTemplates.Add("tower_background", new GameObjectTemplate(typeof(ObjTowerBackground), new object[] { })); + + ObjectTemplates.Add("final_stairs", new GameObjectTemplate(typeof(ObjFinalStairs), new object[] { null })); + ObjectTemplates.Add("final_background", new GameObjectTemplate(typeof(ObjFinalBackground), new object[] { null })); + ObjectTemplates.Add("final_windfish", new GameObjectTemplate(typeof(ObjWindfish), new object[] { null })); + ObjectTemplates.Add("final_fountain", new GameObjectTemplate(typeof(ObjFinalFountain), new object[] { null })); + ObjectTemplates.Add("final_background_stairs", new GameObjectTemplate(typeof(ObjFinalBackgroundStairs), new object[] { null })); + + // fence + ObjectTemplates.Add("fence", new GameObjectTemplate(typeof(ObjFence), new object[] { 15 })); + ObjectTemplates.Add("fenceUL", new GameObjectTemplate(typeof(ObjFence), new object[] { 14 })); + ObjectTemplates.Add("fenceU", new GameObjectTemplate(typeof(ObjFence), new object[] { 12 })); + ObjectTemplates.Add("fenceUR", new GameObjectTemplate(typeof(ObjFence), new object[] { 13 })); + ObjectTemplates.Add("fenceL", new GameObjectTemplate(typeof(ObjFence), new object[] { 10 })); + ObjectTemplates.Add("fenceR", new GameObjectTemplate(typeof(ObjFence), new object[] { 5 })); + ObjectTemplates.Add("fenceDL", new GameObjectTemplate(typeof(ObjFence), new object[] { 11 })); + ObjectTemplates.Add("fenceD", new GameObjectTemplate(typeof(ObjFence), new object[] { 3 })); + ObjectTemplates.Add("fenceDR", new GameObjectTemplate(typeof(ObjFence), new object[] { 7 })); + ObjectTemplates.Add("fenceTR", new GameObjectTemplate(typeof(ObjFence), new object[] { 4 })); + ObjectTemplates.Add("fenceTL", new GameObjectTemplate(typeof(ObjFence), new object[] { 8 })); + ObjectTemplates.Add("fenceBR", new GameObjectTemplate(typeof(ObjFence), new object[] { 1 })); + ObjectTemplates.Add("fenceBL", new GameObjectTemplate(typeof(ObjFence), new object[] { 2 })); + + ObjectTemplates.Add("break_fence_end", null); + + ObjectTemplates.Add("overworldObject", new GameObjectTemplate(typeof(ObjOverworld), new object[] { })); + + ObjectTemplates.Add("door", new GameObjectTemplate(typeof(ObjDoor), new object[] { 16, 16, null, null, null, 0, 0, true })); + ObjectTemplates.Add("door2d", new GameObjectTemplate(typeof(ObjDoor2d), new object[] { 16, 16, null, null, null })); + ObjectTemplates.Add("doorEgg", new GameObjectTemplate(typeof(ObjDoorEgg), new object[] { null })); + + ObjectTemplates.Add("lowFloor", new GameObjectTemplate(typeof(ObjFloor), new object[] { -2 })); + ObjectTemplates.Add("water", new GameObjectTemplate(typeof(ObjWater), new object[] { -2 })); + ObjectTemplates.Add("waterDeep", new GameObjectTemplate(typeof(ObjWaterDeep), new object[] { })); + + ObjectTemplates.Add("eggTeleporter", new GameObjectTemplate(typeof(ObjEggTeleporter), new object[] { })); + ObjectTemplates.Add("stairs", new GameObjectTemplate(typeof(ObjSlow), new object[] { 0.5f })); + ObjectTemplates.Add("teleporter", new GameObjectTemplate(typeof(ObjRaccoonTeleporter), new object[] { 0, 0, 16, 16, 0 })); + ObjectTemplates.Add("jump", new GameObjectTemplate(typeof(ObjJump), new object[] { 0, 0, 16, 16, 1.0f, 1.0f, 0, false, false })); + ObjectTemplates.Add("jumpRaft", new GameObjectTemplate(typeof(ObjJumpRaft), new object[] { 16, 80 })); + + ObjectTemplates.Add("objectSpawner", new GameObjectTemplate(typeof(ObjObjectSpawner), new object[] { null, null, null, null, true })); + ObjectTemplates.Add("objectRespawner", new GameObjectTemplate(typeof(ObjObjectRespawner), new object[] { null, null, null })); + ObjectTemplates.Add("positionDialog", new GameObjectTemplate(typeof(ObjPositionDialog), new object[] { null, null, null })); + + ObjectTemplates.Add("keysetter", new GameObjectTemplate(typeof(ObjKeySetter), new object[] { null, null })); + ObjectTemplates.Add("keyConditionSetter", new GameObjectTemplate(typeof(ObjKeyConditionSetter), new object[] { null, null, true })); + + ObjectTemplates.Add("button", new GameObjectTemplate(typeof(ObjButton), new object[] { null })); + ObjectTemplates.Add("leaveButton", new GameObjectTemplate(typeof(ObjButtonLeave), new object[] { null, 0, 16, 16, false })); + ObjectTemplates.Add("buttonTouch", new GameObjectTemplate(typeof(ObjButtonTouch), new object[] { 16, 16, null, null, true, false })); + ObjectTemplates.Add("buttonOrder", new GameObjectTemplate(typeof(ObjButtonOrder), new object[] { 0, null, null, false })); + + ObjectTemplates.Add("scriptBox", new GameObjectTemplate(typeof(ObjIntroStarter), new object[] { })); + ObjectTemplates.Add("dialogBox", new GameObjectTemplate(typeof(ObjDialogBox), new object[] { null })); + ObjectTemplates.Add("scriptOnTouch", new GameObjectTemplate(typeof(ObjScriptOnTouch), new object[] { 16, 16, null })); + + ObjectTemplates.Add("itemDisabler", new GameObjectTemplate(typeof(ObjItemDisabler), new object[] { })); + ObjectTemplates.Add("shadowDisabler", new GameObjectTemplate(typeof(ObjShadowDisabler), new object[] { })); + ObjectTemplates.Add("shadowSetter", new GameObjectTemplate(typeof(ObjShadowSetter), new object[] { 0.75f, 0.125f })); + + ObjectTemplates.Add("candyGrabber", new GameObjectTemplate(typeof(ObjCandyGrabber), new object[] { })); + ObjectTemplates.Add("candyGrabberControls", new GameObjectTemplate(typeof(ObjCandyGrabberControls), new object[] { })); + + ObjectTemplates.Add("shellHouse", new GameObjectTemplate(typeof(ObjShellHouse), new object[] { })); + ObjectTemplates.Add("swordSpawner", new GameObjectTemplate(typeof(ObjSwordSpawner), new object[] { })); + + ObjectTemplates.Add("waterCurrent0", new GameObjectTemplate(typeof(ObjQuicksand), new object[] { -0.5f, 0.0f, 1 })); + ObjectTemplates.Add("waterCurrent1", new GameObjectTemplate(typeof(ObjQuicksand), new object[] { 0.0f, -0.5f, 1 })); + ObjectTemplates.Add("waterCurrent2", new GameObjectTemplate(typeof(ObjQuicksand), new object[] { 0.5f, 0.0f, 1 })); + ObjectTemplates.Add("waterCurrent3", new GameObjectTemplate(typeof(ObjQuicksand), new object[] { 0.0f, 0.5f, 1 })); + + ObjectTemplates.Add("waterCurrentFast0", new GameObjectTemplate(typeof(ObjQuicksand), new object[] { -0.75f, 0.0f, 1 })); + ObjectTemplates.Add("waterCurrentFast1", new GameObjectTemplate(typeof(ObjQuicksand), new object[] { 0.0f, -0.75f, 1 })); + ObjectTemplates.Add("waterCurrentFast2", new GameObjectTemplate(typeof(ObjQuicksand), new object[] { 0.75f, 0.0f, 1 })); + ObjectTemplates.Add("waterCurrentFast3", new GameObjectTemplate(typeof(ObjQuicksand), new object[] { 0.0f, 0.75f, 1 })); + + ObjectTemplates.Add("quicksand", new GameObjectTemplate(typeof(ObjQuicksand), new object[] { 0.0f, 0.0f, 0 })); + ObjectTemplates.Add("rollband", new GameObjectTemplate(typeof(ObjRollBand), new object[] { 0 })); + ObjectTemplates.Add("rollbandEdge", new GameObjectTemplate(typeof(ObjRollBandEdge), new object[] { })); + + ObjectTemplates.Add("animatorL", new GameObjectTemplate(typeof(ObjAnimator), new object[] { 0, null, null, false })); + + ObjectTemplates.Add("fog", new GameObjectTemplate(typeof(ObjFog), new object[] { 1.0f, 0.4f })); + + ObjectTemplates.Add("break_real_stuff_start", null); + + ObjectTemplates.Add("destroyableStone", new GameObjectTemplate(typeof(ObjDestroyableStone), new object[] { Resources.SourceRectangle("destroyableStone"), null })); + + ObjectTemplates.Add("weatherBird", new GameObjectTemplate(typeof(ObjWeatherBird), new object[] { null })); + + ObjectTemplates.Add("chest", new GameObjectTemplate(typeof(ObjChest), new object[] { null, null, null, 0, false })); + ObjectTemplates.Add("item", new GameObjectTemplate(typeof(ObjItem), new object[] { "", "", "", "", false })); + ObjectTemplates.Add("itemTester", new GameObjectTemplate(typeof(ObjItemTester), new object[] { 16 })); + ObjectTemplates.Add("storeItem", new GameObjectTemplate(typeof(ObjStoreItem), new object[] { null, 0, 1 })); + + ObjectTemplates.Add("signpost", new GameObjectTemplate(typeof(ObjSignpost), new object[] { null, "signpost_0", new Rectangle(0, 4, 16, 12), 1 })); + ObjectTemplates.Add("signpostWoods", new GameObjectTemplate(typeof(ObjSignpost), new object[] { null, "signpost_1", new Rectangle(0, 4, 16, 12), 1 })); + ObjectTemplates.Add("sign", new GameObjectTemplate(typeof(ObjSignpost), new object[] { null, null, new Rectangle(0, 0, 16, 16), -1 })); + ObjectTemplates.Add("pushDialog", new GameObjectTemplate(typeof(ObjOnPushDialog), new object[] { null, 16, 16 })); + ObjectTemplates.Add("pushKeySetter", new GameObjectTemplate(typeof(ObjOnPushKeySetter), new object[] { null, 75, true })); + ObjectTemplates.Add("hitKeySetter", new GameObjectTemplate(typeof(ObjOnHitKeySetter), new object[] { null, 0, true, 16, 16 })); + ObjectTemplates.Add("shellHitSpawner", new GameObjectTemplate(typeof(ObjOnDashSpawner), new object[] { null, "shell" })); + ObjectTemplates.Add("sideWaves", new GameObjectTemplate(typeof(ObjIslandBackground), new object[] { })); + + ObjectTemplates.Add("aquaticPlant", new GameObjectTemplate(typeof(ObjAquaticPlant), new object[] { })); + ObjectTemplates.Add("stoneSpawner", new GameObjectTemplate(typeof(ObjStoneSpawner), new object[] { })); + + ObjectTemplates.Add("bush", new GameObjectTemplate(typeof(ObjBush), new object[] { null, "bush_0", true, true, false, Values.LayerPlayer, null })); + ObjectTemplates.Add("bushForest", new GameObjectTemplate(typeof(ObjBush), new object[] { null, "bush_1", true, true, false, Values.LayerPlayer, null })); + ObjectTemplates.Add("gras", new GameObjectTemplate(typeof(ObjBush), new object[] { null, "grass_0", false, false, true, Values.LayerBottom, null })); + ObjectTemplates.Add("gras0", new GameObjectTemplate(typeof(ObjBush), new object[] { null, "grass_0_0", false, false, true, Values.LayerBottom, null })); + ObjectTemplates.Add("gras1", new GameObjectTemplate(typeof(ObjBush), new object[] { null, "grass_0_1", false, false, true, Values.LayerBottom, null })); + ObjectTemplates.Add("gras2", new GameObjectTemplate(typeof(ObjBush), new object[] { null, "grass_0_2", false, false, true, Values.LayerBottom, null })); + ObjectTemplates.Add("gras3", new GameObjectTemplate(typeof(ObjBush), new object[] { null, "grass_0_3", false, false, true, Values.LayerBottom, null })); + ObjectTemplates.Add("grasForest", new GameObjectTemplate(typeof(ObjBush), new object[] { null, "grass_1", false, false, true, Values.LayerBottom, null })); + ObjectTemplates.Add("grasSwamp", new GameObjectTemplate(typeof(ObjBush), new object[] { null, "grass_2", false, false, true, Values.LayerBottom, null })); + + ObjectTemplates.Add("gravestone", new GameObjectTemplate(typeof(ObjMoveStone), new object[] { 15, null, "gravestone", new Rectangle(0, -12, 16, 12), Values.LayerPlayer, 1, true, null })); + ObjectTemplates.Add("moveStone", new GameObjectTemplate(typeof(ObjMoveStone), new object[] { 15, null, "movestone_0", new Rectangle(0, -16, 16, 16), Values.LayerBottom, 0, false, null })); + ObjectTemplates.Add("moveStoneCave", new GameObjectTemplate(typeof(ObjMoveStone), new object[] { 15, null, "movestone_1", new Rectangle(0, -16, 16, 16), Values.LayerBottom, 0, false, null })); + ObjectTemplates.Add("moveStoneFrogHouse", new GameObjectTemplate(typeof(ObjMoveStone), new object[] { 15, null, "movestone_2", new Rectangle(0, -16, 16, 16), Values.LayerBottom, 0, false, null })); + // why was the height 14??? + ObjectTemplates.Add("moveStoneD3", new GameObjectTemplate(typeof(ObjMoveStone), new object[] { 15, null, "movestone_3", new Rectangle(0, -16, 16, 16), Values.LayerBottom, 0, false, null })); + + ObjectTemplates.Add("leverStone", new GameObjectTemplate(typeof(ObjLeverStone), new object[] { 0 })); + + ObjectTemplates.Add("stone", new GameObjectTemplate(typeof(ObjStone), new object[] { "stone_0", null, null, "stone", false, false })); + ObjectTemplates.Add("stoneWoods", new GameObjectTemplate(typeof(ObjStone), new object[] { "stone_1", null, null, "stone", false, false })); + ObjectTemplates.Add("stoneSkull", new GameObjectTemplate(typeof(ObjStone), new object[] { "skull", null, null, null, false, false })); + ObjectTemplates.Add("pot", new GameObjectTemplate(typeof(ObjStone), new object[] { "pot_0", null, null, "stone", false, true })); + ObjectTemplates.Add("pot2", new GameObjectTemplate(typeof(ObjStone), new object[] { "pot_1", null, null, "stone", false, true })); + ObjectTemplates.Add("pot2D", new GameObjectTemplate(typeof(ObjStone), new object[] { "pot_2", null, null, null, false, false })); + ObjectTemplates.Add("d6Statue", new GameObjectTemplate(typeof(ObjStone), new object[] { "d6_statue", null, null, null, true, false })); + + ObjectTemplates.Add("castleDoor", new GameObjectTemplate(typeof(ObjCastleDoor), new object[] { null })); + + ObjectTemplates.Add("cactus", new GameObjectTemplate(typeof(ObjCactus), new object[] { })); + + ObjectTemplates.Add("overworldTeleporter", new GameObjectTemplate(typeof(ObjOverworldTeleporter), new object[] { -1 })); + + ObjectTemplates.Add("bridge", new GameObjectTemplate(typeof(ObjBridge), new object[] { })); + ObjectTemplates.Add("pullBridge", new GameObjectTemplate(typeof(ObjPullBridge), new object[] { null, false })); + + ObjectTemplates.Add("waterFallSpawner", new GameObjectTemplate(typeof(ObjWaterfall), new object[] { null })); + + ObjectTemplates.Add("book", new GameObjectTemplate(typeof(ObjBook), new object[] { null, null, 0 })); + ObjectTemplates.Add("bed", new GameObjectTemplate(typeof(ObjBed), new object[] { null, null })); + ObjectTemplates.Add("raft", new GameObjectTemplate(typeof(ObjRaft), new object[] { null })); + + // dungeon start + ObjectTemplates.Add("break_dungeon_start", null); + + ObjectTemplates.Add("dungeon", new GameObjectTemplate(typeof(ObjDungeon), new object[] { null, true, 0 })); + + ObjectTemplates.Add("upperLevel", new GameObjectTemplate(typeof(ObjUpperLevel), new object[] { 1 })); + ObjectTemplates.Add("upperLevel2", new GameObjectTemplate(typeof(ObjUpperLevel), new object[] { 2 })); + + ObjectTemplates.Add("dungeonBlackRoom", new GameObjectTemplate(typeof(ObjDungeonBlackRoom), new object[] { null, 160, 128 })); + ObjectTemplates.Add("roomDarkener", new GameObjectTemplate(typeof(ObjRoomDarkener), new object[] { 0.8f, 0.3f })); + ObjectTemplates.Add("colorShift", new GameObjectTemplate(typeof(ObjColorShift), new object[] { 0, 16, 16 })); + ObjectTemplates.Add("dungeonKeyhole", new GameObjectTemplate(typeof(ObjKeyhole), new object[] { null, null, null })); + ObjectTemplates.Add("enemytrigger", new GameObjectTemplate(typeof(ObjEnemyTrigger), new object[] { null })); + ObjectTemplates.Add("hitTrigger", new GameObjectTemplate(typeof(ObjHitTrigger), new object[] { 0, null, 16, 16, 200, true, true })); + ObjectTemplates.Add("killOrderTrigger", new GameObjectTemplate(typeof(ObjKillTrigger), new object[] { null })); + ObjectTemplates.Add("graveTrigger", new GameObjectTemplate(typeof(ObjGraveTrigger), new object[] { null })); + ObjectTemplates.Add("objectHider", new GameObjectTemplate(typeof(ObjObjectHider), new object[] { })); + + // cant change the name because we need it to be the same while adding it to the map + ObjectTemplates.Add("link2dspawner", new GameObjectTemplate(typeof(Obj2DMode), new object[] { })); + ObjectTemplates.Add("dungeonLadder", new GameObjectTemplate(typeof(ObjLadder), new object[] { false })); + ObjectTemplates.Add("dungeonLadderTop", new GameObjectTemplate(typeof(ObjLadder), new object[] { true })); + ObjectTemplates.Add("dungeonPullLever", new GameObjectTemplate(typeof(ObjPullLever), new object[] { 0.18f, null })); + + ObjectTemplates.Add("ddoor", new GameObjectTemplate(typeof(ObjDungeonDoor), new object[] { 0, null, 0, null })); + ObjectTemplates.Add("dungeonEntrance", new GameObjectTemplate(typeof(ObjDungeonEntrance), new object[] { "dungeon_entrance", null })); + ObjectTemplates.Add("dungeonSixEntry", new GameObjectTemplate(typeof(ObjDungeonSixEntry), new object[] { null })); + ObjectTemplates.Add("dungeon7_tower", new GameObjectTemplate(typeof(ObjTower), new object[] { null })); + ObjectTemplates.Add("mermaid_statue", new GameObjectTemplate(typeof(ObjMermaidStatue), new object[] { null })); + + ObjectTemplates.Add("destroyable_barrier", new GameObjectTemplate(typeof(ObjDestroyableBarrier), new object[] { Resources.SourceRectangle("destroyable_barrier"), "", 0, false, "cracked_rock" })); + ObjectTemplates.Add("stoneWall", new GameObjectTemplate(typeof(ObjDestroyableBarrier), new object[] { Resources.SourceRectangle("stone_wall_0"), "", 0, true, null })); + ObjectTemplates.Add("destroyableWallCave", new GameObjectTemplate(typeof(ObjDestroyableBarrier), new object[] { Resources.SourceRectangle("stone_wall_1"), "", 0, true, null })); + ObjectTemplates.Add("destroyableWallColorDungeon", new GameObjectTemplate(typeof(ObjDestroyableBarrier), new object[] { Resources.SourceRectangle("stone_wall_7"), "", 0, true, null })); + ObjectTemplates.Add("destroyableWallDungeon7", new GameObjectTemplate(typeof(ObjDestroyableBarrier), new object[] { Resources.SourceRectangle("stone_wall_9"), "", 0, true, null })); + + ObjectTemplates.Add("dungeonCrystal", new GameObjectTemplate(typeof(ObjCrystal), new object[] { "crystal_2", 0, false, null })); + ObjectTemplates.Add("caveCrystal", new GameObjectTemplate(typeof(ObjCrystal), new object[] { "crystal_0", 1, false, null })); + ObjectTemplates.Add("crystalD4", new GameObjectTemplate(typeof(ObjCrystal), new object[] { "crystal_1", 1, false, null })); + ObjectTemplates.Add("hardCrystal", new GameObjectTemplate(typeof(ObjCrystal), new object[] { "crystal_hard", 1, true, "crystal_hard" })); + + ObjectTemplates.Add("caveBreakingFloor", new GameObjectTemplate(typeof(ObjBreakingFloor), new object[] { "breaking_floor_0" })); + ObjectTemplates.Add("caveBreakingFloor2", new GameObjectTemplate(typeof(ObjBreakingFloor), new object[] { "breaking_floor_1" })); + ObjectTemplates.Add("caveBreakingFloor3", new GameObjectTemplate(typeof(ObjBreakingFloor), new object[] { "breaking_floor_2" })); + ObjectTemplates.Add("dungeonHole", new GameObjectTemplate(typeof(ObjBreakingFloor), new object[] { "breaking_floor_3" })); + ObjectTemplates.Add("breakingFloorCastle", new GameObjectTemplate(typeof(ObjBreakingFloor), new object[] { "breaking_floor_4" })); + ObjectTemplates.Add("dungeon5BreakingFloor", new GameObjectTemplate(typeof(ObjBreakingFloor), new object[] { "breaking_floor_5" })); + ObjectTemplates.Add("dungeon2BreakingFloor", new GameObjectTemplate(typeof(ObjBreakingFloor), new object[] { "breaking_floor_6" })); + ObjectTemplates.Add("dungeon8BreakingFloor", new GameObjectTemplate(typeof(ObjBreakingFloor), new object[] { "breaking_floor_7" })); + ObjectTemplates.Add("breakingFloorHouse", new GameObjectTemplate(typeof(ObjBreakingFloor), new object[] { "breaking_floor_8" })); + + ObjectTemplates.Add("dungeonBlacker", new GameObjectTemplate(typeof(ObjDungeonBlacker), new object[] { 255, 255, 255, 200 })); + ObjectTemplates.Add("houseBlacker", new GameObjectTemplate(typeof(ObjDungeonBlacker), new object[] { 255, 220, 180, 175 })); + ObjectTemplates.Add("caveBlacker", new GameObjectTemplate(typeof(ObjDungeonBlacker), new object[] { 255, 230, 200, 125 })); + + ObjectTemplates.Add("music", new GameObjectTemplate(typeof(ObjMusic), new object[] { null })); + ObjectTemplates.Add("musicTiles", new GameObjectTemplate(typeof(ObjMusicTile), new object[] { })); + ObjectTemplates.Add("compassSound", new GameObjectTemplate(typeof(ObjCompassSound), new object[] { null })); + ObjectTemplates.Add("shoreSound", new GameObjectTemplate(typeof(ObjShoreSound), new object[] { })); + ObjectTemplates.Add("waterfallSound", new GameObjectTemplate(typeof(ObjWaterfallSound), new object[] { })); + + ObjectTemplates.Add("dungeonFairy", new GameObjectTemplate(typeof(ObjDungeonFairy), new object[] { 0, null })); + ObjectTemplates.Add("dungeonBall", new GameObjectTemplate(typeof(ObjBall), new object[] { null })); + ObjectTemplates.Add("dungeonPillar", new GameObjectTemplate(typeof(ObjDungeonPillar), new object[] { null })); + + ObjectTemplates.Add("lava", new GameObjectTemplate(typeof(ObjLava), new object[] { })); + ObjectTemplates.Add("lava2d", new GameObjectTemplate(typeof(ObjLavaField), new object[] { "lava_2d", 4, 175, true, 0, Values.LayerBackground })); + + // real stuff + ObjectTemplates.Add("break_dungeon_start_real", null); + + ObjectTemplates.Add("light", new GameObjectTemplate(typeof(ObjLight), new object[] { 128, 255, 255, 255, 255, 0 })); + //ObjectTemplates.Add("lightHouse", new GameObjectTemplate(typeof(ObjLight), new object[] { 128, 255, 255, 255, 100, 0 })); + ObjectTemplates.Add("caveLight", new GameObjectTemplate(typeof(ObjLight), new object[] { 128, 255, 255, 255, 100, 0 })); + ObjectTemplates.Add("doorLight", new GameObjectTemplate(typeof(ObjLight), new object[] { 128, 255, 255, 255, 100, 0 })); + ObjectTemplates.Add("dungeon2dLight", new GameObjectTemplate(typeof(ObjLight), new object[] { 96, 255, 200, 200, 200, 0 })); + ObjectTemplates.Add("spriteLight", new GameObjectTemplate(typeof(ObjLightSprite), new object[] { null, 255, 255, 255, 100, 0, 0 })); + + ObjectTemplates.Add("lamp", new GameObjectTemplate(typeof(ObjLamp), new object[] { "Objects/lamp_floor", 0, true, false, null })); + ObjectTemplates.Add("lamp2", new GameObjectTemplate(typeof(ObjLamp), new object[] { "Objects/lamp_torch", 0, false, false, null })); + ObjectTemplates.Add("torch_d2_2d", new GameObjectTemplate(typeof(ObjLamp), new object[] { "Objects/lamp_torch_blue", 0, false, false, null })); + ObjectTemplates.Add("torch_d4_2d", new GameObjectTemplate(typeof(ObjLamp), new object[] { "Objects/torch_d4_d4", 0, false, false, null })); + ObjectTemplates.Add("torch_d6_2d", new GameObjectTemplate(typeof(ObjLamp), new object[] { "Objects/torch_d6", 0, false, false, null })); + + ObjectTemplates.Add("lamp_wall_0", new GameObjectTemplate(typeof(ObjLamp), new object[] { "Objects/lamp_wall", 0, false, false, null })); + ObjectTemplates.Add("lamp_wall_1", new GameObjectTemplate(typeof(ObjLamp), new object[] { "Objects/lamp_wall", 1, false, false, null })); + ObjectTemplates.Add("lamp_wall_2", new GameObjectTemplate(typeof(ObjLamp), new object[] { "Objects/lamp_wall", 2, false, false, null })); + ObjectTemplates.Add("lamp_wall_3", new GameObjectTemplate(typeof(ObjLamp), new object[] { "Objects/lamp_wall", 3, false, false, null })); + + ObjectTemplates.Add("lamp_wall_house_0", new GameObjectTemplate(typeof(ObjLamp), new object[] { "Objects/lamp_wall_1", 0, false, false, null })); + ObjectTemplates.Add("lamp_wall_house_1", new GameObjectTemplate(typeof(ObjLamp), new object[] { "Objects/lamp_wall_1", 1, false, false, null })); + ObjectTemplates.Add("lamp_wall_house_2", new GameObjectTemplate(typeof(ObjLamp), new object[] { "Objects/lamp_wall_1", 2, false, false, null })); + ObjectTemplates.Add("lamp_wall_house_3", new GameObjectTemplate(typeof(ObjLamp), new object[] { "Objects/lamp_wall_1", 3, false, false, null })); + + ObjectTemplates.Add("lamp_wall_dt_0", new GameObjectTemplate(typeof(ObjLamp), new object[] { "Objects/lamp_wall_2", 0, false, false, null })); + ObjectTemplates.Add("lamp_wall_dt_1", new GameObjectTemplate(typeof(ObjLamp), new object[] { "Objects/lamp_wall_2", 1, false, false, null })); + ObjectTemplates.Add("lamp_wall_dt_2", new GameObjectTemplate(typeof(ObjLamp), new object[] { "Objects/lamp_wall_2", 2, false, false, null })); + ObjectTemplates.Add("lamp_wall_dt_3", new GameObjectTemplate(typeof(ObjLamp), new object[] { "Objects/lamp_wall_2", 3, false, false, null })); + + ObjectTemplates.Add("torch_d4", new GameObjectTemplate(typeof(ObjLamp), new object[] { "Objects/torch_d4", 0, false, false, null })); + ObjectTemplates.Add("torch_d8", new GameObjectTemplate(typeof(ObjLamp), new object[] { "Objects/torch_d8", 0, false, false, null })); + + ObjectTemplates.Add("dungeonWall", new GameObjectTemplate(typeof(ObjDestroyableBarrier), new object[] { Resources.SourceRectangle("stone_wall_2"), "", 0, true, null })); + ObjectTemplates.Add("dungeonWall3", new GameObjectTemplate(typeof(ObjDestroyableBarrier), new object[] { Resources.SourceRectangle("stone_wall_3"), "", 0, true, null })); + ObjectTemplates.Add("dungeonWall3cracks", new GameObjectTemplate(typeof(ObjDestroyableBarrier), new object[] { Resources.SourceRectangle("stone_wall_4"), "", 0, true, null })); + ObjectTemplates.Add("dungeon4Block", new GameObjectTemplate(typeof(ObjDestroyableBarrier), new object[] { Resources.SourceRectangle("stone_wall_5"), "", 0, false, "rock_cracks" })); + ObjectTemplates.Add("dungeon6Wall", new GameObjectTemplate(typeof(ObjDestroyableBarrier), new object[] { Resources.SourceRectangle("stone_wall_6"), "", 0, true, null })); + ObjectTemplates.Add("dungeon7Wall", new GameObjectTemplate(typeof(ObjDestroyableBarrier), new object[] { Resources.SourceRectangle("stone_wall_8"), "", 0, true, null })); + ObjectTemplates.Add("dungeon8Wall", new GameObjectTemplate(typeof(ObjDestroyableBarrier), new object[] { Resources.SourceRectangle("stone_wall_10"), "", 0, true, null })); + ObjectTemplates.Add("dungeon8WallCracks", new GameObjectTemplate(typeof(ObjDestroyableBarrier), new object[] { Resources.SourceRectangle("stone_wall_11"), "", 0, true, null })); + ObjectTemplates.Add("caveWallBottom", new GameObjectTemplate(typeof(ObjDestroyableBarrier), new object[] { Resources.SourceRectangle("stone_wall_12"), "", 0, true, null })); + + ObjectTemplates.Add("dungeonSwitch", new GameObjectTemplate(typeof(ObjDungeonSwitch), new object[] { null })); + ObjectTemplates.Add("dungeonOneWay", new GameObjectTemplate(typeof(ObjDungeonOneWay), new object[] { })); + ObjectTemplates.Add("dungeonTeleporter", new GameObjectTemplate(typeof(ObjDungeonTeleporter), new object[] { null, null })); + ObjectTemplates.Add("keyholeBlock", new GameObjectTemplate(typeof(ObjKeyholeBlock), new object[] { null })); + + ObjectTemplates.Add("dungeonBarriere", new GameObjectTemplate(typeof(ObjDungeonBarrier), new object[] { null, false, 0 })); + ObjectTemplates.Add("dungeonBarriereOrange", new GameObjectTemplate(typeof(ObjDungeonBarrier), new object[] { null, false, 1 })); + ObjectTemplates.Add("dungeonBarriereRed", new GameObjectTemplate(typeof(ObjDungeonBarrier), new object[] { null, false, 2 })); + + ObjectTemplates.Add("dungeonColorSwitch", new GameObjectTemplate(typeof(ObjDungeonColorSwitch), new object[] { null, 0, 2, 0, 0 })); + + ObjectTemplates.Add("break_dungeon_end", null); + + ObjectTemplates.Add("hole", new GameObjectTemplate(typeof(ObjHole), new object[] { 14, 14, Rectangle.Empty, 1, 1, 0 })); + ObjectTemplates.Add("visiblehole", new GameObjectTemplate(typeof(ObjHole), new object[] { 14, 14, Resources.SourceRectangle("hole_0"), 1, 1, 0 })); + ObjectTemplates.Add("fullHole", new GameObjectTemplate(typeof(ObjHole), new object[] { 16, 16, Rectangle.Empty, 0, 0, 0 })); + ObjectTemplates.Add("holeReset", new GameObjectTemplate(typeof(ObjHoleResetPoint), new object[] { 0 })); + ObjectTemplates.Add("holeTeleporter", new GameObjectTemplate(typeof(ObjHoleTeleporter), new object[] { null, null })); + + ObjectTemplates.Add("doorEnding", new GameObjectTemplate(typeof(ObjDoorEnding), new object[] { })); + + ObjectTemplates.Add("boat", new GameObjectTemplate(typeof(ObjBoat), new object[] { })); + ObjectTemplates.Add("movingPlatform2D", new GameObjectTemplate(typeof(ObjMovingPlatform), new object[] { 0, 0, 0.0f, 1000, 0 })); + ObjectTemplates.Add("chainPlatform", new GameObjectTemplate(typeof(ObjChainPlatform), new object[] { null, 0, 0 })); + ObjectTemplates.Add("spikes2D", new GameObjectTemplate(typeof(ObjSpikes2D), new object[] { })); + + ObjectTemplates.Add("dungeonRollBand", new GameObjectTemplate(typeof(ObjRollBandDungeon), new object[] { 0 })); + ObjectTemplates.Add("dungeonOwl", new GameObjectTemplate(typeof(ObjDungeonOwl), new object[] { null })); + ObjectTemplates.Add("dungeonHorseHead", new GameObjectTemplate(typeof(ObjDungeonHorseHead), new object[] { null, 0 })); + ObjectTemplates.Add("colorJumpTile", new GameObjectTemplate(typeof(ObjColorJumpTile), new object[] { 0 })); + ObjectTemplates.Add("spikes", new GameObjectTemplate(typeof(ObjSpikes), new object[] { })); + ObjectTemplates.Add("iceBlock", new GameObjectTemplate(typeof(ObjIceBlock), new object[] { })); + + ObjectTemplates.Add("break_hole_end", null); + ObjectTemplates.Add("break_people_start", null); + + // npcs + ObjectTemplates.Add("person", new GameObjectTemplate(typeof(ObjPerson), new object[] { null, new Rectangle(0, 0, 14, 10), Vector2.Zero, null })); + ObjectTemplates.Add("personNew", new GameObjectTemplate(typeof(ObjPersonNew), new object[] { null, null, null, null, new Rectangle(0, 0, 14, 10) })); + ObjectTemplates.Add("letterBoy", new GameObjectTemplate(typeof(ObjLetterBoy), new object[] { null })); + ObjectTemplates.Add("maria", new GameObjectTemplate(typeof(ObjMarin), new object[] { })); + ObjectTemplates.Add("mariaDisabler", new GameObjectTemplate(typeof(ObjMarinDisabler), new object[] { })); + ObjectTemplates.Add("grandmother", new GameObjectTemplate(typeof(ObjGrandmother), new object[] { null, null })); + ObjectTemplates.Add("mariaDungeonEntry", new GameObjectTemplate(typeof(ObjMarinDungeonEntry), new object[] { 16, 16 })); + ObjectTemplates.Add("owl", new GameObjectTemplate(typeof(ObjOwl), new object[] { null, new Rectangle(-16, 32, 48, 32), false, "owl", 0 })); + ObjectTemplates.Add("fisherman", new GameObjectTemplate(typeof(ObjFisherman), new object[] { })); + ObjectTemplates.Add("alligator", new GameObjectTemplate(typeof(ObjAlligator), new object[] { })); + ObjectTemplates.Add("raccoon", new GameObjectTemplate(typeof(ObjRaccoon), new object[] { })); + ObjectTemplates.Add("shopkeeper", new GameObjectTemplate(typeof(ObjShopkeeper), new object[] { })); + ObjectTemplates.Add("tracy", new GameObjectTemplate(typeof(ObjTracy), new object[] { })); + ObjectTemplates.Add("mamu", new GameObjectTemplate(typeof(ObjMamu), new object[] { null })); + ObjectTemplates.Add("manbo", new GameObjectTemplate(typeof(ObjManbo), new object[] { null })); + ObjectTemplates.Add("walrus", new GameObjectTemplate(typeof(ObjWalrus), new object[] { null })); + ObjectTemplates.Add("walrusSwim", new GameObjectTemplate(typeof(ObjWalrusSwim), new object[] { null })); + ObjectTemplates.Add("mermaid", new GameObjectTemplate(typeof(ObjMermaid), new object[] { null })); + ObjectTemplates.Add("ghost", new GameObjectTemplate(typeof(ObjGhost), new object[] { })); + ObjectTemplates.Add("lostBoy", new GameObjectTemplate(typeof(ObjLostBoy), new object[] { })); + ObjectTemplates.Add("photoMouse", new GameObjectTemplate(typeof(ObjPhotoMouse), new object[] { null, null })); + ObjectTemplates.Add("chickenDude", new GameObjectTemplate(typeof(ObjChickenDude), new object[] { null })); + ObjectTemplates.Add("painter", new GameObjectTemplate(typeof(ObjPainter), new object[] { })); + ObjectTemplates.Add("hippo", new GameObjectTemplate(typeof(ObjHippo), new object[] { })); + ObjectTemplates.Add("trendy", new GameObjectTemplate(typeof(ObjTrendy), new object[] { })); + + ObjectTemplates.Add("BowWow", new GameObjectTemplate(typeof(ObjBowWow), new object[] { null })); + ObjectTemplates.Add("npcMonkey", new GameObjectTemplate(typeof(ObjMonkey), new object[] { })); + ObjectTemplates.Add("bobWowSmall", new GameObjectTemplate(typeof(ObjBowWowSmall), new object[] { null })); + ObjectTemplates.Add("bird", new GameObjectTemplate(typeof(ObjBird), new object[] { })); + ObjectTemplates.Add("cock", new GameObjectTemplate(typeof(ObjCock), new object[] { null })); + ObjectTemplates.Add("letterBird", new GameObjectTemplate(typeof(ObjLetterBird), new object[] { "NPCs/letterBird" })); + ObjectTemplates.Add("letterBirdGreen", new GameObjectTemplate(typeof(ObjLetterBird), new object[] { "NPCs/letterBirdGreen" })); + ObjectTemplates.Add("dogo", new GameObjectTemplate(typeof(ObjDog), new object[] { })); + ObjectTemplates.Add("mouse", new GameObjectTemplate(typeof(ObjMouse), new object[] { })); + ObjectTemplates.Add("frog", new GameObjectTemplate(typeof(ObjFrog), new object[] { })); + ObjectTemplates.Add("butterfly", new GameObjectTemplate(typeof(ObjButterfly), new object[] { })); + ObjectTemplates.Add("fairy", new GameObjectTemplate(typeof(ObjFairy), new object[] { null })); + ObjectTemplates.Add("npcBat", new GameObjectTemplate(typeof(ObjBat), new object[] { null })); + ObjectTemplates.Add("npcColorDungeon", new GameObjectTemplate(typeof(ObjColorDungeonNPC), new object[] { null, false })); + + ObjectTemplates.Add("honeycomb", new GameObjectTemplate(typeof(ObjHoneycomb), new object[] { null })); + ObjectTemplates.Add("tarinZZZ", new GameObjectTemplate(typeof(ObjZZZSpawner), new object[] { })); + + // fishing game + ObjectTemplates.Add("fish_small", new GameObjectTemplate(typeof(ObjFish), new object[] { 0, 0, 0 })); + ObjectTemplates.Add("fish_big", new GameObjectTemplate(typeof(ObjFish), new object[] { 1, 0, 0 })); + ObjectTemplates.Add("fishing_link", new GameObjectTemplate(typeof(ObjLinkFishing), new object[] { })); + ObjectTemplates.Add("ballGame", new GameObjectTemplate(typeof(ObjBallGame), new object[] { null })); + ObjectTemplates.Add("ballChildrenAttacked", new GameObjectTemplate(typeof(ObjBallChildrenAttacked), new object[] { null })); + + ObjectTemplates.Add("break_people_end", null); + ObjectTemplates.Add("break_enemies_start", null); + + // enemies + ObjectTemplates.Add("enemy_respawner", new GameObjectTemplate(typeof(ObjEnemyRespawner), new object[] { null, null })); + ObjectTemplates.Add("e1", new GameObjectTemplate(typeof(EnemySeaUrchin), new object[] { })); + ObjectTemplates.Add("e2", new GameObjectTemplate(typeof(EnemyOctorok), new object[] { })); + ObjectTemplates.Add("e_wingedOctorok", new GameObjectTemplate(typeof(EnemyOctorokWinged), new object[] { })); + ObjectTemplates.Add("e3", new GameObjectTemplate(typeof(EnemyLeever), new object[] { })); + ObjectTemplates.Add("e4", new GameObjectTemplate(typeof(EnemyCrab), new object[] { })); + ObjectTemplates.Add("e5", new GameObjectTemplate(typeof(EnemyMoblin), new object[] { })); + ObjectTemplates.Add("moblinSword", new GameObjectTemplate(typeof(EnemyMoblinSword), new object[] { })); + ObjectTemplates.Add("shroudedStalfos", new GameObjectTemplate(typeof(EnemyShroudedStalfos), new object[] { })); + ObjectTemplates.Add("stalfosKnight", new GameObjectTemplate(typeof(EnemyStalfosKnight), new object[] { })); + ObjectTemplates.Add("e19", new GameObjectTemplate(typeof(EnemyMoblinPig), new object[] { })); + ObjectTemplates.Add("e_moblinPigSword", new GameObjectTemplate(typeof(EnemyMoblinPigSword), new object[] { })); + ObjectTemplates.Add("e_darknutSpear", new GameObjectTemplate(typeof(EnemyDarknutSpear), new object[] { })); + ObjectTemplates.Add("e_darknut", new GameObjectTemplate(typeof(EnemyDarknut), new object[] { })); + ObjectTemplates.Add("e_wallKnight", new GameObjectTemplate(typeof(ObjWallKnight), new object[] { false })); + ObjectTemplates.Add("e_madBomber", new GameObjectTemplate(typeof(EnemyMadBomber), new object[] { })); + ObjectTemplates.Add("e6", new GameObjectTemplate(typeof(EnemyBladeTrap), new object[] { 0, 0, 0, 0 })); + ObjectTemplates.Add("e8", new GameObjectTemplate(typeof(EnemyHardhatBeetle), new object[] { })); + ObjectTemplates.Add("e9", new GameObjectTemplate(typeof(EnemyGreenZol), new object[] { 0, false })); + ObjectTemplates.Add("e15", new GameObjectTemplate(typeof(EnemyRedZol), new object[] { })); + ObjectTemplates.Add("e7", new GameObjectTemplate(typeof(EnemyGel), new object[] { })); + ObjectTemplates.Add("e10", new GameObjectTemplate(typeof(EnemyKeese), new object[] { })); + ObjectTemplates.Add("e11", new GameObjectTemplate(typeof(EnemySpark), new object[] { 0, true, null })); + ObjectTemplates.Add("e_antiFairy", new GameObjectTemplate(typeof(EnemyAntiFairy), new object[] { })); + ObjectTemplates.Add("e12", new GameObjectTemplate(typeof(EnemyMiniMoldorm), new object[] { })); + ObjectTemplates.Add("polsVoice", new GameObjectTemplate(typeof(EnemyPolsVoice), new object[] { })); + ObjectTemplates.Add("e_dungeonGhost", new GameObjectTemplate(typeof(EnemyBooBuddy), new object[] { null })); + ObjectTemplates.Add("e_bomber", new GameObjectTemplate(typeof(EnemyBomber), new object[] { })); + ObjectTemplates.Add("e_pokey", new GameObjectTemplate(typeof(EnemyPokey), new object[] { })); + ObjectTemplates.Add("e_spinyBeetle", new GameObjectTemplate(typeof(EnemySpinyBeetle), new object[] { 0 })); + ObjectTemplates.Add("e_tektite", new GameObjectTemplate(typeof(EnemyTektite), new object[] { })); + ObjectTemplates.Add("e13", new GameObjectTemplate(typeof(EnemyStalfosOrange), new object[] { false })); + ObjectTemplates.Add("stalfosGreen", new GameObjectTemplate(typeof(EnemyStalfosGreen), new object[] { })); + ObjectTemplates.Add("e_armos", new GameObjectTemplate(typeof(EnemyArmos), new object[] { false })); + ObjectTemplates.Add("e_Vacuum", new GameObjectTemplate(typeof(EnemyVacuum), new object[] { null, null, false })); + ObjectTemplates.Add("e_bombite", new GameObjectTemplate(typeof(EnemyBombite), new object[] { })); + ObjectTemplates.Add("e_bombiteGreen", new GameObjectTemplate(typeof(EnemyBombiteGreen), new object[] { })); + ObjectTemplates.Add("e16", new GameObjectTemplate(typeof(EnemyLikeLike), new object[] { })); + ObjectTemplates.Add("e17", new GameObjectTemplate(typeof(EnemyBuzzBlob), new object[] { })); + ObjectTemplates.Add("e18", new GameObjectTemplate(typeof(EnemyRiverZora), new object[] { })); + ObjectTemplates.Add("e20", new GameObjectTemplate(typeof(EnemyCrow), new object[] { false })); + ObjectTemplates.Add("e_raven", new GameObjectTemplate(typeof(EnemyRaven), new object[] { })); + ObjectTemplates.Add("e21", new GameObjectTemplate(typeof(EnemyGhini), new object[] { false, false })); + ObjectTemplates.Add("e_giantGhini", new GameObjectTemplate(typeof(EnemyGhiniGiant), new object[] { false })); + ObjectTemplates.Add("zombie", new GameObjectTemplate(typeof(EnemyZombie), new object[] { })); + ObjectTemplates.Add("zombieSpawner", new GameObjectTemplate(typeof(ObjZombieSpawner), new object[] { 1250 })); + ObjectTemplates.Add("e23", new GameObjectTemplate(typeof(EnemyPincer), new object[] { })); + ObjectTemplates.Add("e_Beetle", new GameObjectTemplate(typeof(EnemyBeetle), new object[] { })); + ObjectTemplates.Add("e_BeetleSpawner", new GameObjectTemplate(typeof(ObjBeetleSpawner), new object[] { })); + ObjectTemplates.Add("spikedBeetle", new GameObjectTemplate(typeof(EnemySpikedBeetle), new object[] { })); + ObjectTemplates.Add("goponga_flower", new GameObjectTemplate(typeof(EnemyGopongaFlower), new object[] { })); + ObjectTemplates.Add("goponga_flower_giant", new GameObjectTemplate(typeof(EnemyGopongaFlowerGiant), new object[] { })); + ObjectTemplates.Add("e_fish", new GameObjectTemplate(typeof(EnemyFish), new object[] { })); + ObjectTemplates.Add("cardboy", new GameObjectTemplate(typeof(EnemyCardBoy), new object[] { 0, null })); + ObjectTemplates.Add("monkey", new GameObjectTemplate(typeof(EnemyMonkey), new object[] { })); + ObjectTemplates.Add("torchTrap", new GameObjectTemplate(typeof(EnemyTorchTrap), new object[] { null })); + ObjectTemplates.Add("e_pairodd", new GameObjectTemplate(typeof(EnemyPairodd), new object[] { })); + ObjectTemplates.Add("maskMimic", new GameObjectTemplate(typeof(EnemyMaskMimic), new object[] { })); + ObjectTemplates.Add("e_ArmMimic", new GameObjectTemplate(typeof(EnemyArmMimic), new object[] { })); + ObjectTemplates.Add("e_waterTektite", new GameObjectTemplate(typeof(EnemyWaterTektite), new object[] { })); + ObjectTemplates.Add("e_peahat", new GameObjectTemplate(typeof(EnemyPeahat), new object[] { })); + ObjectTemplates.Add("e_ironMask", new GameObjectTemplate(typeof(EnemyIronMask), new object[] { })); + ObjectTemplates.Add("e_star", new GameObjectTemplate(typeof(EnemyStar), new object[] { })); + ObjectTemplates.Add("e_flyingTile", new GameObjectTemplate(typeof(EnemyFlyingTile), new object[] { null, 0, 0 })); + ObjectTemplates.Add("e_wizzrobe", new GameObjectTemplate(typeof(EnemyWizzrobe), new object[] { })); + ObjectTemplates.Add("e_beamos", new GameObjectTemplate(typeof(EnemyBeamos), new object[] { })); + ObjectTemplates.Add("e_camoGoblin", new GameObjectTemplate(typeof(EnemyCamoGoblin), new object[] { 0 })); + ObjectTemplates.Add("e_bonePutter", new GameObjectTemplate(typeof(EnemyBonePutter), new object[] { true })); + ObjectTemplates.Add("e_karakoro", new GameObjectTemplate(typeof(EnemyKarakoro), new object[] { 0, null, null })); + ObjectTemplates.Add("e_gibdo", new GameObjectTemplate(typeof(EnemyGibdo), new object[] { })); + ObjectTemplates.Add("e_antiKirby", new GameObjectTemplate(typeof(EnemyAntiKirby), new object[] { })); + ObjectTemplates.Add("e_vire", new GameObjectTemplate(typeof(EnemyVire), new object[] { })); + ObjectTemplates.Add("e_rope", new GameObjectTemplate(typeof(EnemyRope), new object[] { })); + ObjectTemplates.Add("e_flameFountain", new GameObjectTemplate(typeof(EnemyFlameFountain), new object[] { })); + ObjectTemplates.Add("e_floorLayer", new GameObjectTemplate(typeof(EnemyFloorLayer), new object[] { 0, null })); + ObjectTemplates.Add("e_rockSpawner", new GameObjectTemplate(typeof(EnemyRockSpawner), new object[] { 160, 128 })); + ObjectTemplates.Add("e_anglerFry", new GameObjectTemplate(typeof(EnemyAnglerFry), new object[] { 0 })); + + + ObjectTemplates.Add("break_enemies_end", null); + ObjectTemplates.Add("break_2d_start", null); + + // 2d enemies + ObjectTemplates.Add("e14", new GameObjectTemplate(typeof(EnemyGoomba), new object[] { })); + ObjectTemplates.Add("e_CheepCheep", new GameObjectTemplate(typeof(EnemyCheepCheep), new object[] { 0, false })); + ObjectTemplates.Add("e_Bloober", new GameObjectTemplate(typeof(EnemyBloober), new object[] { })); + ObjectTemplates.Add("e_giantBubble", new GameObjectTemplate(typeof(EnemyGiantBubble), new object[] { })); + ObjectTemplates.Add("e_thwimp", new GameObjectTemplate(typeof(EnemyThwimp), new object[] { })); + + ObjectTemplates.Add("e_PiranhaPlant", new GameObjectTemplate(typeof(EnemyPiranhaPlant), new object[] { })); + ObjectTemplates.Add("e_MegaThwomp", new GameObjectTemplate(typeof(EnemyMegaThwomp), new object[] { })); + ObjectTemplates.Add("e_SpikedThwomp", new GameObjectTemplate(typeof(EnemySpikedThwomp), new object[] { })); + ObjectTemplates.Add("e_Podoboo", new GameObjectTemplate(typeof(EnemyPodoboo), new object[] { 0 })); + + ObjectTemplates.Add("break_2d_end", null); + ObjectTemplates.Add("break_mbosses_start", null); + + // mini-bosses + ObjectTemplates.Add("mb1", new GameObjectTemplate(typeof(MBossRollingBones), new object[] { null, null })); + ObjectTemplates.Add("mb_king_moblin", new GameObjectTemplate(typeof(MKingMoblin), new object[] { null, null })); + ObjectTemplates.Add("mb_hinox", new GameObjectTemplate(typeof(MBossHinox), new object[] { null, 0 })); + ObjectTemplates.Add("mb_BallAndChainSoldier", new GameObjectTemplate(typeof(MBossBallAndChainSoldier), new object[] { null })); + ObjectTemplates.Add("mb_dodongo_snake", new GameObjectTemplate(typeof(MDodongoSnake), new object[] { null, 0, false })); + ObjectTemplates.Add("mb_desert_lanmola", new GameObjectTemplate(typeof(MBossDesertLanmola), new object[] { null, null })); + ObjectTemplates.Add("mb_cue_ball", new GameObjectTemplate(typeof(MBossCueBall), new object[] { null, null })); + ObjectTemplates.Add("mb_MasterStalfos", new GameObjectTemplate(typeof(MBossMasterStalfos), new object[] { null, 0 })); + ObjectTemplates.Add("mb_Gohma", new GameObjectTemplate(typeof(MBossGohma), new object[] { null, false })); + ObjectTemplates.Add("mb_ArmosKnight", new GameObjectTemplate(typeof(MBossArmosKnight), new object[] { null })); + ObjectTemplates.Add("mb_Smasher", new GameObjectTemplate(typeof(MBossSmasher), new object[] { null })); + ObjectTemplates.Add("mb_StoneHinox", new GameObjectTemplate(typeof(MBossStoneHinox), new object[] { null })); + ObjectTemplates.Add("mb_GiantBuzzBlob", new GameObjectTemplate(typeof(MBossGiantBuzzBlob), new object[] { null })); + ObjectTemplates.Add("mb_GrimCreeper", new GameObjectTemplate(typeof(MBossGrimCreeper), new object[] { null })); + ObjectTemplates.Add("mb_TurtleRock", new GameObjectTemplate(typeof(MBossTurtleRock), new object[] { null })); + ObjectTemplates.Add("mb_Blaino", new GameObjectTemplate(typeof(MBossBlaino), new object[] { null, null })); + + ObjectTemplates.Add("break_mbosses_end", null); + ObjectTemplates.Add("break_nightmare_start", null); + + // nightmares + ObjectTemplates.Add("nightmare-moldorm", new GameObjectTemplate(typeof(BossMoldorm), new object[] { null, null })); + ObjectTemplates.Add("nightmare_genie", new GameObjectTemplate(typeof(BossGenieBottle), new object[] { null })); + ObjectTemplates.Add("nightmare_slime_eye", new GameObjectTemplate(typeof(BossSlimeEye), new object[] { null, null, null })); + ObjectTemplates.Add("nightmare_angler_fish", new GameObjectTemplate(typeof(BossAnglerFish), new object[] { null })); + ObjectTemplates.Add("nightmare_slime_eel", new GameObjectTemplate(typeof(BossSlimeEelSpawn), new object[] { null })); + ObjectTemplates.Add("facade", new GameObjectTemplate(typeof(BossFacade), new object[] { null, null })); + ObjectTemplates.Add("nightmare_HardhitBeetle", new GameObjectTemplate(typeof(BossHardhitBeetle), new object[] { null })); + ObjectTemplates.Add("nightmare_EvilEagle", new GameObjectTemplate(typeof(BossEvilEagle), new object[] { null })); + ObjectTemplates.Add("nightmare_HotHead", new GameObjectTemplate(typeof(BossHotHead), new object[] { null })); + ObjectTemplates.Add("nightmare", new GameObjectTemplate(typeof(BossFinalBoss), new object[] { null })); + + + foreach (var objectTemplate in ObjectTemplates) + { + var name = objectTemplate.Key; + var gameObjectTemplate = objectTemplate.Value; + + // editor break? + if (gameObjectTemplate == null) + continue; + + foreach (var constructor in gameObjectTemplate.ObjectType.GetConstructors()) + { + var parameters = constructor.GetParameters(); + // the system currently only supports constructors with 3 additional parameters (map, posX, posY) + if (gameObjectTemplate.Parameter.Length + 3 != parameters.Length) + continue; + + var correctParameter = true; + for (var i = 3; i < parameters.Length; i++) + { + if (gameObjectTemplate.Parameter[i - 3] != null && + parameters[i].ParameterType != gameObjectTemplate.Parameter[i - 3].GetType()) + { + correctParameter = false; + break; + } + } + + if (!correctParameter) + continue; + + ObjectSpawner.Add(name, ObjActivator.GetActivator(constructor)); + + // parameter + GameObjectParameter.Add(name, constructor.GetParameters()); + } + } + + if (Game1.EditorMode) + { + // create the gameObjects used in the editor + var editorMap = Map.Map.CreateEmptyMap(); + foreach (var template in GameObjectTemplates.ObjectTemplates) + { + if (template.Value == null) + continue; + + // check if a base constructor exists and use this instead + if (template.Value.ObjectType.GetConstructor(Type.EmptyTypes) != null) + ObjectEditorScreen.EditorObjectTemplates.Add(template.Key, (GameObject)Activator.CreateInstance(template.Value.ObjectType)); + else + ObjectEditorScreen.EditorObjectTemplates.Add(template.Key, ObjectManager.GetGameObject(editorMap, + template.Key, AddPositionToParameterArray(template.Value.Parameter, editorMap, 0, 0))); + } + } + } + + private static object[] AddPositionToParameterArray(object[] objParameter, Map.Map map, int posX, int posY) + { + // object has only posX and posY as parameter + if (objParameter == null) + return new object[] { map, posX, posY }; + + var outParameter = new object[objParameter.Length + 3]; + Array.Copy(objParameter, 0, outParameter, 3, objParameter.Length); + outParameter[0] = map; + outParameter[1] = posX; + outParameter[2] = posY; + + return outParameter; + } + } +} diff --git a/InGame/GameObjects/MidBoss/MBossArmosKnight.cs b/InGame/GameObjects/MidBoss/MBossArmosKnight.cs new file mode 100644 index 0000000..18696d1 --- /dev/null +++ b/InGame/GameObjects/MidBoss/MBossArmosKnight.cs @@ -0,0 +1,336 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + class MBossArmosKnight : GameObject + { + private readonly Animator _animator; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AnimationComponent _animationComponent; + private readonly AiDamageState _aiDamageState; + private readonly AiTriggerSwitch _knockbackSwitch; + private readonly DamageFieldComponent _damageField; + + private string _saveKey; + private int _jumpCount; + private bool _hitRepelling = true; + + private const int ShakeTime = 500; + private const float WalkSpeed = 0.6f; + private const int AttackUpTime = 400; + + public MBossArmosKnight() : base("armos knight") { } + + public MBossArmosKnight(Map.Map map, int posX, int posY, string saveKey) : base(map) + { + EntityPosition = new CPosition(posX + 16, posY + 32, 0); + EntitySize = new Rectangle(-16, -32, 32, 32); + + // check if the boss was already killed + _saveKey = saveKey; + if (!string.IsNullOrEmpty(_saveKey) && Game1.GameManager.SaveManager.GetString(_saveKey) == "1") + { + // we need to make sure to spawn the key because the player could walk out after killing the boss without collecting the key + SpawnKey(); + IsDead = true; + return; + } + + _animator = AnimatorSaveLoad.LoadAnimator("MidBoss/armosKnight"); + + var sprite = new CSprite(EntityPosition); + _animationComponent = new AnimationComponent(_animator, sprite, new Vector2(0, -32)); + + _body = new BodyComponent(EntityPosition, -14, -20, 28, 20, 8) + { + IgnoreHoles = true, + Gravity = -0.15f, + DragAir = 0.875f, + MaxJumpHeight = 8 + }; + + _aiComponent = new AiComponent(); + _aiComponent.Trigger.Add(_knockbackSwitch = new AiTriggerSwitch(400)); + + var stateIdle = new AiState(UpdateIdle) { Init = InitIdle }; + var stateAwake = new AiState(UpdateAwake) { Init = InitAwake }; + var stateShake = new AiState(); + stateShake.Trigger.Add(new AiTriggerCountdown(ShakeTime, ShakeTick, ShakeEnd)); + var stateWalk = new AiState(UpdateWalk) { Init = InitWalk }; + var stateJump = new AiState(); + var stateAttackUp = new AiState { Init = InitAttackUp }; + stateAttackUp.Trigger.Add(new AiTriggerCountdown(AttackUpTime, AttackUpTick, AttackUpEnd)); + var stateAttackWait = new AiState(); + stateAttackWait.Trigger.Add(new AiTriggerCountdown(200, null, () => _aiComponent.ChangeState("attack"))); + var stateAttack = new AiState(UpdateAttack) { Init = InitAttack }; + var stateAttackFinished = new AiState(); + stateAttackFinished.Trigger.Add(new AiTriggerCountdown(850, null, () => _aiComponent.ChangeState("walk"))); + + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("awake", stateAwake); + _aiComponent.States.Add("shake", stateShake); + _aiComponent.States.Add("walk", stateWalk); + _aiComponent.States.Add("jump", stateJump); + _aiComponent.States.Add("attackUp", stateAttackUp); + _aiComponent.States.Add("attackWait", stateAttackWait); + _aiComponent.States.Add("attack", stateAttack); + _aiComponent.States.Add("attackFinished", stateAttackFinished); + _aiDamageState = new AiDamageState(this, _body, _aiComponent, sprite, 2 * 6, false) { BossHitSound = true }; + _aiDamageState.AddBossDamageState(RemoveObject); + + _aiComponent.ChangeState("idle"); + + var damageCollider = new CBox(EntityPosition, -14, -24, 0, 28, 24, 8, true); + var hittableBox = new CBox(EntityPosition, -13, -24, 0, 26, 22, 8); + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageCollider, HitType.Enemy, 6)); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, _animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite) { ShadowWidth = 24, ShadowHeight = 6 }); + } + + private void InitIdle() + { + _animator.Play("idle"); + } + + private void UpdateIdle() + { + // awake if the player is close enough + var distance = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (distance.Length() < 32) + _aiComponent.ChangeState("awake"); + } + + private void InitAwake() + { + _animator.Play("red"); + Game1.GameManager.SetMusic(79, 2); + } + + private void UpdateAwake() + { + if (!_animator.IsPlaying) + { + _aiComponent.ChangeState("shake"); + _hitRepelling = false; + } + } + + private void ShakeTick(double counter) + { + // 5 frames to go left/right + _animationComponent.SpriteOffset.X = MathF.Sin(MathF.PI * ((ShakeTime - (float)counter) / 1000 * (60 / 5f))); + _animationComponent.UpdateSprite(); + } + + private void ShakeEnd() + { + _animationComponent.SpriteOffset.X = 0; + + _aiComponent.ChangeState("walk"); + } + + private void InitWalk() + { + _jumpCount = 0; + } + + private void UpdateWalk() + { + if (_body.IsGrounded && _aiDamageState.CurrentLives > 0) + { + var distance = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + + if (_jumpCount >= 4) + { + _aiComponent.ChangeState("attackUp"); + } + else + { + if (distance != Vector2.Zero) + { + _jumpCount++; + distance.Normalize(); + + _body.Velocity.Z += 1.125f; + _body.VelocityTarget = distance * WalkSpeed; + + Game1.GameManager.PlaySoundEffect("D360-32-20"); + } + } + } + } + + private void InitAttackUp() + { + _body.IsGrounded = false; + _body.IgnoresZ = true; + _body.VelocityTarget = Vector2.Zero; + + Game1.GameManager.PlaySoundEffect("D360-36-24"); + + var distance = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (distance != Vector2.Zero) + { + distance.Normalize(); + _body.Velocity = new Vector3(distance * 1f, 0); + } + } + + private void AttackUpTick(double time) + { + EntityPosition.Z = MathF.Sin((float)((AttackUpTime - time) / AttackUpTime) * MathF.PI * 0.5f) * 38; + } + + private void AttackUpEnd() + { + _aiComponent.ChangeState("attackWait"); + } + + private void InitAttack() + { + // start falling down + _body.IgnoresZ = false; + _body.JumpStartHeight = 0; + } + + private void UpdateAttack() + { + if (_body.IsGrounded) + { + MapManager.ObjLink.GroundStun(1000); + Game1.GameManager.ShakeScreen(500, 1, 3, 2.5f, 5.5f); + Game1.GameManager.PlaySoundEffect("D360-11-0B"); + + _aiComponent.ChangeState("attackFinished"); + } + } + + private void InitAngry() + { + if (_animator.CurrentAnimation.Id == "angry") + return; + + Game1.GameManager.PlaySoundEffect("D378-41-29"); + SpawnStones(); + + _animator.Play("angry"); + } + + private void InitBroke() + { + if (_animator.CurrentAnimation.Id == "broken") + return; + + Game1.GameManager.PlaySoundEffect("D378-41-29"); + SpawnStones(); + + _animator.Play("broken"); + } + + private void SpawnStones() + { + var randomOffset0 = Game1.RandomNumber.Next(90, 110) / 100f; + var randomOffset1 = Game1.RandomNumber.Next(90, 110) / 100f; + var randomOffset2 = Game1.RandomNumber.Next(90, 110) / 100f; + var randomOffset3 = Game1.RandomNumber.Next(90, 110) / 100f; + + var stone0 = new ObjSmallStone(Map, (int)EntityPosition.X - 3, (int)EntityPosition.Y, (int)EntityPosition.Z + 26, new Vector3(-0.25f, 0.25f * 1, 0.85f) * randomOffset0, true); + var stone1 = new ObjSmallStone(Map, (int)EntityPosition.X - 4, (int)EntityPosition.Y + 8, (int)EntityPosition.Z + 26, new Vector3(-0.35f, 0.25f * 1, 0.85f) * randomOffset1, true); + var stone2 = new ObjSmallStone(Map, (int)EntityPosition.X + 3, (int)EntityPosition.Y, (int)EntityPosition.Z + 26, new Vector3(0.25f, 0.25f * 1, 0.85f) * randomOffset2, true); + var stone3 = new ObjSmallStone(Map, (int)EntityPosition.X + 4, (int)EntityPosition.Y + 8, (int)EntityPosition.Z + 26, new Vector3(0.35f, 0.25f * 1, 0.85f) * randomOffset3, true); + + Map.Objects.SpawnObject(stone0); + Map.Objects.SpawnObject(stone1); + Map.Objects.SpawnObject(stone2); + Map.Objects.SpawnObject(stone3); + } + + private void RemoveObject() + { + if (!string.IsNullOrEmpty(_saveKey)) + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + SpawnKey(); + + // stop boss music + Game1.GameManager.SetMusic(-1, 2); + + Map.Objects.DeleteObjects.Add(this); + } + + private void SpawnKey() + { + var objItem = new ObjItem(Map, 0, 0, "j", "dkey4Collected", "dkey4", null); + if (!objItem.IsDead) + { + objItem.EntityPosition.Set(new Vector2(EntityPosition.X, EntityPosition.Y - 2)); + Map.Objects.SpawnObject(objItem); + } + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (!_hitRepelling && type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X, direction.Y, _body.Velocity.Z); + + return true; + } + + public Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_aiDamageState.CurrentLives <= 0 || + _aiDamageState.IsInDamageState()) + return Values.HitCollision.None; + + // knock the boss back + if (!_hitRepelling && _knockbackSwitch.State) + { + _knockbackSwitch.Reset(); + _body.VelocityTarget = Vector2.Zero; + _body.Velocity.X = direction.X * 3.0f; + _body.Velocity.Y = direction.Y * 3.0f; + } + + if (_hitRepelling) + return Values.HitCollision.RepellingParticle; + + if ((damageType & HitType.PegasusBootsSword) != 0) + { + var hitCollision = _aiDamageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + + if (_aiDamageState.CurrentLives <= 0) + { + _damageField.IsActive = false; + } + + // boss should start jumping directly after getting hit + _jumpCount = 0; + + // change the animation to reflect the health of the boss + if (_aiDamageState.CurrentLives <= 2) + InitBroke(); + else if (_aiDamageState.CurrentLives <= 6) + InitAngry(); + + return hitCollision | Values.HitCollision.Repelling; + } + + return Values.HitCollision.None; + } + } +} diff --git a/InGame/GameObjects/MidBoss/MBossBallAndChain.cs b/InGame/GameObjects/MidBoss/MBossBallAndChain.cs new file mode 100644 index 0000000..0a1a06b --- /dev/null +++ b/InGame/GameObjects/MidBoss/MBossBallAndChain.cs @@ -0,0 +1,78 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + internal class MBossBallAndChain : GameObject + { + private readonly MBossBallAndChainSoldier _owner; + private readonly CSprite _sprite; + + private Rectangle _sourceRectangleLink = new Rectangle(179, 181, 4, 4); + + private bool _isActive; + + public MBossBallAndChain(Map.Map map, MBossBallAndChainSoldier owner) : base(map) + { + EntityPosition = new CPosition(owner.EntityPosition.X - 5, owner.EntityPosition.Y - 8 + 2, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _owner = owner; + _sprite = new CSprite(Resources.SprMidBoss, EntityPosition, new Rectangle(184, 175, 16, 16), new Vector2(-8, -16)); + + var damageCollider = new CBox(EntityPosition, -6, -8 - 6, 0, 12, 12, 8); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 4)); + AddComponent(HittableComponent.Index, new HittableComponent(damageCollider, OnHit)); + AddComponent(PushableComponent.Index, new PushableComponent(damageCollider, OnPush)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBottom, EntityPosition)); + } + + public void Activate() + { + _isActive = true; + } + + public void Deactivate() + { + _isActive = false; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (!_isActive) + return Values.HitCollision.None; + + _owner.BlockBall(); + return Values.HitCollision.RepellingParticle; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (!_isActive) + return false; + + if (type == PushableComponent.PushType.Impact) + _owner.BlockBall(); + + return true; + } + + private void Draw(SpriteBatch spriteBatch) + { + var handPosition = new Vector2(_owner.EntityPosition.X - 5, _owner.EntityPosition.Y - 15); + var direction = new Vector2(EntityPosition.X, EntityPosition.Y - 8) - handPosition; + // draw the chain + for (var i = 0; i < 3; i++) + { + var linkPosition = handPosition + direction * ((i + 1) / 4.0f) - new Vector2(2, 2); + spriteBatch.Draw(Resources.SprMidBoss, linkPosition, _sourceRectangleLink, Color.White); + } + + _sprite.Draw(spriteBatch); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/MidBoss/MBossBallAndChainSoldier.cs b/InGame/GameObjects/MidBoss/MBossBallAndChainSoldier.cs new file mode 100644 index 0000000..362710d --- /dev/null +++ b/InGame/GameObjects/MidBoss/MBossBallAndChainSoldier.cs @@ -0,0 +1,288 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + internal class MBossBallAndChainSoldier : GameObject + { + private readonly Animator _animator; + private readonly BodyComponent _body; + private readonly AnimationComponent _animatorComponent; + private readonly CSprite _sprite; + private readonly AiComponent _ai; + private readonly MBossBallAndChain _ballAndChain; + private readonly AiTriggerTimer _walkTimer; + private readonly AiDamageState _damageState; + private readonly Rectangle _fieldRectangle; + + private const string _leafSaveKey = "ow_goldLeafBalls"; + private string _strKey; + + private float _currentBallSpeed = 300; + + private const float BallDistance = 10; + private const float BallDistanceThrow = 56; + private float _ballState; + private float _throwDirection; + private int _ballCounter; + private bool _startThrowing; + private bool _isThrowing; + + private float _ballRadiant; + private float _distance; + private bool _wasBlocked; + + public MBossBallAndChainSoldier() : base("ballAndChain") { } + + public MBossBallAndChainSoldier(Map.Map map, int posX, int posY, string strKey) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _strKey = strKey; + + _fieldRectangle = map.GetField(posX, posY, 16); + _fieldRectangle.X += 16; + + // was already defeated? + if (!string.IsNullOrEmpty(_strKey) && Game1.GameManager.SaveManager.GetString(_strKey) == "1") + { + IsDead = true; + + // spawn the leaf if is was not already collected + var objLeaf = new ObjItem(Map, posX, posY, null, _leafSaveKey, "goldLeaf", null); + if (!objLeaf.IsDead) + Map.Objects.SpawnObject(objLeaf); + + return; + } + + _animator = AnimatorSaveLoad.LoadAnimator("MidBoss/ball and chain soldier"); + _animator.Play("swing1"); + + _sprite = new CSprite(EntityPosition); + _animatorComponent = new AnimationComponent(_animator, _sprite, new Vector2(-8, -16)); + + _body = new BodyComponent(EntityPosition, -7, -12, 14, 12, 8); + + _ai = new AiComponent(); + + var stateWalk = new AiState(UpdateWalk); + stateWalk.Trigger.Add(_walkTimer = new AiTriggerTimer(500)); + var stateSwing = new AiState(UpdateSwing); + var stateThrow = new AiState(UpdateThrow); + + _ai.States.Add("walk", stateWalk); + _ai.States.Add("swing", stateSwing); + _ai.States.Add("throw", stateThrow); + new AiFallState(_ai, _body, null, KillBoss, 500); + + _ai.Trigger.Add(new AiTriggerUpdate(UpdateBall)); + + _ai.ChangeState("walk"); + + var damageCollider = new CBox(EntityPosition, -8, -16, 0, 16, 16, 8); + AddComponent(AnimationComponent.Index, _animatorComponent); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 4)); + _damageState = new AiDamageState(this, _body, _ai, _sprite, 8, false) + { + OnDeath = OnDeath + }; + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, _damageState.OnHit)); + AddComponent(AiComponent.Index, _ai); + AddComponent(BodyComponent.Index, _body); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _sprite)); + + _ballAndChain = new MBossBallAndChain(map, this); + Map.Objects.SpawnObject(_ballAndChain); + } + + private void OnDeath(bool pieceOfPower) + { + KillBoss(); + _damageState.BaseOnDeath(pieceOfPower); + } + + private void KillBoss() + { + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + playerDirection *= 1.75f; + + // spawn the golden leaf jumping towards the player + var objLeaf = new ObjItem(Map, 0, 0, null, _leafSaveKey, "goldLeaf", null); + if (!objLeaf.IsDead) + { + objLeaf.EntityPosition.Set(new Vector3(EntityPosition.X, EntityPosition.Y, EntityPosition.Z)); + objLeaf.SetVelocity(new Vector3(playerDirection.X, playerDirection.Y, 1.0f)); + objLeaf.Collectable = false; + Map.Objects.SpawnObject(objLeaf); + } + + // save + if (!string.IsNullOrEmpty(_strKey)) + Game1.GameManager.SaveManager.SetString(_strKey, "1"); + + Map.Objects.DeleteObjects.Add(_ballAndChain); + } + + private void ToWalk() + { + _ai.ChangeState("walk"); + _startThrowing = false; + _isThrowing = false; + _ballAndChain.Deactivate(); + } + + private void UpdateWalk() + { + if (!_walkTimer.State) + return; + + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDirection.Length() < 48) + { + ToSwing(); + return; + } + + // do not walk towards the player if he is not in the field + if (!_fieldRectangle.Contains(MapManager.ObjLink.EntityPosition.Position)) + return; + + // walk towards the player + playerDirection.Normalize(); + _body.VelocityTarget = playerDirection / 4; + } + + private void ToSwing() + { + _ai.ChangeState("swing"); + _body.VelocityTarget = Vector2.Zero; + _ballCounter = 0; + } + + private void UpdateSwing() + { + + } + + private void ToThrow() + { + _ai.ChangeState("throw"); + _isThrowing = true; + _wasBlocked = false; + _ballAndChain.Activate(); + } + + private void UpdateThrow() + { + + } + + private void UpdateBall() + { + Vector2 ballOffset; + + if (_isThrowing) + { + if (_wasBlocked) + _ballState += (Game1.DeltaTime / 500.0f) * MathF.PI; + else + _ballState += (Game1.DeltaTime / 1000.0f) * MathF.PI; + + // finished animation? + if (_ballState > _throwDirection + MathF.PI) + { + ToWalk(); + } + } + else + { + var isSwinging = _ai.CurrentStateId == "swing"; + + var target = isSwinging ? 300.0f : 500.0f; + _currentBallSpeed = AnimationHelper.MoveToTarget(_currentBallSpeed, target, target * 0.1f * Game1.TimeMultiplier); + + Game1.DebugText += "\nball: " + (int)_currentBallSpeed; + + // 2 times per second or 4 if he is swinging fast + _ballState += Game1.DeltaTime / _currentBallSpeed * MathF.PI * 2; + + if (_startThrowing && _ballState >= _throwDirection) + { + _currentBallSpeed = 500.0f; + ToThrow(); + _ballState = _throwDirection + ((_ballState - _throwDirection) / 1000.0f) * MathF.PI; + } + else if (_ballState >= MathF.PI * 2) + { + _ballState -= MathF.PI * 2; + + if (isSwinging) + { + _ballCounter++; + if (_ballCounter >= 2) + { + _startThrowing = true; + var playerDirection = MapManager.ObjLink.BodyRectangle.Center - + new Vector2(EntityPosition.X - 5, EntityPosition.Y - 15); + var playerAngle = MathF.Atan2(playerDirection.Y, playerDirection.X) + MathF.PI * 5 / 2; + if (playerAngle >= MathF.PI * 2) + playerAngle -= MathF.PI * 2; + _throwDirection = playerAngle; + } + } + } + } + + _animator.Play("swing" + (_ballState < MathF.PI ? "0" : "1")); + + // calculate the ball offset + if (!_isThrowing) + { + ballOffset = new Vector2(-MathF.Cos(_ballState), -MathF.Sin(_ballState)) * BallDistance; + } + else + { + if (_wasBlocked) + { + if (BallDistance < _distance - 2.5f * Game1.TimeMultiplier) + _distance -= 2.5f * Game1.TimeMultiplier; + else + _distance = BallDistance; + + ballOffset = new Vector2(-MathF.Cos(_ballState), -MathF.Sin(_ballState)) * _distance; + } + else + { + var throwState = MathF.Sin(_ballState - _throwDirection); + _distance = MathHelper.Lerp(BallDistance, BallDistanceThrow, throwState); + + var tan = MathF.Tan((((_ballState - _throwDirection) / MathF.PI) * 2 - 1) * MathF.Atan(10)) / 10; + _ballRadiant = _throwDirection + (tan * 0.5f + 0.5f) * MathF.PI; + + ballOffset = new Vector2(-MathF.Cos(_ballRadiant), -MathF.Sin(_ballRadiant)) * _distance; + } + } + + _ballAndChain.EntityPosition.Set(new Vector2(EntityPosition.X - 5, EntityPosition.Y - 7) + ballOffset); + } + + public void BlockBall() + { + _wasBlocked = true; + _ballState = _ballRadiant; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/MidBoss/MBossBlaino.cs b/InGame/GameObjects/MidBoss/MBossBlaino.cs new file mode 100644 index 0000000..a508ed6 --- /dev/null +++ b/InGame/GameObjects/MidBoss/MBossBlaino.cs @@ -0,0 +1,583 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Dungeon; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using ProjectZ.InGame.Map; +using Microsoft.Xna.Framework.Graphics; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + internal class MBossBlaino : GameObject + { + private readonly DictAtlasEntry _gloveSprite; + + private readonly MBossBlainoGlove _objGlove; + + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _damageState; + private readonly CSprite _sprite; + private readonly Animator _animator; + private readonly AnimationComponent _animationComponent; + + private readonly string _saveKey; + + private const int HitTime1 = 400; + private const int HitTime2 = 700; + private const int HitTime3 = 125; + + private const int TimeSwing0 = 5000; + private const int TimeSwing1 = 400; + private const int TimeSwing2 = 300; + + private Vector2 _spawnPosition; + + private Vector2 _glovePosition; + private Vector2 _gloveStartPosition; + private Vector2 _gloveTargetPosition; + + private Vector2 _startPosition; + private Vector2 _targetPosition; + private Vector2 _lastPosition; + + private Vector2 _swingOrigin = new Vector2(0, -10); + + private float _swingStartRotation; + private float _swingStartDistance; + private float _lastSwingRotation; + + private int _direction = -1; + private int _boxCount; + private int _jumpFollowDelay; + + private bool _drawGlove; + + public MBossBlaino() : base("blaino") { } + + public MBossBlaino(Map.Map map, int posX, int posY, string saveKey, string resetDoor) : base(map) + { + if (!string.IsNullOrEmpty(saveKey) && + Game1.GameManager.SaveManager.GetString(saveKey) == "1") + { + IsDead = true; + return; + } + + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-16, -32, 32, 32); + + _saveKey = saveKey; + + _spawnPosition = EntityPosition.Position; + + _gloveSprite = Resources.GetSprite("blaino glove"); + + _animator = AnimatorSaveLoad.LoadAnimator("MidBoss/blaino"); + _animator.Play("jump"); + + _sprite = new CSprite(EntityPosition); + _animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -7, -12, 14, 12, 8) + { + SimpleMovement = false, + Drag = 0.65f, + DragAir = 0.75f, + Gravity = -0.15f, + MoveCollision = OnMoveCollision, + FieldRectangle = map.GetField(posX, posY, 16), + }; + + var stateWaiting = new AiState(UpdateWaiting); + var stateJumping = new AiState(UpdateJumping) { Init = InitJump }; + var stateBox = new AiState(UpdateBox) { Init = InitBox }; + + var stateHit0 = new AiState(UpdateHit0) { Init = InitHit }; + var stateHit1 = new AiState(); + stateHit1.Trigger.Add(new AiTriggerCountdown(HitTime1, TickHit1, () => TickHit1(0))); + var stateHit2 = new AiState(); + stateHit2.Trigger.Add(new AiTriggerCountdown(HitTime2, TickHit2, () => TickHit2(0))); + var stateHit3 = new AiState() { Init = InitHit3 }; + stateHit3.Trigger.Add(new AiTriggerCountdown(HitTime3, TickHit3, () => TickHit3(0))); + var stateHitBlocked = new AiState(); + stateHitBlocked.Trigger.Add(new AiTriggerCountdown(250, null, () => _aiComponent.ChangeState("hit3"))); + + var stateSwing0 = new AiState() { Init = InitSwing0 }; + stateSwing0.Trigger.Add(new AiTriggerCountdown(TimeSwing0, TickSwing0, () => TickSwing0(0))); + var stateSwing1 = new AiState(); + stateSwing1.Trigger.Add(new AiTriggerCountdown(TimeSwing1, null, () => _aiComponent.ChangeState("swing2"))); + var stateSwing2 = new AiState() { Init = InitSwing2 }; + stateSwing2.Trigger.Add(new AiTriggerCountdown(TimeSwing2, TickSwing2, () => TickSwing2(0))); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("waiting", stateWaiting); + _aiComponent.States.Add("jumping", stateJumping); + _aiComponent.States.Add("box", stateBox); + _aiComponent.States.Add("hit0", stateHit0); + _aiComponent.States.Add("hit1", stateHit1); + _aiComponent.States.Add("hit2", stateHit2); + _aiComponent.States.Add("hit3", stateHit3); + _aiComponent.States.Add("hitBlocked", stateHitBlocked); + _aiComponent.States.Add("swing0", stateSwing0); + _aiComponent.States.Add("swing1", stateSwing1); + _aiComponent.States.Add("swing2", stateSwing2); + _damageState = new AiDamageState(this, _body, _aiComponent, _sprite, 8, true, false); + _damageState.AddBossDamageState(OnDeath); + _damageState.ExplosionOffsetY = 8; + _aiComponent.ChangeState("waiting"); + + var hittableBox = new CBox(EntityPosition, -6, -16, 0, 12, 16, 8, true); + var damageBox = new CBox(EntityPosition, -8, -14, 0, 16, 14, 8, true); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(PushableComponent.Index, new PushableComponent(damageBox, OnPush)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, _animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, Draw, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(_sprite)); + + _objGlove = new MBossBlainoGlove(map, this, EntityPosition.Position, resetDoor); + Map.Objects.SpawnObject(_objGlove); + } + + private void UpdateWaiting() + { + // jump around the start position + if (_body.IsGrounded) + { + var targetDirection = _spawnPosition - EntityPosition.Position; + if (targetDirection == Vector2.Zero) + targetDirection = new Vector2(-1, -0.25f); + targetDirection.Normalize(); + + _body.VelocityTarget = targetDirection * 0.25f; + _body.Velocity.Z = 1; + } + + // player entered the room? + if (_body.FieldRectangle.Contains(MapManager.ObjLink.BodyRectangle)) + { + // start boss music + Game1.GameManager.SetMusic(79, 2); + + _aiComponent.ChangeState("jumping"); + } + } + + private void InitJump() + { + _animator.Play("jump"); + } + + private void UpdateJumping() + { + GloveAnimationUpdate(); + + // landed after a jump? + if (!_body.IsGrounded) + return; + + var playerPosition = MapManager.ObjLink.EntityPosition.Position; + + // jump infront of the player + var verticalDistance = Math.Abs(EntityPosition.Y - MapManager.ObjLink.EntityPosition.Y) / 2; + var sinDist = MathF.Sin((float)Game1.TotalGameTime / 500); + var distanceToPlayer = 26 + sinDist * 2 + verticalDistance; + var targetPosition = new Vector2(EntityPosition.X + _direction * distanceToPlayer, EntityPosition.Y); + var targetDirection = playerPosition - targetPosition; + var distance = targetDirection.Length(); + + if (MapManager.ObjLink.IsStunned()) + { + if (distance < 4) + { + _aiComponent.ChangeState("swing0"); + return; + } + } + else if (distance < 32) + { + // only hit when we are clost to the player + if (Game1.RandomNumber.Next(0, 3) == 0 && sinDist <= 0) + { + if (Game1.RandomNumber.Next(0, 4) < 3) + { + ToBox(true); + return; + } + else + { + _aiComponent.ChangeState("hit0"); + return; + } + } + } + + if (_jumpFollowDelay <= 0) + { + var speedMultiplier = MathHelper.Clamp(distance / 12, 0.25f, 1.0f); + if (targetDirection != Vector2.Zero) + targetDirection.Normalize(); + _body.VelocityTarget = targetDirection * speedMultiplier; + } + else + { + _jumpFollowDelay--; + } + + // jump + _body.Velocity.Z = 1; + + var playerDirection = EntityPosition.Position - playerPosition; + if (Math.Abs(playerDirection.X) > 8) + { + if (playerDirection.X < 0) + _direction = 1; + else + _direction = -1; + } + + _animationComponent.MirroredH = _direction == 1; + } + + private void BodyMove(float percentage) + { + // adjust the start/target positions if the body has moved + if (_lastPosition != Vector2.Zero) + { + var positionOffset = EntityPosition.Position - _lastPosition; + _startPosition += positionOffset; + _targetPosition += positionOffset; + } + + var targetPosition = Vector2.Lerp(_startPosition, _targetPosition, percentage); + + // body movement does not work well because the steps are too big in lower framerates + targetPosition.X = MathHelper.Clamp(targetPosition.X, _body.FieldRectangle.X + 7, _body.FieldRectangle.Right - 7); + EntityPosition.Set(targetPosition); + + _lastPosition = targetPosition; + } + + private void SetGlovePosition(Vector2 newPosition) + { + _glovePosition = newPosition; + _objGlove.EntityPosition.Set(new Vector2( + EntityPosition.X + _glovePosition.X * -_direction - (_direction == 1 ? 11 : 0), + EntityPosition.Y - EntityPosition.Z + _glovePosition.Y)); + } + + private void InitSwing0() + { + _body.VelocityTarget = Vector2.Zero; + _startPosition = EntityPosition.Position; + _targetPosition = _startPosition + new Vector2(-_direction * 23, 0); + _lastPosition = Vector2.Zero; + + _objGlove.IsActive = true; + _objGlove.SetHitDirection(_direction); + _drawGlove = true; + + _animator.Play("hit1"); + } + + private void TickSwing0(double counter) + { + var percentage = (float)(TimeSwing0 - counter) / 75 + MathF.PI / 2 - MathF.Asin(3 / 4f); + + var finishedSwing = false; + if ((_lastSwingRotation % MathF.PI) > (percentage % MathF.PI) && percentage / MathF.PI >= 5) + { + percentage = MathF.PI; + finishedSwing = true; + } + + // moving back + var movePercentage = MathHelper.Clamp((float)((TimeSwing0 - counter) / 750), 0, 1); + BodyMove(MathF.Sin(movePercentage * MathF.PI / 2)); + + // update the glove position + var offset = new Vector2(2 - MathF.Cos(percentage) * 4 + MathF.Sin(percentage) * 2, -6 + MathF.Sin(percentage) * 8); + SetGlovePosition(new Vector2(5, -14) + offset); + + if (counter == 0 || finishedSwing) + _aiComponent.ChangeState("swing1"); + + _lastSwingRotation = percentage; + } + + private void InitSwing2() + { + _objGlove.SetKnockoutMode(true); + + _startPosition = EntityPosition.Position; + _targetPosition = _startPosition + new Vector2(_direction * 36, 0); + _lastPosition = Vector2.Zero; + + var originDirection = new Vector2(_glovePosition.X + 5.5f, _glovePosition.Y + 5.5f) - _swingOrigin; + _swingStartDistance = originDirection.Length(); + _swingStartRotation = MathF.Atan2(originDirection.Y, originDirection.X); + } + + private void TickSwing2(double counter) + { + var percentage = MathHelper.Clamp((float)((TimeSwing2 - counter) / (TimeSwing2 - 75)), 0, 1); + var newRotation = MathHelper.Lerp(_swingStartRotation, _swingStartRotation + 3.75f, percentage); + + // moving forward + BodyMove(MathF.Sin(percentage * MathF.PI / 2)); + + SetGlovePosition(new Vector2(_swingOrigin.X - 5.5f, _swingOrigin.Y - 5.5f) + new Vector2(MathF.Cos(newRotation), MathF.Sin(newRotation)) * _swingStartDistance); + + // change animation frame + if (newRotation > _swingStartRotation + 1.85f) + _animator.Play("hit2"); + + if (counter == 0) + { + _drawGlove = false; + _objGlove.IsActive = false; + _objGlove.SetKnockoutMode(false); + _aiComponent.ChangeState("jumping"); + } + } + + private void InitHit() + { + _body.VelocityTarget = Vector2.Zero; + _animator.Play("hit0"); + } + + private void UpdateHit0() + { + if (!_animator.IsPlaying) + { + _startPosition = EntityPosition.Position; + _targetPosition = _startPosition + new Vector2(-_direction * 6, 0); + _lastPosition = Vector2.Zero; + + _objGlove.IsActive = true; + _objGlove.SetHitDirection(_direction); + _drawGlove = true; + + _animator.Play("hit1"); + _aiComponent.ChangeState("hit1"); + } + } + + private void TickHit1(double time) + { + // move 6px back + var percentage = 1 - (float)(time / HitTime1); + + BodyMove(percentage); + + // update the glove position + SetGlovePosition(new Vector2(5, -14)); + + if (time == 0) + { + _startPosition = EntityPosition.Position; + _targetPosition = _startPosition + new Vector2(_direction * 40, 0); + _lastPosition = Vector2.Zero; + + _objGlove.SetStunMode(true); + + TickHit2(HitTime2); + _animator.Play("hit2"); + _aiComponent.ChangeState("hit2"); + } + } + + private void TickHit2(double time) + { + var percentageGlove = MathHelper.Clamp((float)(HitTime2 - time - 25) / 125, 0, 1); + var sPercentageGlove = 1 - MathF.Cos(percentageGlove * MathF.PI / 2); + + var percentage = MathHelper.Clamp((float)(HitTime2 - time - 75) / 125, 0, 1); + var sPercentage = 1 - MathF.Cos(percentage * MathF.PI / 2); + + // move forward + BodyMove(sPercentage); + + // update the glove position + SetGlovePosition(Vector2.Lerp(new Vector2(-15, -11), new Vector2(-15 - 16, -11), sPercentageGlove)); + + if (time == 0) + _aiComponent.ChangeState("hit3"); + } + + private void InitHit3() + { + _gloveStartPosition = _glovePosition; + _gloveTargetPosition = new Vector2(-15, -11); + + _objGlove.SetStunMode(false); + } + + private void TickHit3(double time) + { + var percentage = 1 - (float)(time / HitTime3); + + // update the glove position + SetGlovePosition(Vector2.Lerp(_gloveStartPosition, _gloveTargetPosition, percentage)); + + if (time == 0) + { + _objGlove.IsActive = false; + _drawGlove = false; + _aiComponent.ChangeState("jumping"); + } + } + + private void ToBox(bool isShort) + { + _body.VelocityTarget = Vector2.Zero; + + _aiComponent.ChangeState("box"); + + _boxCount = Game1.RandomNumber.Next(1, 7) - 3; + + if (isShort) + _animator.Play("box_short"); + else + _animator.Play("box"); + } + + private void InitBox() + { + Game1.GameManager.PlaySoundEffect("D378-10-0A"); + } + + private void UpdateBox() + { + GloveAnimationUpdate(); + + if (!_animator.IsPlaying) + { + // box again? + if (_boxCount > 0) + { + Game1.GameManager.PlaySoundEffect("D378-10-0A"); + _animator.Play("prebox"); + } + else + _aiComponent.ChangeState("jumping"); + + _boxCount--; + } + } + + private void GloveAnimationUpdate() + { + if (_animator.CollisionRectangle != Rectangle.Empty) + { + _objGlove.IsActive = true; + _objGlove.EntityPosition.Set(EntityPosition.Position + + new Vector2(_animator.CollisionRectangle.X * -_direction - (_direction == 1 ? 11 : 0), _animator.CollisionRectangle.Y)); + } + else + { + _objGlove.IsActive = false; + } + } + + private void Draw(SpriteBatch spriteBatch) + { + _sprite.Draw(spriteBatch); + + // draw the glove + if (_drawGlove) + { + DrawHelper.DrawNormalized(spriteBatch, _gloveSprite, + new Vector2(EntityPosition.X + _glovePosition.X * -_direction - (_direction == 1 ? 11 : 0), EntityPosition.Y - EntityPosition.Z + _glovePosition.Y), Color.White); + } + } + + private void OnMoveCollision(Values.BodyCollision collision) + { + // make sure to not continuesly jump into the wall + if ((collision & Values.BodyCollision.Horizontal) != 0 && + _aiComponent.CurrentStateId == "jumping") + { + _direction = -_direction; + } + } + + public bool OnPush(Vector2 direction, PushableComponent.PushType pushType) + { + if (pushType == PushableComponent.PushType.Impact) + { + _jumpFollowDelay = 2; + + var mult = 2.25f; + _body.Velocity = new Vector3(direction.X * mult, direction.Y * mult, _body.Velocity.Z); + _body.VelocityTarget = direction * 0.125f; + } + + return true; + } + + public void GlovePush(Vector2 direction) + { + _objGlove.IsActive = false; + _aiComponent.ChangeState("hitBlocked"); + + _body.Velocity = new Vector3(direction.X, direction.Y, _body.Velocity.Z); + } + + public Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_damageState.IsInDamageState() || + _aiComponent.CurrentStateId == "damage" || _aiComponent.CurrentStateId == "dying") + return Values.HitCollision.None; + + if (damageType == HitType.Bomb || damageType == HitType.Bow || damageType == HitType.MagicRod) + return Values.HitCollision.Enemy; + + var hitDir = AnimationHelper.GetDirection(direction); + if ((hitDir == 2 && _direction == -1) || (hitDir == 0 && _direction == 1)) + return Values.HitCollision.RepellingParticle; + + if (damageType == HitType.Hookshot) + damage = 1; + + // different drag than needed for the jumps + _body.DragAir = 0.75f; + + _damageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + + if (_damageState.CurrentLives <= 0) + { + _animator.IsPlaying = false; + _body.VelocityTarget = Vector2.Zero; + Map.Objects.DeleteObjects.Add(_objGlove); + } + + return Values.HitCollision.Enemy; + } + + private void OnDeath() + { + if (!string.IsNullOrEmpty(_saveKey)) + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + // stop boss music + Game1.GameManager.SetMusic(-1, 2); + + Game1.GameManager.PlaySoundEffect("D360-27-1B"); + Map.Objects.SpawnObject(new ObjDungeonFairy(Map, (int)EntityPosition.X, (int)EntityPosition.Y, 8)); + + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/MidBoss/MBossBlainoGlove.cs b/InGame/GameObjects/MidBoss/MBossBlainoGlove.cs new file mode 100644 index 0000000..177a394 --- /dev/null +++ b/InGame/GameObjects/MidBoss/MBossBlainoGlove.cs @@ -0,0 +1,102 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; +using static ProjectZ.InGame.GameObjects.ObjLink; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + internal class MBossBlainoGlove : GameObject + { + private readonly MBossBlaino _blaino; + private readonly DamageFieldComponent _damageFieldComponent; + private readonly string _resetDoor; + + private int _hitDirection; + private bool _knockoutMode; + private bool _stunMode; + + public MBossBlainoGlove(Map.Map map, MBossBlaino blaino, Vector2 position, string resetDoor) : base(map) + { + EntityPosition = new CPosition(position.X, position.Y, 0); + EntitySize = new Rectangle(0, 0, 11, 11); + + var damageCollider = new CBox(EntityPosition, 0, 0, 0, 11, 11, 8); + AddComponent(DamageFieldComponent.Index, _damageFieldComponent = new DamageFieldComponent(damageCollider, HitType.Enemy, 4) { OnDamage = DamagePlayer, PushMultiplier = 2.25f }); + AddComponent(HittableComponent.Index, new HittableComponent(damageCollider, OnHit)); + AddComponent(PushableComponent.Index, new PushableComponent(damageCollider, OnPush)); + + _blaino = blaino; + _resetDoor = resetDoor; + } + + public void SetHitDirection(int direction) + { + _hitDirection = direction; + } + + public void SetKnockoutMode(bool knockoutMode) + { + _knockoutMode = knockoutMode; + } + + public void SetStunMode(bool stunMode) + { + _stunMode = stunMode; + } + + private bool DamagePlayer() + { + // is the player blocking? + if (_stunMode && + MapManager.ObjLink.CurrentState == State.Blocking && + ((_hitDirection == -1 && MapManager.ObjLink.Direction != 0) || + (_hitDirection == 1 && MapManager.ObjLink.Direction != 2))) + { + _blaino.GlovePush(new Vector2(-_hitDirection * 3.5f, 0)); + + // push the player back + MapManager.ObjLink._body.Velocity += new Vector3(_hitDirection * 3.5f, 0, 0); + + return false; + } + + var damagedPlayer = _damageFieldComponent.DamagePlayer(); + + if (_knockoutMode) + { + _knockoutMode = false; + Game1.GameManager.PlaySoundEffect("D360-11-0B"); + + MapManager.ObjLink.Knockout(new Vector2(_hitDirection * 0.75f, -1), _resetDoor); + return true; + } + + if (_stunMode) + MapManager.ObjLink.Stun(3500, true); + + return damagedPlayer; + } + + public void SetPosition(Vector2 newPosition) + { + EntityPosition.Set(newPosition); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + return Values.HitCollision.RepellingParticle; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (_stunMode) + return false; + + _blaino.OnPush(direction, type); + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/MidBoss/MBossBone.cs b/InGame/GameObjects/MidBoss/MBossBone.cs new file mode 100644 index 0000000..ea773ba --- /dev/null +++ b/InGame/GameObjects/MidBoss/MBossBone.cs @@ -0,0 +1,133 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + internal class MBossBone : GameObject + { + private readonly Animator _animator; + private readonly BodyComponent _body; + + private const float MoveSpeed = 1f; + + private bool _hasCollided; + private bool _isDying; + private float _deathCount; + private int _deathState; + + public MBossBone(Map.Map map, int posX, int posY, int offset) : base(map) + { + var fieldRectangle = map.GetField(posX, posY, 16); + + EntityPosition = new CPosition(fieldRectangle.X + offset, fieldRectangle.Y, 0); + EntitySize = new Rectangle(0, 0, 16, 96); + + _animator = AnimatorSaveLoad.LoadAnimator("MidBoss/mbossOne"); + _animator.Play("idle"); + + _body = new BodyComponent(EntityPosition, 2, 0, 12, 96, 8) + { + MoveCollision = OnCollision, + AbsorbPercentage = 0.75f, + Drag = 1.0f, + DragAir = 1.0f, + }; + + var hittableCollider = new CBox(EntityPosition, 0, 0, 0, 16, 96, 8); + var damageCollider = new CBox(EntityPosition, 2, 0, 0, 12, 96, 4); + AddComponent(HittableComponent.Index, new HittableComponent(hittableCollider, OnHit)); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 2)); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush) { RepelMultiplier = 1.5f }); + AddComponent(BodyComponent.Index, _body); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBottom, EntityPosition)); + } + + public void Push(int direction) + { + _hasCollided = false; + _body.Velocity.X = direction == 0 ? -MoveSpeed : MoveSpeed; + _animator.Play("move"); + } + + public void Delete() + { + _isDying = true; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if ((damageType & HitType.Sword) == 0) + return Values.HitCollision.None; + + return Values.HitCollision.RepellingParticle; + } + + private void Update() + { + _animator.Update(); + + if (_isDying) + { + _deathCount += Game1.DeltaTime; + if (_deathCount > _deathState * 75) + { + _deathState++; + Game1.GameManager.PlaySoundEffect("D378-04-04"); + + // spawn explosion effect + Map.Objects.SpawnObject(new ObjAnimator(Map, (int)EntityPosition.X, (int)EntityPosition.Y + (6 - _deathState) * 16, Values.LayerBottom, "Particles/spawn", "run", true)); + + if (_deathState >= 6) + Map.Objects.DeleteObjects.Add(this); + } + } + + // move sound effect + if (Math.Abs(_body.Velocity.X) > 0.05f && !_hasCollided) + Game1.GameManager.PlaySoundEffect("D370-26-1A", false); + + // collided with the wall? => slow down and stop + if (_hasCollided) + { + _body.Velocity.X *= (float)Math.Pow(0.95f, Game1.TimeMultiplier); + + // stop moving + if (Math.Abs(_body.Velocity.X) < 0.15f * Game1.TimeMultiplier) + { + _body.Velocity.X = 0; + _animator.Play("idle"); + } + } + } + + private void Draw(SpriteBatch spriteBatch) + { + // draw the bar + for (var i = 0; i < 6; i++) + if (i < 6 - _deathState) + _animator.Draw(spriteBatch, new Vector2(EntityPosition.X, EntityPosition.Y + 16 * i), Color.White); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + return true; + } + + private void OnCollision(Values.BodyCollision direction) + { + Game1.GameManager.PlaySoundEffect("D360-11-0B"); + Game1.GameManager.ShakeScreen(800, 4, 1, 5, 5); + + _body.Velocity.X = -_body.Velocity.X; + _hasCollided = true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/MidBoss/MBossBuzz.cs b/InGame/GameObjects/MidBoss/MBossBuzz.cs new file mode 100644 index 0000000..2843746 --- /dev/null +++ b/InGame/GameObjects/MidBoss/MBossBuzz.cs @@ -0,0 +1,69 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + class MBossBuzz : GameObject + { + private readonly CSprite _sprite; + private float _liveCounter = 2000; + + public MBossBuzz(Map.Map map, Vector2 position, Vector2 velocity, string spriteId, float spriteRotation) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(position.X, position.Y, 0); + EntitySize = new Rectangle(-8, -8, 16, 16); + + _sprite = new CSprite(spriteId, EntityPosition, Vector2.Zero); + + var objWidth = _sprite.SourceRectangle.Width * _sprite.Scale; + var objHeight = _sprite.SourceRectangle.Height * _sprite.Scale; + + _sprite.Center = new Vector2(objWidth / 2, objHeight / 2); + _sprite.Rotation = spriteRotation; + + var body = new BodyComponent(EntityPosition, -5, -5, 10, 10, 8) + { + IgnoresZ = true, + IgnoreHoles = true, + CollisionTypes = Values.CollisionTypes.None + }; + + body.VelocityTarget = velocity; + + var damageCollider = new CBox(EntityPosition, -5, -5, 10, 10, 8); + var hittableBox = new CBox(EntityPosition, -5, -5, 10, 10, 8); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 2)); + AddComponent(BodyComponent.Index, body); + //AddComponent(PushableComponent.Index, new PushableComponent(body.BodyBox, OnPush)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerTop)); + } + + private void Update() + { + // blink 8 frame interval + _sprite.SpriteShader = (Game1.TotalGameTime % (8 / 60f * 1000) < 4 / 60f * 1000) ? Resources.DamageSpriteShader0 : null; + + // fade out/ delete object + _liveCounter -= Game1.DeltaTime; + if (_liveCounter < 100) + _sprite.Color = Color.White * (_liveCounter / 100); + if (_liveCounter <= 0) + Map.Objects.DeleteObjects.Add(this); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + + + return Values.HitCollision.RepellingParticle; + } + } +} diff --git a/InGame/GameObjects/MidBoss/MBossCueBall.cs b/InGame/GameObjects/MidBoss/MBossCueBall.cs new file mode 100644 index 0000000..0c0e192 --- /dev/null +++ b/InGame/GameObjects/MidBoss/MBossCueBall.cs @@ -0,0 +1,274 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Dungeon; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + class MBossCueBall : GameObject + { + private readonly CSprite _sprite; + private readonly Animator _animation; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _aiDamageState; + + private const float MovementSpeed = 1.25f; + + private string _saveKey; + private string _enterKey; + + private int _spinStart; + private float _spinCounter; + private float _spinTime; + private const float SpinStepTime = 66.66f; + + private int Lives = 8; + private int _count; + private int _moveClockwise = 1; + private int _moveDirection; + private int _lastFrameIndex; + + private bool _entered; + + public MBossCueBall() : base("cue ball") { } + + public MBossCueBall(Map.Map map, int posX, int posY, string saveKey, string enterKey) : base(map) + { + EntityPosition = new CPosition(posX + 16, posY + 16, 0); + EntitySize = new Rectangle(-16, -16, 32, 32); + + _saveKey = saveKey; + _enterKey = enterKey; + + if (!string.IsNullOrEmpty(_saveKey) && + Game1.GameManager.SaveManager.GetString(_saveKey) == "1") + { + IsDead = true; + return; + } + + _animation = AnimatorSaveLoad.LoadAnimator("MidBoss/cue ball"); + _animation.Play("move_2"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animation, _sprite, new Vector2(-16, -16)); + + _body = new BodyComponent(EntityPosition, -16, -16, 32, 32, 8) + { + IgnoreHoles = true, + IgnoresZ = true, + Drag = 0.9f, + MoveCollision = OnCollision, + }; + + var stateWaiting = new AiState(); + stateWaiting.Trigger.Add(new AiTriggerCountdown(400, null, ToMoving)); + var stateMoving = new AiState(UpdateMoving); + var stateSpinning = new AiState(UpdateSpinning); + var stateDead = new AiState() { Init = InitDeath }; + + _aiComponent = new AiComponent(); + + _aiComponent.States.Add("waiting", stateWaiting); + _aiComponent.States.Add("moving", stateMoving); + _aiComponent.States.Add("spinning", stateSpinning); + _aiComponent.States.Add("dead", stateDead); + _aiDamageState = new AiDamageState(this, _body, _aiComponent, _sprite, Lives, false, false) + { HitMultiplierX = 0, HitMultiplierY = 0, OnDeath = OnDeath, ExplosionOffsetY = 16, BossHitSound = true }; + _aiDamageState.AddBossDamageState(OnDeathEnd); + + ToMoving(); + + var damageCollider = new CBox(EntityPosition, -14, -14, 0, 28, 28, 2); + if (!string.IsNullOrEmpty(enterKey)) + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 4)); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush) { CooldownTime = 50 }); + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, OnHit)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerBottom)); + } + + private void OnKeyChange() + { + if (!_entered) + { + var strEnterKey = Game1.GameManager.SaveManager.GetString(_enterKey, "0"); + if (strEnterKey == "1") + { + _entered = true; + Game1.GameManager.SetMusic(79, 2); + } + } + } + + private void ToMoving() + { + _aiComponent.ChangeState("moving"); + + _moveDirection = (_moveDirection + _moveClockwise) % 4; + if (_moveDirection < 0) + _moveDirection += 4; + + _animation.Play("move_" + _moveDirection); + + _body.VelocityTarget = AnimationHelper.DirectionOffset[_moveDirection] * MovementSpeed; + _lastFrameIndex = 1; + } + + private void UpdateMoving() + { + // spawn particle? + if (_lastFrameIndex == 1 && _lastFrameIndex != _animation.CurrentFrameIndex) + { + var posX = EntityPosition.X + AnimationHelper.DirectionOffset[_moveDirection].X * 22; + var posY = EntityPosition.Y + AnimationHelper.DirectionOffset[_moveDirection].Y * 22; + + // spawn splash effect + Map.Objects.SpawnObject(new ObjAnimator(Map, + (int)posX, (int)posY, Values.LayerPlayer, "Particles/big_water_splash", "run_" + _moveDirection, true)); + + if (_entered) + Game1.GameManager.PlaySoundEffect("D378-47-2F"); + } + + _lastFrameIndex = _animation.CurrentFrameIndex; + } + + private void ToWaiting() + { + _aiComponent.ChangeState("waiting"); + + _animation.Pause(); + _body.VelocityTarget = Vector2.Zero; + } + + private void ToSpinning() + { + _aiComponent.ChangeState("spinning"); + + // rotate 5 or 5.5 times + _spinStart = _moveDirection; + _spinCounter = 0; + _spinTime = SpinStepTime * 5.75f * 4; + _body.VelocityTarget = Vector2.Zero; + } + + private void UpdateSpinning() + { + _spinCounter += Game1.DeltaTime; + if (_spinCounter >= _spinTime) + { + _moveDirection += _moveClockwise; + _moveClockwise = -_moveClockwise; + ToMoving(); + return; + } + + var counterDir = (int)(_spinCounter / SpinStepTime); + var spinDirection = (_spinStart + _moveClockwise * counterDir) % 4; + if (spinDirection < 0) + spinDirection += 4; + + if (spinDirection != _moveDirection) + _count++; + + // spawn splash effect + if (spinDirection != _moveDirection && _count % 3 == 0) + { + Game1.GameManager.PlaySoundEffect("D378-47-2F"); + + var offset = 22; + if (spinDirection == 0) + Map.Objects.SpawnObject(new ObjAnimator(Map, + (int)EntityPosition.X - offset, (int)EntityPosition.Y, Values.LayerPlayer, "Particles/big_water_splash", "run_0", true)); + else if (spinDirection == 1) + Map.Objects.SpawnObject(new ObjAnimator(Map, + (int)EntityPosition.X, (int)EntityPosition.Y - offset, Values.LayerPlayer, "Particles/big_water_splash", "run_1", true)); + else if (spinDirection == 2) + Map.Objects.SpawnObject(new ObjAnimator(Map, + (int)EntityPosition.X + offset, (int)EntityPosition.Y, Values.LayerPlayer, "Particles/big_water_splash", "run_2", true)); + else if (spinDirection == 3) + Map.Objects.SpawnObject(new ObjAnimator(Map, + (int)EntityPosition.X, (int)EntityPosition.Y + offset, Values.LayerPlayer, "Particles/big_water_splash", "run_3", true)); + } + + _moveDirection = spinDirection; + _animation.Play("move_" + _moveDirection); + } + + private void InitDeath() + { + // stop moving + _body.Velocity.X = _body.VelocityTarget.X; + _body.Velocity.Y = _body.VelocityTarget.Y; + _body.VelocityTarget = Vector2.Zero; + } + + private void OnDeath(bool pieceOfPower) + { + if (_aiComponent.CurrentStateId != "death") + _aiComponent.ChangeState("death"); + } + + private void OnDeathEnd() + { + if (!string.IsNullOrEmpty(_saveKey)) + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + // stop boss music + Game1.GameManager.SetMusic(-1, 2); + + Game1.GameManager.PlaySoundEffect("D378-26-1A"); + + Game1.GameManager.PlaySoundEffect("D360-27-1B"); + Map.Objects.SpawnObject(new ObjDungeonFairy(Map, (int)EntityPosition.X, (int)EntityPosition.Y, 8)); + + Map.Objects.DeleteObjects.Add(this); + } + + private void OnCollision(Values.BodyCollision collision) + { + if (_aiComponent.CurrentStateId == "moving") + ToWaiting(); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + return true; + } + + public Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (!_entered || _aiDamageState.IsInDamageState() || _aiDamageState.CurrentLives <= 0) + return Values.HitCollision.None; + + if (_aiComponent.CurrentStateId == "spinning") + return Values.HitCollision.RepellingParticle; + + var dir = AnimationHelper.GetDirection(direction); + dir = (dir + 2) % 4; + if (dir == _moveDirection) + return Values.HitCollision.RepellingParticle; + + _aiDamageState.OnHit(gameObject, direction, damageType, damage, false); + + // star spinning + if (0 < _aiDamageState.CurrentLives) + ToSpinning(); + else + _aiComponent.ChangeState("dead"); + + return Values.HitCollision.Enemy; + } + } +} diff --git a/InGame/GameObjects/MidBoss/MBossDesertLanmola.cs b/InGame/GameObjects/MidBoss/MBossDesertLanmola.cs new file mode 100644 index 0000000..8735723 --- /dev/null +++ b/InGame/GameObjects/MidBoss/MBossDesertLanmola.cs @@ -0,0 +1,356 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + internal class MBossDesertLanmola : GameObject + { + private readonly AiComponent _aiComponent; + private readonly AiTriggerCountdown _damageTrigger; + private readonly Animator _animator; + private readonly CSprite _sprite; + private readonly CPosition _position; + + private MBossDesertLanmolaHead _head; + private MBossDesertLanmolaBody[] _bodyParts = new MBossDesertLanmolaBody[6]; + + private readonly AiTriggerCountdown _jumpCountdown; + private readonly RectangleF _field; + private readonly Rectangle _fieldSmall; + + private Vector2 _jumpStartPosition; + private Vector2 _jumpPosition; + private string _triggerKey; + private string _saveKey; + private int _jumpTime; + + private int _lives = 8; + + private bool _jumpLandSound; + private bool _playerLeft = true; + + private const int CooldownTime = 350; + private const int DespawnTime = 5500; + + public MBossDesertLanmola() : base("desert lanmola") { } + + public MBossDesertLanmola(Map.Map map, int posX, int posY, string triggerKey, string saveKey) : base(map) + { + _position = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _triggerKey = triggerKey; + _saveKey = saveKey; + _field = map.GetField(posX, posY, -16); + _fieldSmall = map.GetField(posX, posY, 16); + + if (!string.IsNullOrEmpty(_saveKey) && + Game1.GameManager.SaveManager.GetString(_saveKey) == "1") + { + IsDead = true; + return; + } + + var stateIdle = new AiState(); + var stateWaiting = new AiState(); + stateWaiting.Trigger.Add(new AiTriggerCountdown(500, null, ToSpawning)); + var stateSpawning = new AiState(); + stateSpawning.Trigger.Add(new AiTriggerCountdown(500, null, ToJumping)); + var stateJumping = new AiState(); + stateJumping.Trigger.Add(_jumpCountdown = new AiTriggerCountdown(500, JumpTick, JumpEnd)); + var stateDespawning = new AiState(); + stateDespawning.Trigger.Add(new AiTriggerCountdown(DespawnTime, DespawnTick, DespawnEnd)); + + _aiComponent = new AiComponent(); + + _aiComponent.Trigger.Add(new AiTriggerUpdate(Update)); + _aiComponent.Trigger.Add(_damageTrigger = new AiTriggerCountdown(CooldownTime, DamageTick, FinishDamage)); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("waiting", stateWaiting); + _aiComponent.States.Add("spawning", stateSpawning); + _aiComponent.States.Add("jumping", stateJumping); + _aiComponent.States.Add("despawning", stateDespawning); + + _aiComponent.ChangeState("idle"); + + _animator = AnimatorSaveLoad.LoadAnimator("MidBoss/desertLanmola"); + _animator.Play("ground"); + + _sprite = new CSprite(_position); + _sprite.IsVisible = false; + + AddComponent(BaseAnimationComponent.Index, new AnimationComponent(_animator, _sprite, new Vector2(0, 0))); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerBottom)); + AddComponent(AiComponent.Index, _aiComponent); + + if (!string.IsNullOrEmpty(_triggerKey)) + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + + _head = new MBossDesertLanmolaHead(map, this, new Vector2(posX, posY)); + map.Objects.SpawnObject(_head); + _head.Hide(); + + for (var i = 0; i < _bodyParts.Length; i++) + { + _bodyParts[i] = new MBossDesertLanmolaBody(map, new Vector2(posX, posY), i == 5); + map.Objects.SpawnObject(_bodyParts[i]); + _bodyParts[i].Hide(); + } + } + + private void OnKeyChange() + { + var triggerState = Game1.GameManager.SaveManager.GetString(_triggerKey); + Game1.GameManager.SaveManager.SetString(_triggerKey, "0"); + + // was triggered? + if (_playerLeft && triggerState == "1") + { + _playerLeft = false; + + // start boss music + Game1.GameManager.SetMusic(79, 2); + + Game1.GameManager.StartDialogPath("desertLanmola"); + + if (_aiComponent.CurrentStateId == "idle") + _aiComponent.ChangeState("waiting"); + } + } + + private void Update() + { + // player left? + if (!_playerLeft && !_field.Contains(MapManager.ObjLink.BodyRectangle)) + { + _playerLeft = true; + Game1.GameManager.SetMusic(-1, 2); + } + } + + private void ToSpawning() + { + if (_playerLeft) + { + _aiComponent.ChangeState("idle"); + return; + } + + _aiComponent.ChangeState("spawning"); + + var randomX = Game1.RandomNumber.Next(0, 8); + var randomY = Game1.RandomNumber.Next(0, 6); + + if (randomX == 0 || randomX == 7) + randomY = Math.Clamp(randomY, 1, 6); + + _position.Set(new Vector2(_fieldSmall.X + randomX * 16 + 8, _fieldSmall.Y + randomY * 16 + 16)); + + _sprite.IsVisible = true; + _animator.Play("ground"); + } + + private void ToJumping() + { + if (_playerLeft) + { + _sprite.IsVisible = false; + _aiComponent.ChangeState("idle"); + return; + } + + _sprite.IsVisible = false; + + var direction = new Vector2(_fieldSmall.Center.X, _fieldSmall.Center.Y) - _position.Position; + direction.Normalize(); + + var randomDistance = Game1.RandomNumber.Next(48, 80); + _jumpPosition = _position.Position + direction * randomDistance; + + _jumpStartPosition = _position.Position; + + _jumpTime = Game1.RandomNumber.Next(1500, 2000); + _jumpCountdown.StartTime = _jumpTime + 1000; + + _jumpLandSound = false; + + _aiComponent.ChangeState("jumping"); + + _head.Spawn(direction); + _head.EntityPosition.Set(_jumpStartPosition); + + // sand particles + SpawnParticles(new Vector2(_position.X, _position.Y)); + } + + private void JumpTick(double count) + { + var jumpState = 1 - (float)((count - 1000) / _jumpTime); + var headPosition = GetPosition(jumpState); + + if (jumpState > 1 && _head.IsVisible) + { + _head.Hide(); + // sand particles + SpawnParticles(new Vector2(headPosition.X, headPosition.Y)); + } + + if (!_jumpLandSound && jumpState > 0.5f) + { + _jumpLandSound = true; + Game1.GameManager.PlaySoundEffect("D378-35-23"); + } + + _head.EntityPosition.Set(headPosition); + + if (jumpState > 0.8f) + _head.SetDown(); + + for (var i = 0; i < _bodyParts.Length; i++) + { + var state = 1 - (float)((count - (5 - i) * 166) / _jumpTime); + var partPosition = GetPosition(state); + + var spawnParticles = false; + + if (0 <= state && state <= 1 && !_bodyParts[i].IsVisible) + { + spawnParticles = true; + _bodyParts[i].Show(); + } + + if (state >= 1 && _bodyParts[i].IsVisible) + { + spawnParticles = true; + _bodyParts[i].Hide(); + } + + // sand particles + if (spawnParticles) + SpawnParticles(new Vector2(partPosition.X, partPosition.Y)); + + _bodyParts[i].EntityPosition.Set(partPosition); + } + } + + private void JumpEnd() + { + JumpTick(0); + _aiComponent.ChangeState("waiting"); + } + + private Vector3 GetPosition(float state) + { + var newPosition = Vector2.Lerp(_jumpStartPosition, _jumpPosition, state); + var x = state * 9.1365f; + var newHeight = (0.75f * MathF.Sin(x) + 1.45f * MathF.Sin(x * 0.36f)) * 10; + + return new Vector3(newPosition.X, newPosition.Y, newHeight); + } + + private void SpawnParticles(Vector2 position) + { + // sand particles + var leftSand = new MBossDesertLanmolaSand(Map, new Vector2(position.X - 4, position.Y), false); + Map.Objects.SpawnObject(leftSand); + + var rightSand = new MBossDesertLanmolaSand(Map, new Vector2(position.X + 4, position.Y), true); + Map.Objects.SpawnObject(rightSand); + } + + private void DamageTick(double time) + { + var currentEffect = (CooldownTime - time) % 133 < 66 ? Resources.DamageSpriteShader0 : null; + SetEffect(currentEffect); + } + + private void FinishDamage() + { + SetEffect(null); + } + + private void DespawnTick(double time) + { + var currentEffect = time % 133 < 66 ? Resources.DamageSpriteShader0 : null; + SetEffect(currentEffect); + + // despawn the parts + if (time < DespawnTime - 2000) + { + for (var i = 0; i < _bodyParts.Length; i++) + { + if (_bodyParts[i] != null && _bodyParts[i].IsVisible && time < DespawnTime - 2000 - (6 - i) * 500) + { + Game1.GameManager.PlaySoundEffect("D378-19-13"); + + var animation = new ObjAnimator(Map, 0, 0, Values.LayerTop, "Particles/spawn", "run", true); + animation.EntityPosition.Set(new Vector2( + _bodyParts[i].EntityPosition.X - 8, + _bodyParts[i].EntityPosition.Y - 16 - _bodyParts[i].EntityPosition.Z)); + Map.Objects.SpawnObject(animation); + + Map.Objects.DeleteObjects.Add(_bodyParts[i]); + _bodyParts[i] = null; + } + } + } + } + + private void DespawnEnd() + { + Game1.GameManager.SetMusic(-1, 2); + + Map.Objects.DeleteObjects.Add(_head); + + var animation = new ObjAnimator(Map, 0, 0, Values.LayerTop, "Particles/spawn", "run", true); + animation.EntityPosition.Set(new Vector2( + _head.EntityPosition.X - 8, + _head.EntityPosition.Y - 16 - _head.EntityPosition.Z)); + Map.Objects.SpawnObject(animation); + + // set the save key + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + // spawn the fish dungeon key + Map.Objects.SpawnObject(new ObjItem(Map, (int)_head.EntityPosition.X - 8, (int)_head.EntityPosition.Y - 16, "j", "dkey3Collected", "dkey3", null)); + } + + private void SetEffect(SpriteShader effect) + { + _head.Sprite.SpriteShader = effect; + foreach (var part in _bodyParts) + if (part != null) + part.Sprite.SpriteShader = effect; + } + + public Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + if (_damageTrigger.CurrentTime > 0 || _aiComponent.CurrentStateId == "despawning") + return Values.HitCollision.None; + + _lives -= damage; + + if (_lives > 0) + { + _damageTrigger.OnInit(); + Game1.GameManager.PlaySoundEffect("D370-07-07"); + } + else + { + _aiComponent.ChangeState("despawning"); + Game1.GameManager.PlaySoundEffect("D370-16-10"); + } + + return Values.HitCollision.Enemy; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/MidBoss/MBossDesertLanmolaBody.cs b/InGame/GameObjects/MidBoss/MBossDesertLanmolaBody.cs new file mode 100644 index 0000000..eeba076 --- /dev/null +++ b/InGame/GameObjects/MidBoss/MBossDesertLanmolaBody.cs @@ -0,0 +1,48 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + internal class MBossDesertLanmolaBody : GameObject + { + public bool IsVisible = true; + public readonly CSprite Sprite; + + private readonly ShadowBodyDrawComponent _shadowComponent; + + public MBossDesertLanmolaBody(Map.Map map, Vector2 position, bool isTail) : base(map) + { + EntityPosition = new CPosition(position.X, position.Y, 0); + EntitySize = new Rectangle(-8, -48, 16, 48); + + var animator = AnimatorSaveLoad.LoadAnimator("MidBoss/desertLanmola"); + animator.Play(isTail ? "tail" : "body"); + + Sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(animator, Sprite, new Vector2(0, 0)); + + AddComponent(AnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(Sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, _shadowComponent = new ShadowBodyDrawComponent(EntityPosition)); + } + + public void Hide() + { + IsVisible = false; + Sprite.IsVisible = false; + _shadowComponent.IsActive = false; + } + + public void Show() + { + IsVisible = true; + Sprite.IsVisible = true; + _shadowComponent.IsActive = true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/MidBoss/MBossDesertLanmolaHead.cs b/InGame/GameObjects/MidBoss/MBossDesertLanmolaHead.cs new file mode 100644 index 0000000..0e1ebfb --- /dev/null +++ b/InGame/GameObjects/MidBoss/MBossDesertLanmolaHead.cs @@ -0,0 +1,82 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + internal class MBossDesertLanmolaHead : GameObject + { + public bool IsVisible = true; + public readonly CSprite Sprite; + + private readonly MBossDesertLanmola _owner; + private readonly Animator _animator; + private readonly ShadowBodyDrawComponent _shadowComponent; + private readonly DamageFieldComponent _damageComponent; + + private int _direction; + + public MBossDesertLanmolaHead(Map.Map map, MBossDesertLanmola owner, Vector2 position) : base(map) + { + EntityPosition = new CPosition(position.X, position.Y, 0); + EntitySize = new Rectangle(-8, -48, 16, 48); + + _owner = owner; + _animator = AnimatorSaveLoad.LoadAnimator("MidBoss/desertLanmola"); + _animator.Play("head_0"); + + Sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, Sprite, new Vector2(0, 0)); + + var damageBox = new CBox(EntityPosition, -7, -15, 0, 14, 14, 8, true); + AddComponent(DamageFieldComponent.Index, _damageComponent = new DamageFieldComponent(damageBox, HitType.Enemy, 4)); + + var hittableBox = new CBox(EntityPosition, -7, -15, 0, 14, 14, 8, true); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(AnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(Sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, _shadowComponent = new ShadowBodyDrawComponent(EntityPosition)); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + if (!IsVisible) + return Values.HitCollision.None; + + return _owner.OnHit(originObject, direction, type, damage, pieceOfPower); + } + + public void Hide() + { + IsVisible = false; + Sprite.IsVisible = false; + _shadowComponent.IsActive = false; + _damageComponent.IsActive = false; + } + + public void Spawn(Vector2 direction) + { + IsVisible = true; + Sprite.IsVisible = true; + _shadowComponent.IsActive = true; + _damageComponent.IsActive = true; + + if (Math.Abs(direction.Y) > Math.Abs(direction.X)) + _direction = direction.Y > 0 ? 3 : 1; + else + _direction = direction.X > 0 ? 2 : 0; + + _animator.Play("head_" + _direction); + } + + public void SetDown() + { + _animator.Play("head_3"); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/MidBoss/MBossDesertLanmolaSand.cs b/InGame/GameObjects/MidBoss/MBossDesertLanmolaSand.cs new file mode 100644 index 0000000..a5ee36a --- /dev/null +++ b/InGame/GameObjects/MidBoss/MBossDesertLanmolaSand.cs @@ -0,0 +1,57 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + internal class MBossDesertLanmolaSand : GameObject + { + private readonly Animator _animator; + private Vector3 _velocity; + + public MBossDesertLanmolaSand(Map.Map map, Vector2 position, bool mirrorH) : base(map) + { + EntityPosition = new CPosition(position.X, position.Y, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("MidBoss/desertLanmola"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(0, 0)) + { + MirroredH = mirrorH + }; + + _animator.Play("sand_up"); + + _velocity = new Vector3(-0.55f, 0, 1.125f); + if (mirrorH) + _velocity.X = -_velocity.X; + + AddComponent(AnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerPlayer)); + } + + private void Update() + { + EntityPosition.Set(EntityPosition.Position + new Vector2(_velocity.X, _velocity.Y) * Game1.TimeMultiplier); + + EntityPosition.Z += _velocity.Z * Game1.TimeMultiplier; + _velocity.Z -= Game1.TimeMultiplier * 0.1f; + + // despawn + if (EntityPosition.Z < 0) + { + Map.Objects.DeleteObjects.Add(this); + return; + } + + if (_velocity.Z < 0) + _animator.Play("sand_down"); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/MidBoss/MBossGiantBuzzBlob.cs b/InGame/GameObjects/MidBoss/MBossGiantBuzzBlob.cs new file mode 100644 index 0000000..52e9ff3 --- /dev/null +++ b/InGame/GameObjects/MidBoss/MBossGiantBuzzBlob.cs @@ -0,0 +1,380 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Dungeon; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + class MBossGiantBuzzBlob : GameObject + { + private readonly Animator _animator; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _aiDamageState; + private readonly CSprite _sprite; + + private ObjDungeonFairy _dungeonFairy; + + private readonly string _saveKey; + + private const float WalkSpeed = 0.25f; + private const float JumpSpeed = 0.5f; + + // small delay before starting to walk + private float _idleDelayCounter = 250; + + private bool _startAttack; + private bool _swordMessage; + private bool _toSlime; + private int _jumpCounter; + private bool _wasHit; + private bool _attackable; + + public MBossGiantBuzzBlob() : base("giant buzz blob") { } + + public MBossGiantBuzzBlob(Map.Map map, int posX, int posY, string saveKey) : base(map) + { + EntityPosition = new CPosition(posX + 16, posY + 32, 0); + EntitySize = new Rectangle(-16, -32, 32, 32); + + _saveKey = saveKey; + + // was already killed? + if (!string.IsNullOrEmpty(_saveKey) && + Game1.GameManager.SaveManager.GetString(_saveKey) == "1") + { + IsDead = true; + return; + } + + _animator = AnimatorSaveLoad.LoadAnimator("MidBoss/giant buzz blob"); + _animator.Play("floor"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -10, -16, 20, 16, 8) + { + IgnoreHoles = true, + Gravity = -0.095f, + FieldRectangle = Map.GetField(posX, posY, 16) + }; + + _aiComponent = new AiComponent(); + + var stateIdle = new AiState(UpdateIdle); + var stateIdleDelay = new AiState(UpdateIdleDelay); + var stateWalk = new AiState(UpdateWalk) { Init = InitWalk }; + stateWalk.Trigger.Add(new AiTriggerRandomTime(EndWalk, 300, 1000)); + var stateAttack = new AiState { Init = InitAttack }; + stateAttack.Trigger.Add(new AiTriggerCountdown(50, null, EndAttack)); + var statePreSlime = new AiState(); + statePreSlime.Trigger.Add(new AiTriggerCountdown(600, null, () => _aiComponent.ChangeState("toSlime"))); + var stateToSlime = new AiState(UpdateToSlime) { Init = InitToSlime }; + var stateSlime = new AiState { Init = InitSlime }; + stateSlime.Trigger.Add(new AiTriggerCountdown(133, null, EndSlime)); + var statePreJump = new AiState(UpdatePreJump) { Init = InitPreJump }; + var stateJump = new AiState(UpdateJump) { Init = InitJump }; + var statePostJump = new AiState(UpdatePostJump) { Init = InitPostJump }; + var stateEndSlime = new AiState(UpdateEndSlime) { Init = InitEndSlime }; + var stateDeath = new AiState { Init = InitDeath }; + + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("idleDelay", stateIdleDelay); + _aiComponent.States.Add("walk", stateWalk); + _aiComponent.States.Add("attack", stateAttack); + _aiComponent.States.Add("preSlime", statePreSlime); + _aiComponent.States.Add("toSlime", stateToSlime); + _aiComponent.States.Add("slime", stateSlime); + _aiComponent.States.Add("preJump", statePreJump); + _aiComponent.States.Add("jump", stateJump); + _aiComponent.States.Add("postJump", statePostJump); + _aiComponent.States.Add("endSlime", stateEndSlime); + _aiComponent.States.Add("death", stateDeath); + _aiDamageState = new AiDamageState(this, _body, _aiComponent, _sprite, 6, false, false) + { + HitMultiplierX = 1, + HitMultiplierY = 1, + ExplosionOffsetY = 4, + BossHitSound = true + }; + _aiDamageState.AddBossDamageState(OnDeathAnimationEnd); + _aiDamageState.DamageSpriteShader = Resources.DamageSpriteShader1; + + _aiComponent.ChangeState("idle"); + + var damageBox = new CBox(EntityPosition, -8, -28, 0, 16, 28, 8, false); + var hittableBox = new CBox(EntityPosition, -8, -28, 0, 16, 28, 8, false); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 4)); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _sprite) { ShadowWidth = 14, ShadowHeight = 5 }); + } + + private void UpdateIdle() + { + if (_body.FieldRectangle.Contains(MapManager.ObjLink.BodyRectangle)) + { + Game1.GameManager.StartDialogPath("giant_buzz_blob_enter"); + _aiComponent.ChangeState("idleDelay"); + } + } + + private void UpdateIdleDelay() + { + if (Game1.GameManager.DialogIsRunning()) + return; + + _idleDelayCounter -= Game1.DeltaTime; + if (0 < _idleDelayCounter) + return; + + _aiComponent.ChangeState("endSlime"); + } + + private void InitWalk() + { + if (_toSlime) + return; + + _animator.Play("walk"); + var rotation = Game1.RandomNumber.Next(0, 628) / 100f; + var direction = new Vector2(MathF.Sin(rotation), MathF.Cos(rotation)); + _body.VelocityTarget = direction * WalkSpeed; + } + + private void UpdateWalk() + { + // spawn a fairy carrying powder for the player? + var powder = Game1.GameManager.GetItem("powder"); + if ((powder == null || powder.Count <= 0) && (_dungeonFairy == null || !_dungeonFairy.IsActive)) + { + _dungeonFairy = new ObjDungeonFairy(Map, (int)EntityPosition.X, (int)EntityPosition.Y, 32, "powder_10"); + Map.Objects.SpawnObject(_dungeonFairy); + } + // make sure to be on the straight frame when attacking + if (!_toSlime && _startAttack && _animator.CurrentFrameIndex % 2 == 0 && _animator.FrameCounter >= 50) + { + _startAttack = false; + _aiComponent.ChangeState("attack"); + } + + if (_toSlime && _animator.CurrentFrameIndex % 2 == 0) + { + _toSlime = false; + _jumpCounter = 0; + _animator.Pause(); + _aiComponent.ChangeState("preSlime"); + } + } + + private void EndWalk() + { + if (Game1.RandomNumber.Next(0, 3) == 0) + _startAttack = true; + else + _aiComponent.ChangeState("walk"); + } + + private void InitAttack() + { + _body.VelocityTarget = Vector2.Zero; + _sprite.SpriteShader = Resources.DamageSpriteShader1; + + // spawn buzz + var direction = Game1.RandomNumber.Next(0, 2); + var spawnOrigin = new Vector2(EntityPosition.X, EntityPosition.Y - 14); + for (var i = 0; i < 4; i++) + { + var rotation = MathF.PI / 2 * i + direction * MathF.PI / 4; + var offset = new Vector2(-MathF.Cos(rotation), MathF.Sin(rotation)); + var objBuzz = new MBossBuzz(Map, new Vector2(spawnOrigin.X + offset.X * 20, spawnOrigin.Y + offset.Y * 20), offset, "buzz_" + direction, MathF.PI / 2 * i); + Map.Objects.SpawnObject(objBuzz); + } + } + + private void EndAttack() + { + _sprite.SpriteShader = null; + _aiComponent.ChangeState("walk"); + } + + private void InitEndSlime() + { + _attackable = false; + _wasHit = false; + _animator.Play("deslime"); + } + + private void UpdateEndSlime() + { + if (!_animator.IsPlaying) + _aiComponent.ChangeState("walk"); + } + + private void InitToSlime() + { + _attackable = true; + _animator.Play("slime"); + } + + private void UpdateToSlime() + { + if (!_animator.IsPlaying) + _aiComponent.ChangeState("slime"); + } + + private void InitSlime() + { + _animator.Play("floor"); + } + + private void EndSlime() + { + if (_jumpCounter < 3 && (!_wasHit || _jumpCounter == 0)) + _aiComponent.ChangeState("preJump"); + else + _aiComponent.ChangeState("endSlime"); + + _jumpCounter++; + } + + private void InitPreJump() + { + _animator.Play("jump"); + } + + private void UpdatePreJump() + { + if (!_animator.IsPlaying) + _aiComponent.ChangeState("jump"); + } + + private void InitJump() + { + _animator.Play("fly"); + _body.Velocity.Z = 2.5f; + + // move towards the player + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + _body.VelocityTarget = playerDirection * JumpSpeed; + } + + private void UpdateJump() + { + if (_body.IsGrounded) + _aiComponent.ChangeState("postJump"); + } + + private void InitPostJump() + { + _body.VelocityTarget = Vector2.Zero; + _animator.Play("land"); + } + + private void UpdatePostJump() + { + if (!_animator.IsPlaying) + _aiComponent.ChangeState("slime"); + } + + private void InitDeath() + { + _body.VelocityTarget = Vector2.Zero; + _animator.Play("land"); + } + + private void OnDeathAnimationEnd() + { + if (!string.IsNullOrEmpty(_saveKey)) + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + // stop boss music + Game1.GameManager.SetMusic(-1, 2); + + Game1.GameManager.PlaySoundEffect("D378-26-1A"); + + // spawns a fairy + Game1.GameManager.PlaySoundEffect("D360-27-1B"); + Map.Objects.SpawnObject(new ObjDungeonFairy(Map, (int)EntityPosition.X, (int)EntityPosition.Y, 8)); + + Map.Objects.DeleteObjects.Add(this); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X, direction.Y, _body.Velocity.Z); + + return true; + } + + public Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_aiDamageState.CurrentLives <= 0 || _aiDamageState.IsInDamageState()) + return Values.HitCollision.None; + + if (damageType == HitType.MagicPowder) + damage = 1; + if (damageType == HitType.Boomerang) + damage = 2; + + if (_attackable) + { + _wasHit = true; + var hit = _aiDamageState.OnHit(gameObject, direction, damageType, damage, false); + if (_aiDamageState.CurrentLives <= 0) + _aiComponent.ChangeState("death"); + + return hit; + } + + _body.Velocity.X = direction.X; + _body.Velocity.Y = direction.Y; + + // show initial message telling the player that the sword is useless + if (!_swordMessage && (damageType & HitType.Sword) != 0) + { + _swordMessage = true; + Game1.GameManager.StartDialogPath("giant_buzz_blob_sword"); + } + + if (damageType == HitType.MagicPowder && _aiComponent.CurrentStateId == "walk") + { + // do not show the sword message after the player has already figured out that there can be something done with the powder + _swordMessage = true; + _toSlime = true; + _body.VelocityTarget = Vector2.Zero; + + var hit = _aiDamageState.OnHit(gameObject, direction, damageType, damage, false); + if (_aiDamageState.CurrentLives <= 0) + _aiComponent.ChangeState("death"); + + return hit; + } + + if (_aiComponent.CurrentStateId == "walk") + { + _aiDamageState.SetDamageState(false); + Game1.GameManager.PlaySoundEffect("D370-07-07"); + + return Values.HitCollision.Repelling | Values.HitCollision.Repelling0; + } + + return Values.HitCollision.Enemy; + } + } +} diff --git a/InGame/GameObjects/MidBoss/MBossGohma.cs b/InGame/GameObjects/MidBoss/MBossGohma.cs new file mode 100644 index 0000000..0def4a3 --- /dev/null +++ b/InGame/GameObjects/MidBoss/MBossGohma.cs @@ -0,0 +1,373 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Enemies; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + class MBossGohma : GameObject + { + private readonly Animator _animator; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _aiDamageState; + private readonly AnimationComponent _animationComponent; + private readonly AiTriggerCountdown _attackAbortTrigger; + private readonly CSprite _sprite; + private readonly DamageFieldComponent _damageField; + + private const int ShakeTime = 1500; + private const int BodyWidth = 28; + + private Vector2 _attackStartPosition; + private Vector2 _attackTargetPosition; + + private const float AttackSpeed = 1.5f; + private const float AttackReturnSpeed = 1f; + + private const float WalkSpeed = 1.0f; + private const float RunSpeed = 1.5f; + + // 0: both parts are alive + // 1: one of them is dead + // 2: both parts are dead + private int _bossState; + + private string _saveKey; + private bool _isOnTop; + + public MBossGohma(Map.Map map, int posX, int posY, string saveKey, bool onTop) : base(map, "gohma") + { + EntityPosition = new CPosition(posX + 16, posY + 16, 0); + EntitySize = new Rectangle(-16, -16, 32, 16); + + _saveKey = saveKey; + _isOnTop = onTop; + + // there is no door and this is strange because in the original you can kill only one of them and just reenter the room + if (!string.IsNullOrEmpty(_saveKey)) + { + // check if the boss was already killed + var bossState = Game1.GameManager.SaveManager.GetInt(_saveKey, 0); + if (bossState == 2) + { + IsDead = true; + return; + } + else + { + Game1.GameManager.SaveManager.SetInt(_saveKey, 0); + } + + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + } + + _animator = AnimatorSaveLoad.LoadAnimator("MidBoss/gohma"); + + _sprite = new CSprite(EntityPosition); + _animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(0, -16)); + + _body = new BodyComponent(EntityPosition, -BodyWidth / 2, -14, BodyWidth, 14, 8) + { + IgnoreHoles = true, + MoveCollision = OnCollision, + FieldRectangle = Map.GetField(posX, posY, 16) + }; + + _aiComponent = new AiComponent(); + + var stateIdle = new AiState(UpdateIdle); + var stateWalk = new AiState { Init = InitWalk }; + stateWalk.Trigger.Add(new AiTriggerRandomTime(ChangeState, 1500, 3000)); + var stateRun = new AiState { Init = InitRun }; + stateRun.Trigger.Add(new AiTriggerRandomTime(ChangeState, 1500, 2500)); + var stateShake = new AiState { Init = InitShake }; + stateShake.Trigger.Add(new AiTriggerCountdown(ShakeTime, ShakeTick, ShakeEnd)); + var stateAttack = new AiState(UpdateAttack) { Init = InitAttack }; + // this trigger is used to abort the attack with a little delay so to not directly return + stateAttack.Trigger.Add(_attackAbortTrigger = new AiTriggerCountdown(65, null, () => _aiComponent.ChangeState("attackReturn"), false)); + var stateAttackReturn = new AiState(UpdateAttackRevert) { Init = InitAttackReturn }; + var stateWait = new AiState(); + + var stateEye0 = new AiState(); + stateEye0.Trigger.Add(new AiTriggerCountdown(1000, null, ToEye1)); + var stateEye1 = new AiState(); + stateEye1.Trigger.Add(new AiTriggerCountdown(400, null, ToEye2)); + var stateEye2 = new AiState(); + stateEye2.Trigger.Add(new AiTriggerCountdown(350, null, ToEye3)); + var stateEye3 = new AiState(); + stateEye3.Trigger.Add(new AiTriggerCountdown(1000, null, () => _aiComponent.ChangeState("walk"))); + + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("walk", stateWalk); + _aiComponent.States.Add("run", stateRun); + _aiComponent.States.Add("attackShake", stateShake); + _aiComponent.States.Add("attack", stateAttack); + _aiComponent.States.Add("attackReturn", stateAttackReturn); + _aiComponent.States.Add("wait", stateWait); + _aiComponent.States.Add("eye0", stateEye0); + _aiComponent.States.Add("eye1", stateEye1); + _aiComponent.States.Add("eye2", stateEye2); + _aiComponent.States.Add("eye3", stateEye3); + + _aiDamageState = new AiDamageState(this, _body, _aiComponent, _sprite, 12, false, false) + { + BossHitSound = true, + HitMultiplierX = 0, + HitMultiplierY = 0, + ExplosionOffsetY = 8 + }; + _aiDamageState.AddBossDamageState(OnDeath); + + _aiComponent.ChangeState("idle"); + + var damageCollider = new CBox(EntityPosition, -14, -14, 0, 28, 14, 8); + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageCollider, HitType.Enemy, 4)); + // RepelMultiplier needs to be high so that the player does not end in the boss + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush) { RepelMultiplier = 1.5f }); + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, OnHit)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, _animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(_sprite)); + } + + private void OnKeyChange() + { + _bossState = Game1.GameManager.SaveManager.GetInt(_saveKey, 0); + } + + private void ChangeState() + { + _animator.SpeedMultiplier = 1f; + + // 25% chance to start walking + var changeState = Game1.RandomNumber.Next(0, 4) < 3 && + MapManager.ObjLink.EntityPosition.Position.Y < EntityPosition.Position.Y + 40; + + if (changeState) + { + // player is standing above the boss + if (Game1.RandomNumber.Next(0, 2) == 0) + _aiComponent.ChangeState("attackShake"); + else + ToEye0(); + } + else + { + _aiComponent.ChangeState("walk"); + } + + // player left the room? + if (!_body.FieldRectangle.Intersects(MapManager.ObjLink.BodyRectangle)) + { + Game1.GameManager.SetMusic(-1, 2); + _aiComponent.ChangeState("idle"); + } + } + + private void UpdateIdle() + { + // start walking + if (_body.FieldRectangle.Intersects(MapManager.ObjLink.BodyRectangle)) + { + Game1.GameManager.SetMusic(79, 2); + _aiComponent.ChangeState("walk"); + } + } + + private void ToEye0() + { + // stop walking + _body.VelocityTarget = Vector2.Zero; + _animator.Play("stand"); + + _aiComponent.ChangeState("eye0"); + } + + private void ToEye1() + { + _animator.Play("eye"); + + _aiComponent.ChangeState("eye1"); + } + + private void ToEye2() + { + // spawn a fireball + Map.Objects.SpawnObject(new EnemyFireball(Map, (int)EntityPosition.X, (int)EntityPosition.Y - 8, 1.25f)); + + _aiComponent.ChangeState("eye2"); + } + + private void ToEye3() + { + _animator.Play("stand"); + + _aiComponent.ChangeState("eye3"); + } + + private void InitWalk() + { + var direction = -1 + Game1.RandomNumber.Next(0, 2) * 2; + _body.VelocityTarget = new Vector2(direction, 0) * WalkSpeed; + _animator.Play("walk"); + } + + private void InitRun() + { + var direction = -1 + Game1.RandomNumber.Next(0, 2) * 2; + _body.VelocityTarget = new Vector2(direction, 0) * RunSpeed; + _animator.Play("walk"); + _animator.SpeedMultiplier = 1.5f; + } + + private void InitShake() + { + _body.VelocityTarget = Vector2.Zero; + } + + private void ShakeTick(double counter) + { + // 5 frames to go left/right + _animationComponent.SpriteOffset.X = MathF.Sin(MathF.PI * ((ShakeTime - (float)counter) / 1000 * (60 / 5f))); + _animationComponent.UpdateSprite(); + } + + private void ShakeEnd() + { + _animationComponent.SpriteOffset.X = 0; + + // attack or start running depending on if the player is standing above the boss + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDirection.Y < 0) + _aiComponent.ChangeState("run"); + else + _aiComponent.ChangeState("attack"); + } + + private void InitAttack() + { + _attackStartPosition = EntityPosition.Position; + // 45 if the top is the last one alive + _attackTargetPosition = EntityPosition.Position + new Vector2(0, _bossState == 1 ? 45 : 25); + + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + + var offset = 44; + // make sure to not leave the room + if (playerDirection.X < -22 && _body.FieldRectangle.Left <= EntityPosition.Position.X - BodyWidth / 2 - offset) + _attackTargetPosition.X -= offset; + if (playerDirection.X > 22 && EntityPosition.Position.X + BodyWidth / 2 + offset <= _body.FieldRectangle.Right) + _attackTargetPosition.X += offset; + } + + private void UpdateAttack() + { + var targetDirection = _attackTargetPosition - EntityPosition.Position; + var offset = AttackSpeed * Game1.TimeMultiplier; + + if (targetDirection.Length() <= offset) + { + EntityPosition.Set(_attackTargetPosition); + _aiComponent.ChangeState("attackReturn"); + _attackStartPosition.X = _attackTargetPosition.X; + } + else + { + // move towards the target position + targetDirection.Normalize(); + EntityPosition.Move(targetDirection * AttackSpeed); + } + } + + private void InitAttackReturn() + { + Game1.GameManager.PlaySoundEffect("D370-22-16"); + } + + private void UpdateAttackRevert() + { + var targetDirection = _attackStartPosition - EntityPosition.Position; + var offset = AttackReturnSpeed * Game1.TimeMultiplier; + + if (targetDirection.Length() <= offset) + { + EntityPosition.Set(_attackStartPosition); + _aiComponent.ChangeState("walk"); + } + else + { + // move towards the target position + targetDirection.Normalize(); + EntityPosition.Move(targetDirection * AttackReturnSpeed); + } + } + + private void OnDeath() + { + // spawn a heart + var objItem = new ObjItem(Map, (int)EntityPosition.X - 8, (int)EntityPosition.Y - 16, "j", null, "heart", null); + Map.Objects.SpawnObject(objItem); + + _damageField.IsActive = false; + + Game1.GameManager.SaveManager.SetInt(_saveKey, _bossState + 1); + + if (_bossState == 1) + { + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + // stop boss music + Game1.GameManager.SetMusic(-1, 2); + } + + Map.Objects.DeleteObjects.Add(this); + } + + private void OnCollision(Values.BodyCollision collision) + { + // change the direction if we collide with a wall + _body.VelocityTarget.X = -_body.VelocityTarget.X; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + // abort the attack + if (_aiComponent.CurrentStateId == "attack" && !_attackAbortTrigger.IsRunning()) + { + _attackAbortTrigger.OnInit(); + _attackAbortTrigger.Start(); + } + + return true; + } + + public Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + // can only hit the boss with the hookshot or an arrow + if ((damageType & (HitType.Hookshot | HitType.Bow | HitType.MagicRod | HitType.Boomerang)) == 0 || + (_aiComponent.CurrentStateId != "eye1" && _aiComponent.CurrentStateId != "eye2") || + _aiDamageState.IsInDamageState()) + { + return Values.HitCollision.RepellingParticle; + } + + if (damageType == HitType.Bow) + damage *= 2; + if (damageType == HitType.MagicRod) + damage *= 2; + if (damageType == HitType.Boomerang) + damage = 4; + + return _aiDamageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + } + } +} diff --git a/InGame/GameObjects/MidBoss/MBossGrimCreeper.cs b/InGame/GameObjects/MidBoss/MBossGrimCreeper.cs new file mode 100644 index 0000000..eda18f7 --- /dev/null +++ b/InGame/GameObjects/MidBoss/MBossGrimCreeper.cs @@ -0,0 +1,302 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Enemies; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + internal class MBossGrimCreeper : GameObject + { + private readonly Animator _animator; + private readonly BodyComponent _body; + private readonly AnimationComponent _animatorComponent; + private readonly CSprite _sprite; + private readonly AiComponent _aiComponent; + private readonly BodyDrawShadowComponent _shadowComponent; + + private readonly MBossGrimCreeperFly[] _fly = new MBossGrimCreeperFly[6]; + + private Vector2 _flyOrigin; + private Vector2[] _positions = new[] { + new Vector2(1, 2), new Vector2(6, 2), new Vector2(2, 3), new Vector2(3, 2),new Vector2(5, 3), new Vector2(4, 2), + new Vector2(2, 1), new Vector2(5, 1), new Vector2(2, 3), new Vector2(5, 3), new Vector2(2, 5), new Vector2(5, 5), + new Vector2(2, 2), new Vector2(5, 4), new Vector2(3.5f, 1), new Vector2(3.5f, 5), new Vector2(2, 4), new Vector2(5, 2), + new Vector2(1, 1), new Vector2(6, 5), new Vector2(6, 1), new Vector2(1, 5), new Vector2(3.5f, 1), new Vector2(3.5f, 5), + new Vector2(1, 0), new Vector2(2, 1), new Vector2(3, 2), new Vector2(4, 2), new Vector2(5, 1), new Vector2(6, 0), + new Vector2(1, 1), new Vector2(6, 1), new Vector2(6, 5), new Vector2(1, 5), new Vector2(4.5f, 3), new Vector2(2.5f, 3), + new Vector2(0, 1.5f), new Vector2(7, 1.5f), new Vector2(1, 3.5f), new Vector2(6, 3.5f), new Vector2(4.5f, 5), new Vector2(2.5f, 5), + new Vector2(2, 4), new Vector2(5, 4), new Vector2(3, 3), new Vector2(4, 5), new Vector2(3, 5), new Vector2(4, 3), + }; + + private readonly string _saveKey; + + private int _flyIndex; + + private float _spawnCounter; + private const float SpawnTime = 500; + private int _spawnIndex; + + private float _attackCounter; + private const float AttackTime = 550; + private int _attackIndex; + + private bool _initDialog; + + public MBossGrimCreeper() : base("grim creeper") { } + + public MBossGrimCreeper(Map.Map map, int posX, int posY, string saveKey) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, 32); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _saveKey = saveKey; + + if (!string.IsNullOrEmpty(_saveKey) && + Game1.GameManager.SaveManager.GetString(_saveKey) == "1") + { + IsDead = true; + return; + } + + _animator = AnimatorSaveLoad.LoadAnimator("MidBoss/grim creeper"); + _animator.Play("idle"); + + _sprite = new CSprite(EntityPosition); + _animatorComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -7, -12, 14, 12, 8) + { + IsActive = false, + IsGrounded = false, + Gravity = -0.125f, + FieldRectangle = Map.GetField(posX, posY, 16) + }; + + var stateIdle = new AiState(UpdateIdle); + var stateSpawn = new AiState(UpdateSpawn) { Init = InitSpawn }; + var statePostSpawn = new AiState(); + statePostSpawn.Trigger.Add(new AiTriggerCountdown(500, null, () => _aiComponent.ChangeState("summoning"))); + var stateSummoning = new AiState(UpdateSummoning) { Init = InitSummoning }; + var stateWait = new AiState() { Init = InitWait }; + stateWait.Trigger.Add(new AiTriggerCountdown(3500, null, () => _aiComponent.ChangeState("attack"))); + var stateAttack = new AiState(UpdateAttack) { Init = InitAttack }; + var statePostAttack = new AiState(UpdatePostAttack); + statePostAttack.Trigger.Add(new AiTriggerCountdown(1500, null, EndPostAttack)); + var stateFinished = new AiState(); + stateFinished.Trigger.Add(new AiTriggerCountdown(750, null, () => _aiComponent.ChangeState("preJump"))); + var statePreJump = new AiState() { Init = InitPreJump }; + statePreJump.Trigger.Add(new AiTriggerCountdown(500, null, () => _aiComponent.ChangeState("jump"))); + var stateJump = new AiState(UpdateJump) { Init = InitJump }; + + // evil eagle states + var stateSequence = new AiState(UpdateSaddleJump); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("spawn", stateSpawn); + _aiComponent.States.Add("postSpawn", statePostSpawn); + _aiComponent.States.Add("summoning", stateSummoning); + _aiComponent.States.Add("wait", stateWait); + _aiComponent.States.Add("attack", stateAttack); + _aiComponent.States.Add("postAttack", statePostAttack); + _aiComponent.States.Add("finished", stateFinished); + _aiComponent.States.Add("preJump", statePreJump); + _aiComponent.States.Add("jump", stateJump); + _aiComponent.States.Add("sequence", stateSequence); + _aiComponent.ChangeState("idle"); + + var damageCollider = new CBox(EntityPosition, -8, -16, 0, 16, 16, 8); + AddComponent(BaseAnimationComponent.Index, _animatorComponent); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 4)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, _shadowComponent = new BodyDrawShadowComponent(_body, _sprite)); + + UpdateTransparency(24); + _flyOrigin = new Vector2(posX - 48, posY + 8 + 43); + } + + public void StartNightmareSequnece() + { + EntityPosition.Z = 0; + UpdateTransparency(24); + + _aiComponent.ChangeState("sequence"); + _animator.Play("stand"); + } + + public void StartSaddleJump() + { + _body.IsActive = true; + _body.Velocity.X = 0.9f; + _body.Velocity.Y = -2.65f; + _body.DragAir = 1; + _body.IsGrounded = false; + } + + private void UpdateSaddleJump() + { + // check if we are behind the evil eagle + if (_body.Velocity.Y > 2 || _body.IsGrounded) + { + Map.Objects.DeleteObjects.Add(this); + } + } + + private void UpdateIdle() + { + // player entered the room? + if (_body.FieldRectangle.Contains(MapManager.ObjLink.BodyRectangle)) + { + _aiComponent.ChangeState("spawn"); + } + } + + private void InitSpawn() + { + // fall down + _body.IsActive = true; + _animator.Play("attack"); + + Game1.GameManager.SetMusic(79, 2); + } + + private void UpdateSpawn() + { + UpdateTransparency(24); + + if (_body.IsGrounded) + { + Game1.GameManager.StartDialogPath("grim_creeper_enter"); + _animator.Play("play"); + _aiComponent.ChangeState("postSpawn"); + } + } + + private void InitSummoning() + { + _flyIndex = Game1.RandomNumber.Next(0, 8); + _spawnCounter = 0; + _spawnIndex = 0; + _animator.Play("play"); + } + + private void UpdateSummoning() + { + _spawnCounter += Game1.DeltaTime; + + if (_spawnCounter < SpawnTime * _spawnIndex) + return; + + var index = _flyIndex * 6 + _spawnIndex; + var targetPosition = _flyOrigin + new Vector2(_positions[index].X, _positions[index].Y) * 16; + var randomOffsetX = Game1.RandomNumber.Next(0, 32) - 16; + var startPosition = targetPosition + new Vector2(randomOffsetX, 64) * (_positions[index].Y > 4 ? 1 : -1); + _fly[_spawnIndex] = new MBossGrimCreeperFly(Map, startPosition, targetPosition); + _fly[_spawnIndex].FightInit(); + Map.Objects.SpawnObject(_fly[_spawnIndex]); + + _spawnIndex++; + + if (_spawnIndex >= 6) + _aiComponent.ChangeState("wait"); + } + + private void InitWait() + { + _animator.Play("idle"); + } + + private void InitAttack() + { + _attackCounter = 0; + _attackIndex = 0; + _animator.Play("attack"); + } + + private void UpdateAttack() + { + _attackCounter += Game1.DeltaTime; + + if (_attackCounter < AttackTime * _attackIndex) + return; + + if (_attackIndex >= 6) + { + _aiComponent.ChangeState("postAttack"); + } + else + { + _fly[_attackIndex].StartAttack(); + _attackIndex++; + } + } + + private void UpdatePostAttack() + { + // killed all flies? + var finished = true; + for (var i = 0; i < _fly.Length; i++) + { + if (_fly[i].IsAlive()) + { + finished = false; + break; + } + } + + if (finished) + _aiComponent.ChangeState("finished"); + } + + private void EndPostAttack() + { + if (!_initDialog) + { + _initDialog = true; + Game1.GameManager.StartDialogPath("grim_creeper_1"); + } + + _aiComponent.ChangeState("summoning"); + } + + private void InitJump() + { + Game1.GameManager.PlaySoundEffect("D378-62-3F"); + + if (!string.IsNullOrEmpty(_saveKey)) + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + } + + private void UpdateJump() + { + if (_body.IsGrounded) + _body.Velocity.Z = 3.5f; + + // fade out + UpdateTransparency(16); + + // completely invisible => despawn + if (_shadowComponent.Transparency == 0 || _body.Velocity.Z < 0) + Map.Objects.DeleteObjects.Add(this); + } + + private void InitPreJump() + { + Game1.GameManager.StartDialogPath("grim_creeper_end"); + } + + private void UpdateTransparency(int offset) + { + var transparency = 1 - MathHelper.Clamp((EntityPosition.Z - offset) / 8, 0, 1); + _sprite.Color = Color.White * transparency; + _shadowComponent.Transparency = transparency; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/MidBoss/MBossGrimCreeperFly.cs b/InGame/GameObjects/MidBoss/MBossGrimCreeperFly.cs new file mode 100644 index 0000000..413beb0 --- /dev/null +++ b/InGame/GameObjects/MidBoss/MBossGrimCreeperFly.cs @@ -0,0 +1,246 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using ProjectZ.InGame.Map; +using System; + +namespace ProjectZ.InGame.GameObjects.Enemies +{ + internal class MBossGrimCreeperFly : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly CSprite _sprite; + private readonly DamageFieldComponent _damageField; + private readonly HittableComponent _hittableComponent; + private readonly AiDamageState _damageState; + private readonly BodyDrawShadowComponent _shadowComponent; + + private readonly Vector2 _targetPosition; + + private const float FlySpeed = 1; + private const float AttackSpeed = 2; + + private const float FadeTime = 100; + private float _fadeCounter; + + private Vector2 _roomCenter; + private Vector2 _centerPosition; + + private Vector2 _leaveStart; + private Vector2 _leaveEnd; + private float _leaveCounter; + + private float _circlingOffset; + private float _circleSpeed; + + // TODO: sync animations + public MBossGrimCreeperFly(Map.Map map, Vector2 position, Vector2 targetPosition) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(position.X, position.Y, 28); + EntitySize = new Rectangle(-8, -42, 16, 42); + + _roomCenter = Map.GetRoomCenter(targetPosition.X, targetPosition.Y - 43); + _targetPosition = targetPosition; + + _animator = AnimatorSaveLoad.LoadAnimator("MidBoss/grim creeper fly"); + _animator.Play("idle"); + + _sprite = new CSprite(EntityPosition) { Color = Color.Transparent }; + var animatorComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -6, -12, 12, 12, 8) + { + IgnoresZ = true, + IgnoreHoles = true, + Bounciness = 0.25f, + Gravity = -0.175f, + CollisionTypes = Values.CollisionTypes.None + }; + + _aiComponent = new AiComponent(); + + var stateSpawn = new AiState(UpdateSpawn); + var stateIdle = new AiState(); + var stateAttack = new AiState(UpdateAttacking) { Init = InitAttack }; + var stateFadeout = new AiState(UpdateFadeout) { Init = InitFadeout }; + + // grim creeper states + var stateCircling = new AiState(UpdateCircling); + var stateLeave = new AiState(UpdateLeave); + + _aiComponent.States.Add("spawn", stateSpawn); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("attack", stateAttack); + _aiComponent.States.Add("fadeout", stateFadeout); + _damageState = new AiDamageState(this, _body, _aiComponent, _sprite, 1) + { + OnBurn = OnBurn + }; + + _aiComponent.States.Add("circling", stateCircling); + _aiComponent.States.Add("leave", stateLeave); + + _aiComponent.ChangeState("spawn"); + + var damageBox = new CBox(EntityPosition, -5, -12, 0, 10, 10, 8, true); + var hittableBox = new CBox(EntityPosition, -7, -14, 0, 14, 14, 8, true); + + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageBox, HitType.Enemy, 2) { IsActive = false }); + AddComponent(HittableComponent.Index, _hittableComponent = new HittableComponent(hittableBox, _damageState.OnHit) { IsActive = false }); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animatorComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer) { WaterOutline = false }); + AddComponent(DrawShadowComponent.Index, _shadowComponent = new BodyDrawShadowComponent(_body, _sprite) { Transparency = 0 }); + } + + public void StartSequenceMode() + { + EntityPosition.Z = 0; + _centerPosition = EntityPosition.Position; + + _body.VelocityTarget = Vector2.Zero; + _sprite.Color = Color.White; + _aiComponent.ChangeState("circling"); + + _circlingOffset = Game1.RandomNumber.Next(0, 20) / 5f; + _circleSpeed = Game1.RandomNumber.Next(100, 125); + } + + public void ToLeave() + { + _aiComponent.ChangeState("leave"); + _leaveStart = EntityPosition.Position; + _leaveEnd = _targetPosition; + } + + public void FightInit() + { + Game1.GameManager.PlaySoundEffect("D360-49-31"); + } + + private void OnBurn() + { + _body.IgnoresZ = false; + } + + private void UpdateSpawn() + { + UpdateFading(false); + + // move towards the target position + var direction = _targetPosition - EntityPosition.Position; + if (direction.Length() > FlySpeed * Game1.TimeMultiplier) + { + direction.Normalize(); + _body.VelocityTarget = direction * FlySpeed; + } + else + { + // reached the target position + _body.VelocityTarget = Vector2.Zero; + EntityPosition.Set(_targetPosition); + _aiComponent.ChangeState("idle"); + } + } + + private void UpdateLeave() + { + _leaveCounter += Game1.DeltaTime; + + var percentage = 1 - MathF.Cos(_leaveCounter / 1000 * MathF.PI / 2); + var newPosition = Vector2.Lerp(_leaveStart, _leaveEnd, percentage); + EntityPosition.Set(newPosition); + + // fade out + var transparency = Math.Clamp((1000 - _leaveCounter) / FadeTime, 0, 1); + _sprite.Color = Color.White * transparency; + + if (percentage > 1) + { + Map.Objects.DeleteObjects.Add(this); + } + } + + private void UpdateCircling() + { + var newPosition = _centerPosition + new Vector2( + MathF.Sin((float)Game1.TotalGameTime / _circleSpeed + _circlingOffset) * 1, + MathF.Sin((float)Game1.TotalGameTime / _circleSpeed + 1.0f + _circlingOffset) * 2); + EntityPosition.Set(newPosition); + } + + public void StartAttack() + { + _aiComponent.ChangeState("attack"); + } + + public bool IsAlive() + { + return _damageState.CurrentLives > 0; + } + + private void InitAttack() + { + Game1.GameManager.PlaySoundEffect("D360-49-31"); + + _damageField.IsActive = true; + _hittableComponent.IsActive = true; + + // fly towards the player + var direction = MapManager.ObjLink.EntityPosition.Position - new Vector2(EntityPosition.X, EntityPosition.Y - 12); + if (direction != Vector2.Zero) + { + direction.Normalize(); + _body.VelocityTarget = direction * AttackSpeed; + } + } + + private void UpdateAttacking() + { + if (EntityPosition.Z > 12) + EntityPosition.Z -= 0.5f * Game1.TimeMultiplier; + + var direction = _roomCenter - new Vector2(EntityPosition.X, EntityPosition.Y - EntityPosition.Z); + + // fade out? + if (direction.Length() > 120) + _aiComponent.ChangeState("fadeout"); + } + + private void InitFadeout() + { + _fadeCounter = 0; + } + + private void UpdateFadeout() + { + if (UpdateFading(true)) + Map.Objects.DeleteObjects.Add(this); + } + + private bool UpdateFading(bool fadeOut) + { + _fadeCounter += Game1.DeltaTime; + if (_fadeCounter > FadeTime) + _fadeCounter = FadeTime; + + var transparency = _fadeCounter / FadeTime; + if (fadeOut) + transparency = 1 - transparency; + + _sprite.Color = Color.White * transparency; + _shadowComponent.Transparency = transparency; + + return _fadeCounter == FadeTime; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/MidBoss/MBossHinox.cs b/InGame/GameObjects/MidBoss/MBossHinox.cs new file mode 100644 index 0000000..7df773e --- /dev/null +++ b/InGame/GameObjects/MidBoss/MBossHinox.cs @@ -0,0 +1,376 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Dungeon; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + class MBossHinox : GameObject + { + private readonly Color[] _colors = new Color[] { new Color(248, 120, 8), new Color(248, 8, 40), new Color(24, 128, 248) }; + + private readonly Animator _animator; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _aiDamageState; + private readonly DamageFieldComponent _damageFieldComponent; + private readonly CBox _grabBox; + + private readonly string _saveKey; + + private const int GrabTime = 300; + private const int Lives = 8; + + private float _runParticleCount; + + private Vector3 _grabStartPosition; + private int _grabDirection; + + public MBossHinox() : base("hinox") { } + + public MBossHinox(Map.Map map, int posX, int posY, string saveKey, int color) : base(map) + { + if (!string.IsNullOrEmpty(saveKey) && + Game1.GameManager.SaveManager.GetString(saveKey) == "1") + { + IsDead = true; + return; + } + + EntityPosition = new CPosition(posX + 16, posY + 32, 0); + EntitySize = new Rectangle(-16, -32, 32, 32); + + _saveKey = saveKey; + + _animator = AnimatorSaveLoad.LoadAnimator("MidBoss/hinox"); + _animator.Play("idle_0"); + + color = MathHelper.Clamp(color, 0, _colors.Length - 1); + var sprite = new CSprite(EntityPosition) { SpriteShader = Resources.ColorShader, Color = _colors[color] }; + var animationComponent = new AnimationComponent(_animator, sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -14, -20, 28, 20, 8) + { + IgnoreHoles = true, + FieldRectangle = Map.GetField(posX, posY, 8) + }; + + _aiComponent = new AiComponent(); + + var stateIdle = new AiState(UpdateIdle); + var stateWait = new AiState(UpdateWait) { Init = InitWait }; + stateWait.Trigger.Add(new AiTriggerRandomTime(WalkOrRun, 1000, 1500)); + var stateWalk = new AiState { Init = InitWalking }; + stateWalk.Trigger.Add(new AiTriggerRandomTime(EndWalking, 750, 1250)); + var statePreRun = new AiState(UpdatePreRun) { Init = InitPreRun }; + statePreRun.Trigger.Add(new AiTriggerCountdown(750, null, () => _aiComponent.ChangeState("run"))); + var stateRun = new AiState(UpdateRunning) { Init = InitRun }; + stateRun.Trigger.Add(new AiTriggerRandomTime(EndRun, 500, 750)); + var stateThrowLink = new AiState(); + var stateThrowBomb = new AiState() { Init = InitThrowBomb }; + stateThrowBomb.Trigger.Add(new AiTriggerCountdown(250, null, ThrowBomb)); + var stateThrownBomb = new AiState(UpdateThrownBomb); + var stateGrab = new AiState { Init = InitGrab }; + stateGrab.Trigger.Add(new AiTriggerCountdown(GrabTime, GrabTick, () => _aiComponent.ChangeState("grabbed"))); + var stateGrabbed = new AiState(); + stateGrabbed.Trigger.Add(new AiTriggerCountdown(500, null, () => _aiComponent.ChangeState("throw"))); + var stateThrow = new AiState { Init = InitThrow }; + stateThrow.Trigger.Add(new AiTriggerCountdown(600, null, () => _aiComponent.ChangeState("walk"))); + + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("wait", stateWait); + _aiComponent.States.Add("walk", stateWalk); + _aiComponent.States.Add("preRun", statePreRun); + _aiComponent.States.Add("run", stateRun); + _aiComponent.States.Add("throwLink", stateThrowLink); + _aiComponent.States.Add("throwBomb", stateThrowBomb); + _aiComponent.States.Add("thrownBomb", stateThrownBomb); + _aiComponent.States.Add("grab", stateGrab); + _aiComponent.States.Add("grabbed", stateGrabbed); + _aiComponent.States.Add("throw", stateThrow); + _aiDamageState = new AiDamageState(this, _body, _aiComponent, sprite, Lives, true, false) + { + BossHitSound = true + }; + _aiDamageState.AddBossDamageState(OnDeath); + + _aiComponent.ChangeState("idle"); + + _grabBox = new CBox(EntityPosition, -20, -20, 0, 40, 24, 8); + var damageCollider = new CBox(EntityPosition, -14, -24, 0, 28, 24, 8); + var hittableBox = new CBox(EntityPosition, -14, -28, 0, 28, 28, 8); + AddComponent(DamageFieldComponent.Index, _damageFieldComponent = new DamageFieldComponent(damageCollider, HitType.Enemy, 4)); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + } + + private void UpdateIdle() + { + // player entered the room? + if (_body.FieldRectangle.Contains(MapManager.ObjLink.BodyRectangle)) + { + // start boss music + Game1.GameManager.SetMusic(79, 2); + + _aiComponent.ChangeState("walk"); + } + } + + private void InitGrab() + { + MapManager.ObjLink.Stun(2000); + MapManager.ObjLink.StartGrab(); + + Game1.GameManager.PlaySoundEffect("D370-22-16"); + + _body.VelocityTarget = Vector2.Zero; + + _damageFieldComponent.IsActive = false; + + if (MapManager.ObjLink.PosX < EntityPosition.X) + _grabDirection = 1; + else + _grabDirection = -1; + + _animator.Pause(); + _animator.SetFrame(_grabDirection == 1 ? 0 : 1); + + _grabStartPosition = MapManager.ObjLink.EntityPosition.ToVector3(); + } + + private void GrabTick(double counter) + { + var percentage = 1 - (float)(counter / GrabTime); + var grabEndPosition = new Vector3(EntityPosition.X + 16 * _grabDirection, EntityPosition.Y + 1, 26); + var newPosition = Vector3.Lerp(_grabStartPosition, grabEndPosition, percentage); + MapManager.ObjLink.EntityPosition.Set(newPosition); + } + + private void InitThrow() + { + Game1.GameManager.PlaySoundEffect("D360-08-08"); + + // set the position to be inside of the hinox body to not start throwing the player into a collider + var grabEndPosition = new Vector3(EntityPosition.X + 16 * _grabDirection, EntityPosition.Y, 25); + MapManager.ObjLink.EntityPosition.Set(grabEndPosition); + MapManager.ObjLink.EndGrab(); + MapManager.ObjLink.StartThrow(new Vector3(-4.5f * _grabDirection, 2.5f, 0)); + Game1.GameManager.InflictDamage(4); + + _damageFieldComponent.IsActive = true; + _animator.SetFrame(_grabDirection == 1 ? 1 : 0); + } + + private void ContinueAnimation() + { + _animator.Continue(); + _animator.SpeedMultiplier = 1.0f; + + // set the animation to the next frame + _animator.ResetFrameCounter(); + _animator.SetFrame((_animator.CurrentFrameIndex + 1) % _animator.CurrentAnimation.Frames.Length); + } + + private void InitWait() + { + _animator.Pause(); + _body.VelocityTarget = Vector2.Zero; + } + + private void UpdateWait() + { + // player left the room? + if (!_body.FieldRectangle.Contains(MapManager.ObjLink.BodyRectangle)) + { + // stop boss music + Game1.GameManager.SetMusic(-1, 2); + _aiComponent.ChangeState("idle"); + } + } + + private void WalkOrRun() + { + var random = Game1.RandomNumber.Next(0, 2); + _aiComponent.ChangeState(random == 0 ? "preRun" : "walk"); + _animator.Play("idle_0"); + } + + private void InitWalking() + { + ContinueAnimation(); + + // walk into a random direction + var direction = Game1.RandomNumber.Next(0, 4); + _body.VelocityTarget = AnimationHelper.DirectionOffset[direction] * 0.5f; + } + + private void EndWalking() + { + _aiComponent.ChangeState("wait"); + } + + private void InitPreRun() + { + _animator.Continue(); + _animator.SpeedMultiplier = 2.0f; + } + + private void UpdatePreRun() + { + Game1.GameManager.PlaySoundEffect("D360-32-20", false); + } + + private void InitRun() + { + // run towards the player + var direction = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (direction != Vector2.Zero) + direction.Normalize(); + _body.VelocityTarget = direction * 1.5f; + } + + private void UpdateRunning() + { + // grab the player + if (Game1.GameManager.CurrentHealth > 0 && + _grabBox.Box.Rectangle().Intersects(MapManager.ObjLink.BodyRectangle)) + _aiComponent.ChangeState("grab"); + + // spawn run particle + _runParticleCount -= Game1.DeltaTime; + if (_runParticleCount <= 0) + { + _runParticleCount = 133; + + var animator = new ObjAnimator(Map, + (int)EntityPosition.X, (int)(EntityPosition.Y + 1), + 0, -1 - (int)EntityPosition.Z, Values.LayerPlayer, "Particles/run", "spawn", true); + Map.Objects.SpawnObject(animator); + } + } + + private void EndRun() + { + _aiComponent.ChangeState("wait"); + } + + private void InitThrowBomb() + { + _animator.Pause(); + _body.VelocityTarget = Vector2.Zero; + } + + private void ThrowBomb() + { + var handOffset = _animator.CurrentFrameIndex == 0 ? 8 : -8; + var spawnPosition = new Vector2(EntityPosition.X + handOffset, EntityPosition.Y); + var throwDirection = MapManager.ObjLink.EntityPosition.Position - spawnPosition; + var maxRange = 48f; + var mult = 1.5f; + if (throwDirection.Length() > maxRange) + { + throwDirection.Normalize(); + throwDirection *= mult; + } + else + throwDirection = (throwDirection / maxRange) * mult; + + // spawn a bomb + var bomb = new ObjBomb(Map, 0, 0, false, true); + bomb.EntityPosition.Set(new Vector3(spawnPosition.X, spawnPosition.Y, 20)); + bomb.Body.Velocity = new Vector3(throwDirection.X, throwDirection.Y, 1); + bomb.Body.Gravity = -0.2f; + bomb.Body.Bounciness = 0.25f; + bomb.Body.DragAir = 1.0f; + Map.Objects.SpawnObject(bomb); + + Game1.GameManager.PlaySoundEffect("D360-08-08"); + + // play throw animation + _animator.Play("throw_" + _animator.CurrentFrameIndex); + + _aiComponent.ChangeState("thrownBomb"); + } + + private void UpdateThrownBomb() + { + // finished throw animation? + if (!_animator.IsPlaying) + WalkOrRun(); + } + + private void OnDeath() + { + if (!string.IsNullOrEmpty(_saveKey)) + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + // stop the music + Game1.GameManager.SetMusic(-1, 2); + + Game1.GameManager.PlaySoundEffect("D378-26-1A"); + + // spawns a fairy + Game1.GameManager.PlaySoundEffect("D360-27-1B"); + Map.Objects.SpawnObject(new ObjDungeonFairy(Map, (int)EntityPosition.X, (int)EntityPosition.Y, 8)); + + Map.Objects.DeleteObjects.Add(this); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X, direction.Y, _body.Velocity.Z); + + return true; + } + + public Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_aiComponent.CurrentStateId == "idle") + return Values.HitCollision.None; + + if (_aiComponent.CurrentStateId == "throwBomb") + ThrowBomb(); + + // the boss will throw a bomb right after getting damaged + if (!_aiDamageState.IsInDamageState() && + _aiComponent.CurrentStateId != "deathBoss" && + _aiComponent.CurrentStateId != "preRun" && + _aiComponent.CurrentStateId != "run") + _aiComponent.ChangeState("throwBomb"); + + if (damageType == HitType.Bow || damageType == HitType.Bomb || damageType == HitType.MagicRod) + damage *= 2; + + if (damageType == HitType.Boomerang) + damage = 2; + + var hitCollision = _aiDamageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + + // stop walking and stop the animation when dead + if (_aiDamageState.CurrentLives <= 0) + { + RemoveComponent(HittableComponent.Index); + + _animator.Stop(); + _body.VelocityTarget = Vector2.Zero; + + // make sure to let the player go if he was grabbed + MapManager.ObjLink.EndGrab(); + } + + return hitCollision; + } + } +} diff --git a/InGame/GameObjects/MidBoss/MBossMasterStalfos.cs b/InGame/GameObjects/MidBoss/MBossMasterStalfos.cs new file mode 100644 index 0000000..b5b4a9b --- /dev/null +++ b/InGame/GameObjects/MidBoss/MBossMasterStalfos.cs @@ -0,0 +1,629 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + class MBossMasterStalfos : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly DamageFieldComponent _damageField; + private readonly AiDamageState _aiDamageState; + private readonly ShadowBodyDrawComponent _shadowComponent; + private readonly AiTriggerSwitch _damageCooldown; + + private SheetAnimator _animator; + + private CPosition[] _positions = new CPosition[5]; + private CSprite[] _sprites = new CSprite[5]; + private readonly CSprite _sprite; + + // quick fix: draw the swing behind the sword + private int[] _drawOrder = { 0, 1, 2, 4, 3 }; + + private const float MovementSpeed = 0.5f; + + private float[] DamageTime = { 0, 175, 75, 0 }; + private float[] _damageCounters = new float[4]; + private float[] _partVelocity = new float[4]; + private float[] _partOffset = { 0, 0, 3, 3 }; + private float _partGravity = 0.15f; + + private float[] _standCounters = new float[4]; + + private const int WobbleTime = 750; + private int _direction; + + private float _transparency; + private readonly string _saveKey; + + private readonly int _encounterNumber; + private string _encounterState; + private bool _shownIntroText; + + private bool _damageState; + private bool _flee; + private bool _attackSound; + + private const int FleeTime = 400; + + public MBossMasterStalfos() : base("ms_shield") { } + + public MBossMasterStalfos(Map.Map map, int posX, int posY, string saveKey, int encounterNumber) : base(map) + { + EntityPosition = new CPosition(posX + 16, posY + 32, 100); + EntitySize = new Rectangle(-24, -38, 48, 38); + + _saveKey = saveKey; + _encounterNumber = encounterNumber; + + _animator = new SheetAnimator(); + + var aniStandLeft = new SheetAnimation("stand-1", 0, + new AFrame(16, new ASprite(-15, -16), new ASprite(-14, -32, false, true), new ASprite(-24, -24), new ASprite(8, -37), null)); + var aniStandRight = new SheetAnimation("stand1", 0, + new AFrame(16, new ASprite(-15, -16), new ASprite(-13, -32), new ASprite(-16, -24), new ASprite(8, -40), null)); + var aniPreJumpLeft = new SheetAnimation("preJump-1", 0, + new AFrame(16, new ASprite(-15, -16), new ASprite(-14, -30, false, true), new ASprite(-24, -22), new ASprite(8, -35), null)); + var aniPreJumpRight = new SheetAnimation("preJump1", 0, + new AFrame(16, new ASprite(-15, -16), new ASprite(-13, -30), new ASprite(-16, -22), new ASprite(8, -38), null)); + var aniWalkLeft = new SheetAnimation("walk-1", -1, + new AFrame(16, new ASprite(-15, -16), new ASprite(-14, -32, false, true), new ASprite(-24, -24), new ASprite(8, -37), null), + new AFrame(16, new ASprite(-15, -16, false, true), new ASprite(-14, -32, false, true), new ASprite(-24, -24), new ASprite(8, -37), null)); + var aniWalkRight = new SheetAnimation("walk1", -1, + new AFrame(16, new ASprite(-15, -16), new ASprite(-13, -32), new ASprite(-16, -24), new ASprite(8, -40), null), + new AFrame(16, new ASprite(-15, -16, false, true), new ASprite(-13, -32), new ASprite(-16, -24), new ASprite(8, -40), null)); + var aniHitLeft = new SheetAnimation("hit-1", 0, + new AFrame(24, new ASprite(-15, -16, false, true), new ASprite(-14, -32, false, true), new ASprite(-24, -24), new ASprite(-16, -48), null), + new AFrame(8, new ASprite(-15, -16, false, true), new ASprite(-14, -32), new ASprite(-24, -32), null, new ASprite(-24, -24)), + new AFrame(8, new ASprite(-15, -16, false, true), new ASprite(-14, -32), new ASprite(-24, -36), new ASprite(8, -8, true), new ASprite(-24, -24)), + new AFrame(40, new ASprite(-15, -16, false, true), new ASprite(-14, -32), new ASprite(-24, -36), new ASprite(8, -8, true), null)); + var aniHitRight = new SheetAnimation("hit1", 0, + new AFrame(24, new ASprite(-15, -16), new ASprite(-13, -32), new ASprite(-16, -24), new ASprite(1, -56, false, true), null), + new AFrame(8, new ASprite(-15, -16), new ASprite(-14, -32, false, true), new ASprite(-24, -28), null, new ASprite(-8, -24, false, true)), + new AFrame(8, new ASprite(-15, -16), new ASprite(-14, -32, false, true), new ASprite(-24, -32), new ASprite(-15, -8, true, true), new ASprite(-8, -24, false, true)), + new AFrame(40, new ASprite(-15, -16), new ASprite(-14, -32, false, true), new ASprite(-24, -32), new ASprite(-15, -8, true, true), null)); + + _animator.Animations.Add(aniStandLeft); + _animator.Animations.Add(aniStandRight); + _animator.Animations.Add(aniPreJumpLeft); + _animator.Animations.Add(aniPreJumpRight); + _animator.Animations.Add(aniWalkLeft); + _animator.Animations.Add(aniWalkRight); + _animator.Animations.Add(aniHitLeft); + _animator.Animations.Add(aniHitRight); + + _animator.Play("standLeft"); + + for (var i = 0; i < _positions.Length; i++) + _positions[i] = new CPosition(0, 0, 0); + + // get all the sprites for the boss + _sprites[0] = new CSprite("ms_feet", _positions[0], Vector2.Zero); + _sprites[1] = new CSprite("ms_head", _positions[1], Vector2.Zero); + _sprites[2] = new CSprite("ms_shield", _positions[2], Vector2.Zero); + _sprites[3] = new CSprite("ms_sword", _positions[3], Vector2.Zero); + _sprites[4] = new CSprite("ms_swing", _positions[4], Vector2.Zero); + + var animationComponent = new AnimationSheetComponent(_animator); + + _body = new BodyComponent(EntityPosition, -14, -16, 28, 16, 8) + { + IgnoreHoles = true, + Gravity = -0.125f, + FieldRectangle = Map.GetField(posX, posY, 16), + IsActive = false + }; + + _aiComponent = new AiComponent(); + _aiComponent.Trigger.Add(_damageCooldown = new AiTriggerSwitch(500)); + + var stateHidden = new AiState(UpdateHidden); + var statePreFall = new AiState(); + statePreFall.Trigger.Add(new AiTriggerCountdown(500, null, () => _aiComponent.ChangeState("fall"))); + var stateFall = new AiState(UpdateFall) { Init = InitFall }; + var statePostFall = new AiState(); + statePostFall.Trigger.Add(new AiTriggerCountdown(500, null, () => _aiComponent.ChangeState("idle"))); + var stateIdle = new AiState { Init = InitIdle }; + stateIdle.Trigger.Add(new AiTriggerCountdown(100, null, EndIdle)); + var stateWalk = new AiState(UpdateWalking) { Init = InitWalk }; + stateWalk.Trigger.Add(new AiTriggerCountdown(1000, null, EndWalking)); + var statePreDamaged = new AiState(UpdatePreDamaged) { Init = InitPreDamageState }; + var stateDamaged = new AiState(UpdateDamaged) { Init = InitDamageState }; + stateDamaged.Trigger.Add(new AiTriggerCountdown(3000, null, () => _aiComponent.ChangeState("wobble"))); + var stateWobble = new AiState(); + stateWobble.Trigger.Add(new AiTriggerCountdown(WobbleTime, WobbleTick, WobbleEnd)); + var stateStandingUp = new AiState { Init = InitStandingUp }; + stateStandingUp.Trigger.Add(new AiTriggerCountdown(750, StandUpTick, StandUpEnd)); + var statePreJump = new AiState { Init = InitPreJump }; + statePreJump.Trigger.Add(new AiTriggerCountdown(500, null, () => _aiComponent.ChangeState("jump"))); + var stateJump = new AiState(UpdateJump) { Init = InitJump }; + var statePostJump = new AiState { Init = InitPostJump }; + statePostJump.Trigger.Add(new AiTriggerCountdown(300, null, () => _aiComponent.ChangeState("idle"))); + var stateAttack = new AiState(UpdateAttack) { Init = InitAttack }; + var statePreFlee = new AiState { Init = InitPreJump }; + statePreFlee.Trigger.Add(new AiTriggerCountdown(250, null, () => _aiComponent.ChangeState("flee"))); + var stateFlee = new AiState { Init = InitFlee }; + stateFlee.Trigger.Add(new AiTriggerCountdown(FleeTime, FleeTick, FleeEnd)); + + _aiComponent.States.Add("hidden", stateHidden); + _aiComponent.States.Add("preFall", statePreFall); + _aiComponent.States.Add("fall", stateFall); + _aiComponent.States.Add("postFall", statePostFall); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("walk", stateWalk); + _aiComponent.States.Add("preDamaged", statePreDamaged); + _aiComponent.States.Add("damaged", stateDamaged); + _aiComponent.States.Add("wobble", stateWobble); + _aiComponent.States.Add("standUp", stateStandingUp); + _aiComponent.States.Add("preJump", statePreJump); + _aiComponent.States.Add("jump", stateJump); + _aiComponent.States.Add("postJump", statePostJump); + _aiComponent.States.Add("attack", stateAttack); + _aiComponent.States.Add("preFlee", statePreFlee); + _aiComponent.States.Add("flee", stateFlee); + + // dummy sprite + _sprite = new CSprite(EntityPosition); + var lives = 6; + if (_encounterNumber == 1 || _encounterNumber == 2) + lives = 4; + + _aiDamageState = new AiDamageState(this, _body, _aiComponent, _sprite, lives, false, false) + { BossHitSound = true, HitMultiplierX = 3, HitMultiplierY = 3 }; + if (_encounterNumber != 3) + _aiDamageState.OnDeath = OnDeath; + else + _aiDamageState.AddBossDamageState(OnBossDeath); + _aiDamageState.ExplosionOffsetY = 8; + + _aiComponent.ChangeState("hidden"); + + var damageCollider = new CBox(EntityPosition, -14, -24, 0, 28, 24, 8); + var hittableBox = new CBox(EntityPosition, -12, -26, 0, 24, 24, 8); + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageCollider, HitType.Enemy, 4)); + AddComponent(PushableComponent.Index, new PushableComponent(damageCollider, OnPush)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + AddComponent(DrawShadowComponent.Index, _shadowComponent = new ShadowBodyDrawComponent(EntityPosition) { IsActive = false, ShadowWidth = 22, ShadowHeight = 6 }); + + if (!string.IsNullOrEmpty(_saveKey)) + { + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + + // spawn the hookshot if the player did not collect it after + var encounterState = Game1.GameManager.SaveManager.GetString(_saveKey); + if (encounterState == "4" && _encounterNumber == 3) + SpawnHookshot(); + } + + // TODO: need to find a way to draw shadow for this + //AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + } + + private void OnKeyChange() + { + _encounterState = Game1.GameManager.SaveManager.GetString(_saveKey); + if (_encounterState == null) + _encounterState = "0"; + } + + private void InitFlee() + { + Game1.GameManager.PlaySoundEffect("D378-62-3F"); + + _body.IsActive = false; + _animator.Play("stand" + _direction); + + // stop the music + Game1.GameManager.SetMusic(-1, 2); + } + + private void FleeTick(double counter) + { + var state = (float)(FleeTime - counter) / FleeTime; + EntityPosition.Z = MathF.Sin(state * MathF.PI * 0.4f) * 80; + _transparency = MathF.Min((1 - state) / 0.25f, 1); + _shadowComponent.Transparency = 1 - state; + } + + private void FleeEnd() + { + if (!string.IsNullOrEmpty(_saveKey)) + Game1.GameManager.SaveManager.SetString(_saveKey, (_encounterNumber + 1).ToString()); + + Map.Objects.DeleteObjects.Add(this); + } + + private void UpdateHidden() + { + // player entered the room? => fall down + if (_encounterState == _encounterNumber.ToString() && + _body.FieldRectangle.Contains(MapManager.ObjLink.BodyRectangle)) + { + Game1.GameManager.SetMusic(79, 2); + _aiComponent.ChangeState("preFall"); + } + } + + private void InitFall() + { + Game1.GameManager.PlaySoundEffect("D360-08-08"); + + _animator.Play("stand1"); + _shadowComponent.IsActive = true; + _body.IsActive = true; + } + + private void UpdateFall() + { + _transparency = MathF.Min((100 - EntityPosition.Z) / 10f, 1); + + if (_body.IsGrounded) + { + _animator.Play("preJump1"); + _aiComponent.ChangeState("postFall"); + } + } + + private void InitAttack() + { + _attackSound = false; + _body.VelocityTarget = Vector2.Zero; + _animator.Play("hit" + _direction); + } + + private void UpdateAttack() + { + if (_animator.CurrentFrameIndex == 1 || _animator.CurrentFrameIndex == 2) + { + if (!_attackSound) + { + _attackSound = true; + Game1.GameManager.PlaySoundEffect("D378-39-27"); + } + + // attack the player + var damageBox = new Box(EntityPosition.X - 16 + (_direction == -1 ? -6 : 6), EntityPosition.Y - 22, 0, 32, 38, 8); + if (damageBox.Intersects(MapManager.ObjLink._body.BodyBox.Box)) + { + var direction = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (direction != Vector2.Zero) + direction.Normalize(); + + MapManager.ObjLink.HitPlayer(direction * 2.5f, HitType.Boss, 4, false); + } + } + + // finished attacking + if (!_animator.IsPlaying) + _aiComponent.ChangeState("idle"); + } + + private void InitIdle() + { + _body.VelocityTarget = Vector2.Zero; + // look at the player + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + _direction = playerDirection.X < 0 ? -1 : 1; + _animator.Play("stand" + _direction); + } + + private void EndIdle() + { + if (_flee) + { + Game1.GameManager.StartDialogPath("master_stalfos_0"); + _aiComponent.ChangeState("preFlee"); + return; + } + + if (_encounterNumber > 0 && !_shownIntroText) + { + _shownIntroText = true; + Game1.GameManager.StartDialogPath(_encounterNumber == 3 ? "master_stalfos_2" : "master_stalfos_1"); + } + + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + + // player is standing in front of the boss? => attack + if (Math.Abs(playerDirection.X) < 24 && 0 < playerDirection.Y && playerDirection.Y < 18) + _aiComponent.ChangeState("attack"); + else if (Math.Abs(playerDirection.X) < 28 && 0 < playerDirection.Y && playerDirection.Y < 48) + _aiComponent.ChangeState("walk"); + else + _aiComponent.ChangeState("preJump"); + } + + private void InitPreJump() + { + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + _direction = playerDirection.X < 0 ? -1 : 1; + _animator.Play("preJump" + _direction); + } + + private void InitJump() + { + Game1.GameManager.PlaySoundEffect("D360-36-24"); + + _animator.Play("stand" + _direction); + + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDirection != Vector2.Zero) + { + // try to jump at a spot where the player can be easily hit + if (playerDirection.Y < 0) + playerDirection.Y *= 2; + + playerDirection.Normalize(); + _body.VelocityTarget = playerDirection * 1.5f; + _body.Velocity.Z = 3; + } + } + + private void UpdateJump() + { + // reached the ground + if (_body.IsGrounded && _body.Velocity.Z <= 0) + { + _aiComponent.ChangeState("postJump"); + _body.VelocityTarget = Vector2.Zero; + } + } + + private void InitPostJump() + { + _animator.Play("preJump" + _direction); + } + + private void InitWalk() + { + // look at the player while moving + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + _direction = playerDirection.X < 0 ? -1 : 1; + _animator.Play("walk" + _direction); + + // move towards the player + if (playerDirection != Vector2.Zero) + { + playerDirection.Normalize(); + _body.VelocityTarget = playerDirection * MovementSpeed; + } + } + + private void UpdateWalking() + { + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + + // attack if we are close enough + if (Math.Abs(playerDirection.X) < 24 && 0 < playerDirection.Y && playerDirection.Y < 18) + _aiComponent.ChangeState("attack"); + } + + private void EndWalking() + { + _aiComponent.ChangeState("idle"); + } + + private void InitPreDamageState() + { + _body.Velocity = Vector3.Zero; + _body.VelocityTarget = Vector2.Zero; + } + + private void UpdatePreDamaged() + { + if (_body.IsGrounded && + !_aiDamageState.IsInDamageState() && + _body.Velocity.Length() < 0.1f) + _aiComponent.ChangeState("damaged"); + } + + private void InitDamageState() + { + _body.Velocity = Vector3.Zero; + _body.VelocityTarget = Vector2.Zero; + + _damageField.IsActive = false; + + Game1.GameManager.PlaySoundEffect("D360-40-28"); + + for (var i = 0; i < _partVelocity.Length; i++) + { + _damageCounters[i] = DamageTime[i]; + _partVelocity[i] = 0; + } + } + + private void UpdateDamaged() + { + _damageState = true; + + for (var i = 1; i < _partVelocity.Length; i++) + { + _damageCounters[i] -= Game1.DeltaTime; + + // fall onto the ground + if (_damageCounters[i] < 0) + { + _partVelocity[i] += _partGravity * Game1.TimeMultiplier; + var velocityOffset = _partVelocity[i] * Game1.TimeMultiplier; + + if (_positions[i].Z - velocityOffset > _sprites[i].SourceRectangle.Height - _partOffset[i]) + _positions[i].Z -= velocityOffset; + else + _positions[i].Z = _sprites[i].SourceRectangle.Height - _partOffset[i]; + } + } + } + + private void WobbleTick(double counter) + { + // move the upper body up and down + // 4 frames to go up/down + _positions[1].Z = _sprites[1].SourceRectangle.Height + 1 - + MathF.Sin(MathF.PI / 2 + MathF.PI * ((WobbleTime - (float)counter) / 1000 * (60 / 4f))); + } + + private void WobbleEnd() + { + _aiComponent.ChangeState("standUp"); + } + + private void InitStandingUp() + { + for (var i = 0; i < _partVelocity.Length; i++) + { + _standCounters[i] = DamageTime[i]; + } + } + + private void StandUpTick(double counter) + { + for (var i = 0; i < _partVelocity.Length; i++) + { + _standCounters[i] -= Game1.DeltaTime; + + if (_standCounters[i] < 0) + { + var speed = 0.5f * Game1.TimeMultiplier; + if (_positions[i].Z + speed < -_animator.CurrentFrame.Sprites[i].Offset.Y) + _positions[i].Z += speed; + else + _positions[i].Z = -_animator.CurrentFrame.Sprites[i].Offset.Y; + } + } + } + + private void StandUpEnd() + { + _damageCooldown.Reset(); + _damageField.IsActive = true; + _damageState = false; + _aiComponent.ChangeState("idle"); + } + + private void OnDeath(bool pieceOfPower) + { + _flee = true; + _damageField.IsActive = false; + } + + private void OnBossDeath() + { + if (!string.IsNullOrEmpty(_saveKey)) + Game1.GameManager.SaveManager.SetString(_saveKey, (_encounterNumber + 1).ToString()); + + // stop the music + Game1.GameManager.SetMusic(-1, 2); + + SpawnHookshot(); + + Map.Objects.DeleteObjects.Add(this); + } + + private void SpawnHookshot() + { + var objItem = new ObjItem(Map, (int)EntityPosition.X - 8, (int)EntityPosition.Y - 16, "j", "hookshot_collected", "hookshot", null); + Map.Objects.SpawnObject(objItem); + } + + private void Draw(SpriteBatch spriteBatch) + { + // change the draw effect + if (_sprite.SpriteShader != null) + { + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, _sprite.SpriteShader); + } + + // do not draw the legs if the upper part is laying on the floor + _sprites[0].IsVisible = _sprites[1].SourceRectangle.Height + 2 < _positions[1].Z; + + for (var i = 0; i < _positions.Length; i++) + { + var spriteIndex = _drawOrder[i]; + + if (_animator.CurrentFrame.Sprites[spriteIndex] == null) + continue; + + _positions[spriteIndex].X = EntityPosition.X + _animator.CurrentFrame.Sprites[spriteIndex].Offset.X; + _positions[spriteIndex].Y = EntityPosition.Y; + + // only update the animation if the boss is not in the damaged state + if (!_damageState) + { + _positions[spriteIndex].Z = EntityPosition.Z - _animator.CurrentFrame.Sprites[spriteIndex].Offset.Y; + + _sprites[spriteIndex].SpriteEffect = (_animator.CurrentFrame.Sprites[spriteIndex].MirroredV ? SpriteEffects.FlipVertically : 0) | + (_animator.CurrentFrame.Sprites[spriteIndex].MirroredH ? SpriteEffects.FlipHorizontally : 0); + + } + + _sprites[spriteIndex].Color = Color.White * _transparency; + _sprites[spriteIndex].Draw(spriteBatch); + } + + // change the draw effect + if (_sprite.SpriteShader != null) + { + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, null); + } + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (!_damageField.IsActive) + return false; + + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X, direction.Y, _body.Velocity.Z); + + return true; + } + + public Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_aiDamageState.CurrentLives <= 0 || _aiDamageState.IsInDamageState()) + return Values.HitCollision.None; + + // switch to the damaged state + if (_damageCooldown.State && + _aiComponent.CurrentStateId != "preDamaged" && _aiComponent.CurrentStateId != "damaged" && + _aiComponent.CurrentStateId != "attack" && _aiComponent.CurrentStateId != "wobble" && _aiComponent.CurrentStateId != "standUp") + { + _aiComponent.ChangeState("preDamaged"); + _aiDamageState.OnHit(gameObject, direction, damageType, 0, pieceOfPower); + return Values.HitCollision.Repelling; + } + + if (_body.Velocity.Length() < 0.01f) + { + _body.Velocity.X = direction.X; + _body.Velocity.Y = direction.Y; + } + + // can only be damaged while lying on the floor while being hit by a bomb + if ((_aiComponent.CurrentStateId == "damaged" || _aiComponent.CurrentStateId == "wobble") && damageType == HitType.Bomb) + { + _aiDamageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + } + + return Values.HitCollision.RepellingParticle; + } + + } +} diff --git a/InGame/GameObjects/MidBoss/MBossRollingBones.cs b/InGame/GameObjects/MidBoss/MBossRollingBones.cs new file mode 100644 index 0000000..5924844 --- /dev/null +++ b/InGame/GameObjects/MidBoss/MBossRollingBones.cs @@ -0,0 +1,304 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Dungeon; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + internal class MBossRollingBones : GameObject + { + private readonly MBossBone _bone; + + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _damageState; + private readonly CSprite _sprite; + private readonly Animator _animator; + + private readonly string _triggerKey; + private readonly string _saveKey; + + private const float MoveSpeed = 1.2f; + private const int Lives = 8; + + private Vector2 _moveDirection; + + private float _roomMiddle; + private float _deathCount; + private float _burstCounter; + private int _jumpCount; + + public MBossRollingBones() : base("rolling bones") { } + + public MBossRollingBones(Map.Map map, int posX, int posY, string triggerKey, string saveKey) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-12, -30, 24, 32); + + _triggerKey = triggerKey; + _saveKey = saveKey; + + if (!string.IsNullOrEmpty(_saveKey) && + Game1.GameManager.SaveManager.GetString(_saveKey) == "1") + { + IsDead = true; + return; + } + + _animator = AnimatorSaveLoad.LoadAnimator("MidBoss/mbossOneBoss"); + _animator.Play("walk"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-10, -23)); + + _body = new BodyComponent(EntityPosition, -9, -12, 18, 12, 8) + { + Drag = 0.65f, + DragAir = 0.75f, + Gravity = -0.15f, + MoveCollision = OnMoveCollision, + FieldRectangle = map.GetField(posX, posY) + }; + _roomMiddle = _body.FieldRectangle.Center.Y + 4; + + var stateWaiting = new AiState(); + var stateInitJump = new AiState(UpdateInitJump); + var stateIdle = new AiState(UpdateIdle); + stateIdle.Trigger.Add(new AiTriggerCountdown(300, null, () => _aiComponent.ChangeState("jumping"))); + var stateJumping = new AiState(UpdateJumping) { Init = InitJump }; + var statePushing = new AiState(); + statePushing.Trigger.Add(new AiTriggerCountdown(500, null, ToPushed)); + var statePushed = new AiState(UpdatePushed); + var stateBlink = new AiState(); + stateBlink.Trigger.Add(new AiTriggerCountdown(1000, UpdateBlink, () => _aiComponent.ChangeState("death"))); + var stateDeath = new AiState(UpdateDeath); + stateDeath.Trigger.Add(new AiTriggerCountdown(2000, UpdateBlink, RemoveObject)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("waiting", stateWaiting); + _aiComponent.States.Add("initJump", stateInitJump); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("jumping", stateJumping); + _aiComponent.States.Add("pushing", statePushing); + _aiComponent.States.Add("pushed", statePushed); + _aiComponent.States.Add("blink", stateBlink); + _aiComponent.States.Add("death", stateDeath); + _damageState = new AiDamageState(this, _body, _aiComponent, _sprite, Lives, false, false) { OnDeath = OnDeath }; + _aiComponent.ChangeState("waiting"); + + var damageCollider = new CBox(EntityPosition, -7, -11, 0, 14, 11, 8, true); + var hittableBox = new CBox(EntityPosition, -8, -14, 0, 16, 14, 8, true); + + if (!string.IsNullOrEmpty(_triggerKey)) + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 4)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _sprite) { ShadowWidth = 16, ShadowHeight = 6 }); + + // check if we are on the left or the right side of the room + int boneOffset = 0; + if (posX > _body.FieldRectangle.X + Values.FieldWidth / 2) + { + _moveDirection.X = -MoveSpeed; + _animator.Play("idle_0"); + boneOffset = 80; + } + else + { + _moveDirection.X = MoveSpeed; + _animator.Play("idle_1"); + boneOffset = 32; + } + + _bone = new MBossBone(map, posX, posY, boneOffset); + map.Objects.SpawnObject(_bone); + } + + private void OnMoveCollision(Values.BodyCollision collision) + { + if ((collision & Values.BodyCollision.Floor) != 0) + { + Game1.GameManager.PlaySoundEffect("D360-32-20"); + } + } + + private void KeyChanged() + { + // activate the boss after entering the room + if (_aiComponent.CurrentStateId == "waiting" && Game1.GameManager.SaveManager.GetString(_triggerKey) == "1") + { + // start boss music + Game1.GameManager.SetMusic(79, 2); + + _aiComponent.ChangeState("initJump"); + } + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + { + _body.Velocity.X += direction.X * 0.35f; + _body.Velocity.Y += direction.Y * 0.35f; + } + + return true; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_damageState.IsInDamageState() || _aiComponent.CurrentStateId == "death") + return Values.HitCollision.None; + + if (damageType == HitType.Bomb || damageType == HitType.Bow || damageType == HitType.MagicRod) + damage *= 2; + + // different drag than needed for the jumps + _body.DragAir = 0.75f; + + return _damageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + } + + private void UpdateIdle() + { + _animator.Play("idle_" + (_moveDirection.X < 0 ? 0 : 1)); + } + + private void InitJump() + { + // jump to the top or to the bottom? + if (EntityPosition.Y > _roomMiddle) + _moveDirection.Y = -0.5f; + else + _moveDirection.Y = 0.5f; + + _body.DragAir = 1.0f; + _body.Velocity = new Vector3(_moveDirection.X, _moveDirection.Y, 2); + _body.IsGrounded = false; + + _animator.Play("jump_" + (_moveDirection.X < 0 ? 0 : 1)); + } + + private void UpdateInitJump() + { + if (_body.IsGrounded) + { + if (_jumpCount < 3) + { + _jumpCount++; + + if (EntityPosition.Y > _roomMiddle) + _moveDirection.Y = -0.5f; + else + _moveDirection.Y = 0.5f; + + _body.DragAir = 1.0f; + _body.Velocity = new Vector3(_moveDirection.X * 0.375f, _moveDirection.Y * 0.375f, 1.0f); + _body.IsGrounded = false; + } + else + { + _aiComponent.ChangeState("pushing"); + } + } + } + + private void UpdateJumping() + { + // landed after a jump? + if (_body.IsGrounded) + { + if ((_body.LastVelocityCollision & Values.BodyCollision.Horizontal) != 0 && + Math.Sign(_body.Velocity.X) == Math.Sign(_moveDirection.X)) + { + _aiComponent.ChangeState("pushing"); + _moveDirection.X = -_moveDirection.X; + _body.Velocity.X = -_body.Velocity.X * 0.125f; + _animator.Play("idle_" + (_moveDirection.X < 0 ? 0 : 1)); + return; + } + + _aiComponent.ChangeState("idle"); + } + } + + private void ToPushed() + { + // push the bar + _bone.Push(_moveDirection.X < 0 ? 0 : 1); + + _animator.Play("push_" + (_moveDirection.X < 0 ? 0 : 1)); + _aiComponent.ChangeState("pushed"); + } + + private void UpdatePushed() + { + // finished pushing + if (!_animator.IsPlaying) + _aiComponent.ChangeState("idle"); + } + + private void UpdateBlink(double time) + { + _sprite.SpriteShader = time % 133 < 66 ? Resources.DamageSpriteShader0 : null; + } + + private void UpdateDeath() + { + _burstCounter -= Game1.DeltaTime; + if (_burstCounter < 0) + { + _burstCounter += 150; + Game1.GameManager.PlaySoundEffect("D378-19-13"); + } + + _deathCount += Game1.DeltaTime; + if (_deathCount > 100) + _deathCount -= 100; + else + return; + + var posX = (int)EntityPosition.X + Game1.RandomNumber.Next(0, 32) - 8 - 16; + var posY = (int)EntityPosition.Y - (int)EntityPosition.Z + Game1.RandomNumber.Next(0, 32) - 16 - 16; + + // spawn explosion effect + Map.Objects.SpawnObject(new ObjAnimator(Map, posX, posY, Values.LayerBottom, "Particles/spawn", "run", true)); + } + + private void RemoveObject() + { + if (!string.IsNullOrEmpty(_saveKey)) + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + // stop boss music + Game1.GameManager.SetMusic(-1, 2); + + Game1.GameManager.PlaySoundEffect("D360-27-1B"); + Map.Objects.SpawnObject(new ObjDungeonFairy(Map, (int)EntityPosition.X, (int)EntityPosition.Y, 8)); + + Map.Objects.DeleteObjects.Add(this); + _bone.Delete(); + } + + private void OnDeath(bool pieceOfPower) + { + Game1.GameManager.PlaySoundEffect("D370-16-10"); + + _aiComponent.ChangeState("blink"); + _damageState.IsActive = false; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/MidBoss/MBossSmasher.cs b/InGame/GameObjects/MidBoss/MBossSmasher.cs new file mode 100644 index 0000000..bf5b208 --- /dev/null +++ b/InGame/GameObjects/MidBoss/MBossSmasher.cs @@ -0,0 +1,403 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Dungeon; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using ProjectZ.Base; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + internal class MBossSmasher : GameObject + { + private MBossSmasherBall _ball; + + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _damageState; + private readonly Animator _animator; + private readonly CubicBezier _pickupCurveX; + private readonly CubicBezier _pickupCurveY; + + private readonly RectangleF _triggerRectangle; + private Vector2 _moveDirection; + + private readonly string _saveKey; + + private Vector2 _jumpDirection; + private Vector2 _pickupStart; + private const int PickupTime = 500; + + private const float WalkSpeed = 0.75f; + private const float CarrySpeed = 0.25f; + + private int _direction; + private int _jumpCount; + + public MBossSmasher(Map.Map map, int posX, int posY, string saveKey) : base(map, "smasher") + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-12, -24, 24, 24); + + _saveKey = saveKey; + + if (!string.IsNullOrEmpty(_saveKey) && + Game1.GameManager.SaveManager.GetString(_saveKey) == "1") + { + IsDead = true; + return; + } + + EntityPosition.AddPositionListener(typeof(MBossSmasher), OnPositionChange); + + _pickupCurveX = new CubicBezier(100, new Vector2(0.6f, 0.8f), new Vector2(0.7f, 1)); + _pickupCurveY = new CubicBezier(100, new Vector2(0.15f, 0.55f), new Vector2(0.15f, 1)); + + _triggerRectangle = Map.GetField(posX, posY, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("MidBoss/smasher"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(0, 0)); + + _body = new BodyComponent(EntityPosition, -9, -12, 18, 12, 8) + { + MoveCollision = OnCollision, + Drag = 0.65f, + DragAir = 0.75f, + Gravity = -0.125f, + FieldRectangle = map.GetField(posX, posY) + }; + + var stateWaiting = new AiState(UpdateWaiting) { Init = InitWaiting }; + var stateWalk = new AiState(UpdateWalk) { Init = InitWalk }; + var statePickup = new AiState { Init = InitPickup }; + statePickup.Trigger.Add(new AiTriggerCountdown(PickupTime, TickPickup, PickupEnd)); + var stateCarry = new AiState(UpdateCarry) { Init = InitCarrying }; + var statePostThrow = new AiState(); + statePostThrow.Trigger.Add(new AiTriggerCountdown(550, null, () => _aiComponent.ChangeState("walk"))); + + _aiComponent = new AiComponent(); + _aiComponent.Trigger.Add(new AiTriggerUpdate(Update)); + + _aiComponent.States.Add("waiting", stateWaiting); + _aiComponent.States.Add("walk", stateWalk); + _aiComponent.States.Add("pickup", statePickup); + _aiComponent.States.Add("carry", stateCarry); + _aiComponent.States.Add("postThrow", statePostThrow); + _damageState = new AiDamageState(this, _body, _aiComponent, sprite, 8) { BossHitSound = true, ExplosionOffsetY = 6, OnLiveZeroed = OnLiveZeroed }; + _damageState.AddBossDamageState(RemoveObject); + + _aiComponent.ChangeState("waiting"); + + var damageCollider = new CBox(EntityPosition, -7, -11, 0, 14, 11, 14, true); + var hittableBox = new CBox(EntityPosition, -9, -14, 0, 18, 14, 16, true); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 4)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite) { ShadowWidth = 18, ShadowHeight = 6 }); + + _moveDirection = new Vector2(-1.2f, 0); + _animator.Play("idle_0"); + + _ball = new MBossSmasherBall(map, new Vector2(EntityPosition.X + 56, EntityPosition.Y + 16)); + map.Objects.SpawnObject(_ball); + } + + private void Update() + { + // player left? + if (!_triggerRectangle.Contains(MapManager.ObjLink.BodyRectangle) && + _aiComponent.CurrentStateId == "walk" && _body.IsGrounded) + { + _aiComponent.ChangeState("waiting"); + + // stop boss music + Game1.GameManager.SetMusic(-1, 2); + } + } + + private void InitWaiting() + { + _body.VelocityTarget = Vector2.Zero; + } + + private void UpdateWaiting() + { + // awake if the player enters the room + if (_triggerRectangle.Contains(MapManager.ObjLink.BodyRectangle)) + StartMoving(); + } + + private void StartMoving() + { + _aiComponent.ChangeState("walk"); + + // start boss music + Game1.GameManager.SetMusic(79, 2); + } + + private void InitPickup() + { + if (!_ball.InitPickup()) + { + _aiComponent.ChangeState("walk"); + return; + } + + Game1.GameManager.PlaySoundEffect("D370-28-1C"); + + _pickupStart = new Vector2(_ball.EntityPosition.Position.X, EntityPosition.Y - _ball.EntityPosition.Position.Y); + _direction = _ball.EntityPosition.Position.X < EntityPosition.X ? 0 : 1; + _animator.Play("up_" + _direction); + } + + private void TickPickup(double countdownState) + { + var ballTargetPosition = new Vector2(EntityPosition.X, 15); + + // the ball gets picked up in a curved way + var percentage = (float)((PickupTime - countdownState) / PickupTime); + var percentageX = _pickupCurveX.EvaluateX(percentage); + var percentageY = _pickupCurveY.EvaluateX(percentage); + var newBallPosition = new Vector2( + MathHelper.Lerp(_pickupStart.X, ballTargetPosition.X, percentageX), + MathHelper.Lerp(_pickupStart.Y, ballTargetPosition.Y, percentageY)); + + _ball.EntityPosition.Set(new Vector3(newBallPosition.X, EntityPosition.Y + 1, newBallPosition.Y)); + } + + private void PickupEnd() + { + _ball.EntityPosition.Set(new Vector3(EntityPosition.X, EntityPosition.Y + 1, 15)); + _aiComponent.ChangeState("carry"); + } + + private void InitWalk() + { + _jumpCount = 0; + } + + private void UpdateWalk() + { + if (_body.Velocity.Z < 0) + _animator.Play("idle_" + _direction); + + if (_body.IsGrounded) + { + // jump towards the ball if the player is not already carrying it + if (_ball.IsAvailable()) + JumpTowardsBall(); + else + JumpRandom(); + } + } + + private void JumpRandom() + { + // change direction? + if (_jumpCount <= 0) + { + _jumpCount = Game1.RandomNumber.Next(2, 3); + var dirX = Game1.RandomNumber.Next(0, 2) * 2 - 1; + var dirY = Game1.RandomNumber.Next(0, 2) * 2 - 1; + _jumpDirection = new Vector2(dirX, dirY * 0.5f); + } + + Jump(_jumpDirection, "up_"); + _jumpCount--; + } + + private void JumpTowardsBall() + { + // jump toward the ball or pick him up if we are close enough + var targetPosition = new Vector2(_ball.EntityPosition.X, _ball.EntityPosition.Y); + if (EntityPosition.Position.X < _ball.EntityPosition.X) + { + // need to make sure that the target position is not inside the wall where the boss can not reach it + var offset = Math.Clamp(14 + _body.Width / 2 - (_ball.EntityPosition.X - (_body.FieldRectangle.X + 16)), 0, 32); + targetPosition.X -= 14 - offset; + } + else + { + // need to make sure that the target position is not inside the wall where the boss can not reach it + var offset = Math.Clamp(14 + _body.Width / 2 - ((_body.FieldRectangle.Right - 16) - _ball.EntityPosition.X), 0, 32); + targetPosition.X += 14 - offset; + } + + var ballDirection = targetPosition - EntityPosition.Position; + + if (ballDirection.Length() > 5) + { + ballDirection.Normalize(); + Jump(ballDirection, "idle_"); + } + else + { + _aiComponent.ChangeState("pickup"); + _body.VelocityTarget = Vector2.Zero; + } + } + + private void Jump(Vector2 direction, string animationName) + { + _direction = direction.X < 0 ? 0 : 1; + _animator.Play(animationName + _direction); + + _body.VelocityTarget = direction * WalkSpeed; + _body.Velocity = new Vector3(0, 0, 0.8f); + } + + private void OnPositionChange(CPosition newPosition) + { + if (_aiComponent.CurrentStateId != "carry") + return; + + // set the position of the ball if it is carried + _ball.EntityPosition.Set(new Vector3(newPosition.X, newPosition.Y + 1, newPosition.Z + 15)); + } + + private void InitCarrying() + { + _jumpCount = 0; + } + + private void UpdateCarry() + { + // start throwing + if (_jumpCount > 2 && _body.Velocity.Z < 0) + { + ThrowBall(); + return; + } + + if (_body.IsGrounded) + { + _jumpCount++; + + // jump toward the player + var ballDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + + if (ballDirection.Length() > 5) + { + ballDirection.Normalize(); + _direction = ballDirection.X < 0 ? 0 : 1; + _animator.Play("up_" + _direction); + + _body.VelocityTarget = ballDirection * CarrySpeed; + _body.Velocity = new Vector3(0, 0, 0.8f); + } + } + } + + private void ThrowBall() + { + _aiComponent.ChangeState("postThrow"); + + Game1.GameManager.PlaySoundEffect("D360-08-08"); + + _animator.Play("idle_" + _direction); + _body.Velocity = new Vector3(0, 0, 1.75f); + + // throw towards the player; scale the throw speed depending on the distance of the player + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + var playerDistance = playerDirection.Length(); + if (playerDistance > 0) + playerDirection.Normalize(); + playerDirection *= Math.Clamp(playerDistance / 24, 0, 2.5f); + + var throwDirection = new Vector3(playerDirection, 1.5f); + _ball.Throw(throwDirection); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X, direction.Y, _body.Velocity.Z); + + return true; + } + + public Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_damageState.IsInDamageState()) + return Values.HitCollision.None; + + if (_aiComponent.CurrentStateId == "carry") + { + _ball.EndPickup(); + _animator.Play("idle_" + _direction); + _aiComponent.ChangeState("walk"); + } + + // ball was thrown at the boss + if ((damageType & HitType.ThrownObject) != 0) + { + _damageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + _body.VelocityTarget = Vector2.Zero; + } + // only knock the boss back + else if (_aiComponent.CurrentStateId != "pickup") + { + _damageState.HitKnockBack(gameObject, direction, damageType, pieceOfPower, false); + } + + return Values.HitCollision.RepellingParticle; + } + + private void OnCollision(Values.BodyCollision direction) + { + if (_aiComponent.CurrentStateId == "jumping" && (direction & Values.BodyCollision.Horizontal) != 0 && + Math.Sign(_body.Velocity.X) == Math.Sign(_moveDirection.X)) + { + _aiComponent.ChangeState("pushing"); + _moveDirection.X = -_moveDirection.X; + _body.Velocity.X = -_body.Velocity.X * 0.125f; + _animator.Play("idle_" + (_moveDirection.X < 0 ? 0 : 1)); + } + + // landed after a jump? + if ((direction & Values.BodyCollision.Floor) != 0) + { + if (_aiComponent.CurrentStateId == "jumping") + _aiComponent.ChangeState("idle"); + } + } + + private void OnLiveZeroed() + { + // destroy the ball + if (_ball != null) + { + _ball.Destroy(); + _ball = null; + } + } + + private void RemoveObject() + { + if (!string.IsNullOrEmpty(_saveKey)) + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + // stop boss music + Game1.GameManager.SetMusic(-1, 2); + + // spawns a fairy + Game1.GameManager.PlaySoundEffect("D360-27-1B"); + Map.Objects.SpawnObject(new ObjDungeonFairy(Map, (int)EntityPosition.X, (int)EntityPosition.Y, 8)); + + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/MidBoss/MBossSmasherBall.cs b/InGame/GameObjects/MidBoss/MBossSmasherBall.cs new file mode 100644 index 0000000..8d7c983 --- /dev/null +++ b/InGame/GameObjects/MidBoss/MBossSmasherBall.cs @@ -0,0 +1,190 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + internal class MBossSmasherBall : GameObject + { + private readonly DamageFieldComponent _damageField; + private readonly CarriableComponent _carriableComponent; + private readonly BodyComponent _body; + private readonly CBox _damageBox; + private readonly RectangleF _fieldRectangle; + + private bool _isPickedUp; + private bool _hitEnemies; + + public MBossSmasherBall(Map.Map map, Vector2 position) : base(map) + { + EntityPosition = new CPosition(position.X, position.Y, 0); + EntitySize = new Rectangle(-8, -32, 16, 32); + + // this is the same size as the player so that it can not get thrown into the wall + _body = new BodyComponent(EntityPosition, -4, -10, 8, 10, 14) + { + CollisionTypes = Values.CollisionTypes.Normal | Values.CollisionTypes.NPCWall, + MoveCollision = Collision, + DragAir = 1.0f, + Gravity = -0.125f, + FieldRectangle = map.GetField((int)position.X, (int)position.Y, 12) + }; + + _fieldRectangle = _body.FieldRectangle; + + var cSprite = new CSprite("smasher_ball", EntityPosition, new Vector2(-8, -15)); + + var bodyBox = new CBox(EntityPosition, -7, -12, 14, 11, 14); + _damageBox = new CBox(EntityPosition, -7, -14, 0, 14, 14, 14, true); + _damageBox = new CBox(EntityPosition, -2, -2, 0, 2, 2, 2, true); + + AddComponent(BodyComponent.Index, _body); + AddComponent(CarriableComponent.Index, _carriableComponent = new CarriableComponent(new CRectangle(EntityPosition, new Rectangle(-7, -14, 14, 14)), CarryInit, CarryUpdate, CarryThrow)); + AddComponent(PushableComponent.Index, new PushableComponent(bodyBox, OnPush)); + AddComponent(HittableComponent.Index, new HittableComponent(bodyBox, OnHit)); + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(_damageBox, HitType.ThrownObject, 4) { IsActive = false }); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(cSprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, cSprite) { ShadowWidth = 12, ShadowHeight = 6 }); + } + + public void Destroy() + { + // spawn explosion + var animation = new ObjAnimator(Map, 0, 0, Values.LayerTop, "Particles/explosion0", "runc", true); + animation.EntityPosition.Set(new Vector2(EntityPosition.X, EntityPosition.Y - EntityPosition.Z - 8)); + Map.Objects.SpawnObject(animation); + + Map.Objects.DeleteObjects.Add(this); + } + + private void Update() + { + if (_hitEnemies) + { + var collision = Map.Objects.Hit(this, EntityPosition.Position, _damageBox.Box, HitType.ThrownObject, 2, false); + if (collision != Values.HitCollision.None) + { + _body.Velocity.X = -_body.Velocity.X * 0.45f; + _body.Velocity.Y = -_body.Velocity.Y * 0.45f; + } + } + } + + /// + /// Returns if the ball can be picket up by the boss. This is the case if it is laying on the ground and the player is not holding it. + /// + /// + public bool IsAvailable() + { + return !_isPickedUp && _body.IsGrounded; + } + + /// + /// Init Pickup by the boss + /// + /// + public bool InitPickup() + { + if (_isPickedUp) + return false; + + _carriableComponent.IsActive = false; + _damageField.IsActive = true; + _body.IgnoresZ = true; + return true; + } + + public void EndPickup() + { + _body.IgnoresZ = false; + _body.Velocity = Vector3.Zero; + + _carriableComponent.IsActive = true; + } + + public void Throw(Vector3 direction) + { + // make sure to not get over walls + _body.IsGrounded = false; + _body.JumpStartHeight = 0; + _body.IgnoresZ = false; + _body.Velocity = direction; + + _carriableComponent.IsActive = true; + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + // do not get hit by itself + if (originObject == this) + return Values.HitCollision.None; + + return Values.HitCollision.RepellingParticle; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType pushType) + { + if (pushType == PushableComponent.PushType.Impact) + return true; + + return false; + } + + private Vector3 CarryInit() + { + // the ball was picked up + _isPickedUp = true; + _body.IsActive = false; + + return new Vector3(EntityPosition.X, EntityPosition.Y, EntityPosition.Z); + } + + private bool CarryUpdate(Vector3 newPosition) + { + // if the player tries to move the ball out of the field it will just fall down + if (!_fieldRectangle.Contains(new Vector2(newPosition.X, newPosition.Y))) + return false; + + EntityPosition.Set(new Vector3(newPosition.X, newPosition.Y, newPosition.Z)); + return true; + } + + private void CarryThrow(Vector2 velocity) + { + Release(); + _body.Velocity = new Vector3(velocity.X, velocity.Y, 0) * 1.0f; + _hitEnemies = true; + } + + private void Release() + { + _isPickedUp = false; + // @HACK: we need to make sure that the boss is not walking into walls + _body.JumpStartHeight = 0; + _body.IsGrounded = false; + _body.IsActive = true; + } + + private void Collision(Values.BodyCollision direction) + { + if ((direction & Values.BodyCollision.Floor) != 0) + { + Game1.GameManager.PlaySoundEffect("D360-09-09"); + + // stop hitting the player/boss when the ball touches the ground + _damageField.IsActive = false; + _hitEnemies = false; + } + + if ((direction & Values.BodyCollision.Horizontal) != 0) + _body.Velocity.X = -_body.Velocity.X * 0.65f; + if ((direction & Values.BodyCollision.Vertical) != 0) + _body.Velocity.Y = -_body.Velocity.Y * 0.65f; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/MidBoss/MBossStoneHinox.cs b/InGame/GameObjects/MidBoss/MBossStoneHinox.cs new file mode 100644 index 0000000..37bb7c4 --- /dev/null +++ b/InGame/GameObjects/MidBoss/MBossStoneHinox.cs @@ -0,0 +1,305 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Dungeon; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + class MBossStoneHinox : GameObject + { + private readonly Animator _animator; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _aiDamageState; + private readonly AnimationComponent _animationComponent; + + private Vector2[] _walkOffset = { new Vector2(-24, 0), new Vector2(24, 0), new Vector2(0, 24) }; + + private readonly Vector2 _spawnPosition; + private Vector2 _targetPosition; + + private int _lastWalkFrame; + private bool _wasHit; + + private readonly string _saveKey; + + public MBossStoneHinox() : base("stone hinox") { } + + public MBossStoneHinox(Map.Map map, int posX, int posY, string saveKey) : base(map) + { + EntityPosition = new CPosition(posX + 16, posY + 32, 0); + EntitySize = new Rectangle(-16, -32, 32, 32); + + _saveKey = saveKey; + + // was already killed? + if (!string.IsNullOrEmpty(_saveKey) && + Game1.GameManager.SaveManager.GetString(_saveKey) == "1") + { + IsDead = true; + return; + } + + _spawnPosition = EntityPosition.Position; + + _animator = AnimatorSaveLoad.LoadAnimator("MidBoss/stone hinox"); + _animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + _animationComponent = new AnimationComponent(_animator, sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -14, -20, 28, 20, 8) + { + Gravity = -0.1f, + FieldRectangle = Map.GetField(posX, posY, 16) + }; + + _aiComponent = new AiComponent(); + + var stateIdle = new AiState(UpdateIdle); + var stateIdleDelay = new AiState(UpdateIdleDelay); + var stateWalk = new AiState(UpdateWalk) { Init = InitWalking }; + var stateJump = new AiState(UpdateJump) { Init = InitJump }; + var stateHitFloor = new AiState { Init = InitHitFloor }; + stateHitFloor.Trigger.Add(new AiTriggerCountdown(500, null, EndHitFloor)); + var statePostAttack = new AiState { Init = InitPostAttack }; + statePostAttack.Trigger.Add(new AiTriggerCountdown(400, null, EndPostAttack)); + var statePostHit = new AiState { Init = InitPostHit }; + statePostHit.Trigger.Add(new AiTriggerCountdown(300, null, EndPostHit)); + + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("idleDelay", stateIdleDelay); + _aiComponent.States.Add("walk", stateWalk); + _aiComponent.States.Add("jump", stateJump); + _aiComponent.States.Add("attack", stateHitFloor); + _aiComponent.States.Add("postAttack", statePostAttack); + _aiComponent.States.Add("postHit", statePostHit); + _aiDamageState = new AiDamageState(this, _body, _aiComponent, sprite, 8, false, false) + { + HitMultiplierX = 0, + HitMultiplierY = 0, + BossHitSound = true + }; + _aiDamageState.DamageSpriteShader = Resources.DamageSpriteShader1; + _aiDamageState.AddBossDamageState(OnDeathAnimationEnd); + + _aiComponent.ChangeState("idle"); + + var damageCollider = new CBox(EntityPosition, -14, -24, 0, 28, 24, 8); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 4)); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, OnHit)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, _animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite) { ShadowWidth = 16, ShadowHeight = 6 }); + } + + private void UpdateIdle() + { + if (_body.FieldRectangle.Contains(MapManager.ObjLink.BodyRectangle)) + { + Game1.GameManager.StartDialogPath("stone_hinox"); + _aiComponent.ChangeState("idleDelay"); + } + } + + private void UpdateIdleDelay() + { + if (!Game1.GameManager.DialogIsRunning()) + _aiComponent.ChangeState("jump"); + } + + private void InitJump() + { + _body.IsGrounded = false; + _body.Velocity.Z = 2; + _animator.Pause(); + } + + private void UpdateJump() + { + // jump towards the spawn position + var spawnDirection = _spawnPosition - EntityPosition.Position; + if (spawnDirection.Length() > 0.75f * Game1.TimeMultiplier) + { + spawnDirection.Normalize(); + _body.VelocityTarget = 0.75f * spawnDirection; + } + else + { + _body.VelocityTarget = Vector2.Zero; + EntityPosition.Set(_spawnPosition); + } + + // end jump + if (_body.IsGrounded) + { + _body.VelocityTarget = Vector2.Zero; + EntityPosition.Set(_spawnPosition); + + _aiComponent.ChangeState("attack"); + + Game1.GameManager.PlaySoundEffect("D360-11-0B"); + // shake the screen + Game1.GameManager.ShakeScreen(800, 1, 2, 2, 7.5f); + + MapManager.ObjLink.GroundStun(800); + + // spawn stones + SpawnStone(); + SpawnStone(); + } + } + + private void InitHitFloor() + { + _animationComponent.MirroredH = _animator.CurrentFrameIndex == 0; + _animator.Play("attack"); + } + + private void EndHitFloor() + { + SpawnStone(); + _aiComponent.ChangeState("postAttack"); + } + + private void SpawnStone() + { + var objStone = new MBossStoneHinoxStone(Map, + new Vector3(_spawnPosition.X + Game1.RandomNumber.Next(0, 120) - 60, _spawnPosition.Y - 8 - Game1.RandomNumber.Next(0, 8), 16), + new Vector3(0, 1, 1), (int)_spawnPosition.X); + Map.Objects.SpawnObject(objStone); + } + + private void InitPostAttack() + { + _animator.Play("fast"); + _animator.SetFrame(_animationComponent.MirroredH ? 1 : 0); + _animationComponent.MirroredH = false; + } + + private void EndPostAttack() + { + if (_wasHit) + { + _wasHit = false; + _aiComponent.ChangeState("jump"); + } + else + { + var newState = Game1.RandomNumber.Next(0, 2); + _aiComponent.ChangeState(newState == 0 ? "walk" : "jump"); + _aiComponent.ChangeState("jump"); + } + } + + private void InitPostHit() + { + _animator.Pause(); + } + + private void EndPostHit() + { + _aiComponent.ChangeState("postAttack"); + } + + private void InitWalking() + { + var frameIndex = _animator.CurrentFrameIndex; + _animator.Play("idle"); + _animator.SetFrame(frameIndex); + _lastWalkFrame = frameIndex; + + // walk into a random direction if we are at the spawn position + if (EntityPosition.Position == _spawnPosition) + { + var randomDirection = Game1.RandomNumber.Next(0, 3); + _targetPosition = _spawnPosition + _walkOffset[randomDirection]; + } + else + { + _targetPosition = _spawnPosition; + } + } + + private void UpdateWalk() + { + // only move when a new frame from the animation is shown + if (_lastWalkFrame == _animator.CurrentFrameIndex) + return; + _lastWalkFrame = _animator.CurrentFrameIndex; + + // finished walking? + if (EntityPosition.Position == _targetPosition) + { + var newState = Game1.RandomNumber.Next(0, 2); + _aiComponent.ChangeState(newState == 0 ? "walk" : "jump"); + } + + // walk towards the target position + var newPosition = EntityPosition.Position; + if (EntityPosition.X != _targetPosition.X) + newPosition.X += 4 * Math.Sign(_targetPosition.X - EntityPosition.X); + if (EntityPosition.Y != _targetPosition.Y) + newPosition.Y += 4 * Math.Sign(_targetPosition.Y - EntityPosition.Y); + EntityPosition.Set(newPosition); + } + + private void OnDeathAnimationEnd() + { + if (!string.IsNullOrEmpty(_saveKey)) + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + // stop boss music + Game1.GameManager.SetMusic(-1, 2); + + // spawns a fairy + Game1.GameManager.PlaySoundEffect("D360-27-1B"); + Map.Objects.SpawnObject(new ObjDungeonFairy(Map, (int)EntityPosition.X, (int)EntityPosition.Y, 8)); + + Map.Objects.DeleteObjects.Add(this); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + return true; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_aiComponent.CurrentStateId == "idle") + return Values.HitCollision.None; + + if (_aiComponent.CurrentStateId == "walk" && _aiDamageState.CurrentLives > damage) + { + _aiComponent.ChangeState("postHit"); + _animator.Pause(); + _wasHit = true; + } + + if (damageType == HitType.Bomb || damageType == HitType.Boomerang || damageType == HitType.Bow || damageType == HitType.MagicRod) + damage = 4; + + var hitCollision = _aiDamageState.OnHit(gameObject, direction, damageType, damage, false); + + if (_aiDamageState.CurrentLives <= 0) + { + _body.VelocityTarget = Vector2.Zero; + _animator.Pause(); + } + + if (hitCollision != Values.HitCollision.None) + return hitCollision | Values.HitCollision.Repelling | Values.HitCollision.Repelling0; + + return hitCollision; + } + } +} diff --git a/InGame/GameObjects/MidBoss/MBossStoneHinoxStone.cs b/InGame/GameObjects/MidBoss/MBossStoneHinoxStone.cs new file mode 100644 index 0000000..c3c8de3 --- /dev/null +++ b/InGame/GameObjects/MidBoss/MBossStoneHinoxStone.cs @@ -0,0 +1,85 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + class MBossStoneHinoxStone : GameObject + { + private readonly BodyComponent _body; + private readonly CSprite _sprite; + + private readonly int _centerX; + private readonly int _spawnY; + + private int _collisionCount; + + public MBossStoneHinoxStone(Map.Map map, Vector3 position, Vector3 direction, int centerX) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(position.X, position.Y, position.Z); + EntitySize = new Rectangle(-8, -32, 16, 32); + + _centerX = centerX; + _spawnY = (int)EntityPosition.Position.Y; + _sprite = new CSprite("hinox stone", EntityPosition, new Vector2(-8, -16)); + + _body = new BodyComponent(EntityPosition, -6, -12, 12, 12, 8) + { + MoveCollision = MoveCollision, + CollisionTypes = Values.CollisionTypes.None, + Gravity = -0.1f, + DragAir = 1.0f, + Bounciness = 0.85f + }; + _body.Velocity = direction; + + // random start sprite effect + _sprite.SpriteEffect = (SpriteEffects)Game1.RandomNumber.Next(0, 4); + + var hitBox = new CBox(EntityPosition, -7, -14, 0, 14, 14, 8, true); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(hitBox, HitType.Enemy, 2)); + AddComponent(HittableComponent.Index, new HittableComponent(hitBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerPlayer)); + + var shadow = new DrawShadowSpriteComponent(Resources.SprShadow, EntityPosition, new Rectangle(0, 0, 65, 66), new Vector2(-6, -6), 12, 6); + AddComponent(DrawShadowComponent.Index, shadow); + } + + private void MoveCollision(Values.BodyCollision collisionType) + { + _collisionCount++; + + if ((collisionType & Values.BodyCollision.Floor) != 0) + Game1.GameManager.PlaySoundEffect("D360-32-20"); + + if (_collisionCount > 3 || EntityPosition.Y > _spawnY + Values.FieldHeight - 32) + { + Map.Objects.DeleteObjects.Add(this); + return; + } + + // set a new random direction + _body.Velocity.X = -1 + Game1.RandomNumber.Next(0, 100) / 50f; + // make sure that we do not get to far away from the center of the room + if (MathF.Abs(EntityPosition.X - _centerX) > 64) + _body.Velocity.X = MathF.Sign(_centerX - EntityPosition.X); + + _body.Velocity.Z = Game1.RandomNumber.Next(75, 125) / 50f; + + // flip the sprite + _sprite.SpriteEffect ^= SpriteEffects.FlipHorizontally; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + return Values.HitCollision.RepellingParticle; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/MidBoss/MBossTurtleRock.cs b/InGame/GameObjects/MidBoss/MBossTurtleRock.cs new file mode 100644 index 0000000..59c8932 --- /dev/null +++ b/InGame/GameObjects/MidBoss/MBossTurtleRock.cs @@ -0,0 +1,461 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using System; +using System.Collections.Generic; + +namespace ProjectZ.InGame.GameObjects.Bosses +{ + class MBossTurtleRock : GameObject + { + // list of sprite that are in the area of the turtle; this is used to set the visibility because normal layers do not work with the turtle head + private readonly List _spriteList = new List(); + + private readonly DictAtlasEntry _stoneHead; + private readonly Rectangle[] _headParts = new Rectangle[6]; + private readonly Vector2[] _headPartOffset = new Vector2[6]; + + private readonly Animator _animator; + private readonly AnimationComponent _animationComponent; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly CSprite _sprite; + private readonly DamageFieldComponent _damageField; + private readonly AiDamageState _aiDamageState; + + private readonly DictAtlasEntry _spriteNeck; + + private readonly Vector2 _startPosition; + private readonly Vector2 _centerPosition; + + private const float AttackSpeed = 1.5f; + private const float ReturnSpeed = 0.5f; + private const int WobbleTime = 140; + + private Vector3[] _partPosition = new Vector3[6]; + private Vector3[] _partVelocity = new Vector3[6]; + private int[] _partBreakOrder = new[] { 0, 5, 3, 4, 1, 2 }; + private int _partBreakIndex; + private float _partCounter = -500; + + private string _saveKey; + private bool _attackable = false; + + public MBossTurtleRock() : base("turtle rock") { } + + public MBossTurtleRock(Map.Map map, int posX, int posY, string saveKey) : base(map) + { + // do not spawn if the tutle was already killed + _saveKey = saveKey; + if (!string.IsNullOrEmpty(_saveKey) && + Game1.GameManager.SaveManager.GetString(_saveKey) == "1") + { + IsDead = true; + return; + } + + Tags = Values.GameObjectTag.Enemy; + + _startPosition = new Vector2(posX + 24, posY + 16); + _centerPosition = new Vector2(_startPosition.X, _startPosition.Y + 32); + + EntityPosition = new CPosition(_startPosition.X, _startPosition.Y, 0); + EntitySize = new Rectangle(-16, -16, 32, 32); + + _body = new BodyComponent(EntityPosition, -8, 0, 16, 16, 8) + { + CollisionTypes = Values.CollisionTypes.None + }; + + _spriteNeck = Resources.GetSprite("turtle neck"); + _stoneHead = Resources.GetSprite("turtle rock"); + + // the top gets split into 4 parts with the middle parts beeing 8px wide + // the bottom is split into two parts + var headWidth = (_stoneHead.SourceRectangle.Width - 16) / 2; + var headHeight = _stoneHead.SourceRectangle.Height / 2; + + _headPartOffset[0] = new Vector2(0, 0); + _headPartOffset[1] = new Vector2(headWidth, 0); + _headPartOffset[2] = new Vector2(headWidth + 8, 0); + _headPartOffset[3] = new Vector2(headWidth + 16, 0); + _headPartOffset[4] = new Vector2(0, headHeight); + _headPartOffset[5] = new Vector2(_stoneHead.SourceRectangle.Width / 2, headHeight); + + _headParts[0] = new Rectangle(_stoneHead.SourceRectangle.X + (int)_headPartOffset[0].X, _stoneHead.SourceRectangle.Y + (int)_headPartOffset[0].Y, headWidth, headHeight); + _headParts[1] = new Rectangle(_stoneHead.SourceRectangle.X + (int)_headPartOffset[1].X, _stoneHead.SourceRectangle.Y + (int)_headPartOffset[1].Y, 8, headHeight); + _headParts[2] = new Rectangle(_stoneHead.SourceRectangle.X + (int)_headPartOffset[2].X, _stoneHead.SourceRectangle.Y + (int)_headPartOffset[2].Y, 8, headHeight); + _headParts[3] = new Rectangle(_stoneHead.SourceRectangle.X + (int)_headPartOffset[3].X, _stoneHead.SourceRectangle.Y + (int)_headPartOffset[3].Y, headWidth, headHeight); + _headParts[4] = new Rectangle(_stoneHead.SourceRectangle.X + (int)_headPartOffset[4].X, _stoneHead.SourceRectangle.Y + (int)_headPartOffset[4].Y, _stoneHead.SourceRectangle.Width / 2, headHeight); + _headParts[5] = new Rectangle(_stoneHead.SourceRectangle.X + (int)_headPartOffset[5].X, _stoneHead.SourceRectangle.Y + (int)_headPartOffset[5].Y, _stoneHead.SourceRectangle.Width / 2, headHeight); + + // set the part position + for (var i = 0; i < _partPosition.Length; i++) + _partPosition[i] = new Vector3(EntityPosition.X + _headPartOffset[i].X, EntityPosition.Y + _headPartOffset[i].Y, 0); + + _animator = AnimatorSaveLoad.LoadAnimator("MidBoss/turtle rock"); + _animator.Play("stone"); + + _sprite = new CSprite(EntityPosition); + _animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(0, -16)); + + _aiComponent = new AiComponent(); + // deal damage at the neck positions + _aiComponent.Trigger.Add(new AiTriggerUpdate(UpdateDamageNeck)); + + var stateStone = new AiState(); + var stateWobble = new AiState(); + stateWobble.Trigger.Add(new AiTriggerCountdown(WobbleTime * 18, TickWobble, WobbleEnd)); + var stateBreak = new AiState(UpdateBreak) { Init = InitBreak }; + var stateOpenEyes = new AiState(UpdateEyeOpening) { Init = InitOpenEyes }; + var stateCome = new AiState(UpdateCome) { Init = InitCome }; + var stateInitWait = new AiState(); + stateInitWait.Trigger.Add(new AiTriggerCountdown(1000, null, () => _aiComponent.ChangeState("move"))); + var stateMove = new AiState(UpdateMove) { Init = InitMove }; + var stateWait = new AiState(); + stateWait.Trigger.Add(new AiTriggerCountdown(150, null, () => _aiComponent.ChangeState("move"))); + var statePreAttack = new AiState(); + statePreAttack.Trigger.Add(new AiTriggerCountdown(1000, null, () => _aiComponent.ChangeState("attack"))); + var stateAttack = new AiState(UpdateAttack) { Init = InitAttack }; + stateAttack.Trigger.Add(new AiTriggerCountdown(600, null, () => _aiComponent.ChangeState("return"))); + var stateReturn = new AiState(UpdateReturn); + var stateDead = new AiState(); + + _aiComponent.States.Add("stone", stateStone); + _aiComponent.States.Add("wobble", stateWobble); + _aiComponent.States.Add("break", stateBreak); + _aiComponent.States.Add("openEyes", stateOpenEyes); + _aiComponent.States.Add("come", stateCome); + _aiComponent.States.Add("initWait", stateInitWait); + _aiComponent.States.Add("move", stateMove); + _aiComponent.States.Add("wait", stateWait); + _aiComponent.States.Add("preAttack", statePreAttack); + _aiComponent.States.Add("attack", stateAttack); + _aiComponent.States.Add("return", stateReturn); + _aiComponent.States.Add("dead", stateDead); + + _aiDamageState = new AiDamageState(this, _body, _aiComponent, _sprite, 16, false, false, AiDamageState.BlinkTime * 6) + { + HitMultiplierX = 0, + HitMultiplierY = 0, + ExplosionOffsetY = 16 + }; + _aiDamageState.AddBossDamageState(OnDeath); + + _aiComponent.ChangeState("stone"); + + var damageCollider = new CBox(EntityPosition, -6, -16, 0, 12, 30, 8); + var hittableBox = new CBox(EntityPosition, -6, -16, 0, 12, 30, 8); + + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, _animationComponent); + AddComponent(OcarinaListenerComponent.Index, new OcarinaListenerComponent(OnSongPlayed)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageCollider, HitType.Enemy, 2) { IsActive = false }); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(new CBox(EntityPosition, -8, 0, 16, 14, 8), Values.CollisionTypes.Enemy)); + + } + + public override void Init() + { + Map.Objects.GetComponentList(_spriteList, (int)EntityPosition.X - 8 - 16 * 3, (int)EntityPosition.Y - 16, 16 * 7, 16 * 5, DrawComponent.Mask); + UpdateSpriteLayers(); + } + + private void UpdateDamageNeck() + { + var startOffset = EntityPosition.Position - _startPosition; + var partCount = (int)((startOffset.Y + 4) / 16); + for (var i = 0; i < partCount; i++) + { + var percentage = 1 - (startOffset.Y - i * 16) / (startOffset.Y + 8); + var offset = 1 - MathF.Sin(percentage * MathF.PI / 2); + var position = new Vector2(_startPosition.X - 8 + startOffset.X * offset, EntityPosition.Y - i * 16 - 32); + var damageBox = new ProjectZ.Base.Box(position.X, position.Y, 0, 16, 16, 8); + var playerDamageBox = MapManager.ObjLink.DamageCollider.Box; + var direction = playerDamageBox.Center - damageBox.Center; + if (direction != Vector2.Zero) + direction.Normalize(); + direction *= 1.5f; + + if (damageBox.Intersects(playerDamageBox)) + MapManager.ObjLink.HitPlayer(direction, HitType.Sword, 2, false, ObjLink.CooldownTime / 4); + } + } + + private void UpdateReturn() + { + // return to the start position + var playerDirection = _centerPosition - EntityPosition.Position; + if (playerDirection.Length() > ReturnSpeed * Game1.TimeMultiplier) + { + playerDirection.Normalize(); + _body.VelocityTarget = playerDirection * ReturnSpeed; + } + else + { + _body.VelocityTarget = Vector2.Zero; + _aiComponent.ChangeState("move"); + } + + UpdateSpriteLayers(); + } + + private void InitAttack() + { + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + var angle = MathF.Atan2(playerDirection.Y, playerDirection.X); + angle = MathHelper.Clamp(angle, 0, MathF.PI); + + _body.VelocityTarget = new Vector2(MathF.Cos(angle), MathF.Sin(angle)) * AttackSpeed; + } + + private void UpdateAttack() + { + UpdateSpriteLayers(); + } + + private void InitMove() + { + _attackable = true; + // move to the left or to the right? + _body.VelocityTarget.X = 0.5f; + if (EntityPosition.X > _startPosition.X) + _body.VelocityTarget *= -1; + } + + private void UpdateMove() + { + // finished moving? + if (_body.VelocityTarget.X < 0 && EntityPosition.X <= _startPosition.X - 15) + { + EntityPosition.Set(new Vector2(_startPosition.X - 15, EntityPosition.Y)); + EndMove(); + } + if (_body.VelocityTarget.X > 0 && EntityPosition.X >= _startPosition.X + 15) + { + EntityPosition.Set(new Vector2(_startPosition.X + 15, EntityPosition.Y)); + EndMove(); + } + + UpdateSpriteLayers(); + } + + private void EndMove() + { + _body.VelocityTarget.X = 0; + + if (Game1.RandomNumber.Next(0, 2) == 0) + _aiComponent.ChangeState("wait"); + else + _aiComponent.ChangeState("preAttack"); + } + + private void InitCome() + { + _body.VelocityTarget.Y = 0.25f; + } + + private void UpdateCome() + { + UpdateSpriteLayers(); + + // come out of the hole + if (EntityPosition.Y > _startPosition.Y + 32) + { + _body.VelocityTarget.Y = 0; + EntityPosition.Set(new Vector2(_startPosition.X, _startPosition.Y + 32)); + _aiComponent.ChangeState("initWait"); + } + } + + private void InitOpenEyes() + { + // start opening the eyes + _animator.Play("open"); + } + + private void UpdateEyeOpening() + { + if (!_animator.IsPlaying) + { + _aiComponent.ChangeState("come"); + } + } + + private void InitBreak() + { + _animator.Play("closed"); + } + + private void UpdateBreak() + { + _partCounter += Game1.DeltaTime; + + // break away + if (_partCounter > _partBreakIndex * 500) + { + if (_partBreakIndex >= 6) + { + _aiComponent.ChangeState("openEyes"); + return; + } + + Game1.GameManager.PlaySoundEffect("D378-19-13"); + + var partIndex = _partBreakOrder[_partBreakIndex]; + _partVelocity[partIndex] = new Vector3(0.45f, 0, 1.5f); + if (partIndex == 0 || partIndex == 1 || partIndex == 4) + _partVelocity[partIndex].X *= -1; + + _partBreakIndex++; + } + + // move the part + for (var i = 0; i < _partBreakIndex; i++) + { + var partIndex = _partBreakOrder[i]; + _partPosition[partIndex] += _partVelocity[partIndex] * Game1.TimeMultiplier; + _partVelocity[partIndex].Z -= 0.25f * Game1.TimeMultiplier; + } + } + + private void UpdateSpriteLayers() + { + var rectangle = new Rectangle((int)EntityPosition.X - 8, (int)EntityPosition.Y - 16, 16, 32); + + foreach (var sprite in _spriteList) + { + if (sprite is ObjSprite) + { + if (!rectangle.Contains(sprite.EntityPosition.Position)) + { + ((DrawComponent)sprite.Components[DrawComponent.Index]).Layer = Values.LayerPlayer; + ((DrawShadowComponent)sprite.Components[DrawShadowComponent.Index]).IsActive = true; + } + else + { + ((DrawComponent)sprite.Components[DrawComponent.Index]).Layer = Values.LayerBottom; + ((DrawShadowComponent)sprite.Components[DrawShadowComponent.Index]).IsActive = false; + } + } + } + } + + private void TickWobble(double counter) + { + _animationComponent.SpriteOffset.X = MathF.Sin((float)(counter / WobbleTime) * 2 * MathF.PI); + _animationComponent.UpdateSprite(); + } + + private void WobbleEnd() + { + _animationComponent.SpriteOffset.X = 0; + _aiComponent.ChangeState("break"); + } + + private void OnDeath() + { + Game1.GameManager.PlaySoundEffect("D378-12-0C"); + + if (!string.IsNullOrEmpty(_saveKey)) + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + // stop boss music + Game1.GameManager.SetMusic(-1, 2); + + Map.Objects.DeleteObjects.Add(this); + } + + private void Draw(SpriteBatch spriteBatch) + { + // change the draw effect + if (_sprite.SpriteShader != null) + { + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, _sprite.SpriteShader); + } + + // draw the nack while moving around outside + var startOffset = EntityPosition.Position - _startPosition; + var partCount = (int)((startOffset.Y + 4) / 16); + for (var i = 0; i < partCount; i++) + { + var percentage = 1 - (startOffset.Y - i * 16) / (startOffset.Y + 8); + var offset = 1 - MathF.Sin(percentage * MathF.PI / 2); + var position = new Vector2(_startPosition.X - 8 + startOffset.X * offset, EntityPosition.Y - i * 16 - 32); + DrawHelper.DrawNormalized(spriteBatch, _spriteNeck, position, Color.White); + } + + // draw the head + _sprite.Draw(spriteBatch); + + // draw the head parts + if (_aiComponent.CurrentStateId != "wobble") + for (var i = 0; i < _partPosition.Length; i++) + { + if (_partPosition[i].Z < 0) + continue; + + var position = new Vector2(_partPosition[i].X - 14, _partPosition[i].Y - _partPosition[i].Z - 16); + DrawHelper.DrawNormalized(spriteBatch, _stoneHead.Texture, position, _headParts[i], Color.White); + } + + // change the draw effect + if (_sprite.SpriteShader != null) + { + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, null); + } + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + if (_aiDamageState.CurrentLives <= 0) + return Values.HitCollision.None; + + // can only be hit after beeing spawned + if (!_attackable || ((type & HitType.Sword) == 0)) + return Values.HitCollision.RepellingParticle; + + // close the eyes for a short time + if (!_aiDamageState.IsInDamageState()) + { + Game1.GameManager.PlaySoundEffect("D370-07-07"); + _animator.Play("damaged"); + } + + _aiDamageState.OnHit(originObject, direction, type, damage, false); + + if (_aiDamageState.CurrentLives <= 0) + { + _body.VelocityTarget = Vector2.Zero; + _aiComponent.ChangeState("dead"); + Game1.GameManager.StartDialogPath("turtle_rock_killed"); + } + + return Values.HitCollision.Enemy; + } + + private void OnSongPlayed(int songIndex) + { + if (songIndex == 2 && _aiComponent.CurrentStateId == "stone") + { + Game1.GameManager.SetMusic(56, 2); + + ((BoxCollisionComponent)Components[CollisionComponent.Index]).IsActive = false; + ((DamageFieldComponent)Components[DamageFieldComponent.Index]).IsActive = true; + _aiComponent.ChangeState("wobble"); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/MidBoss/MDodongoSnake.cs b/InGame/GameObjects/MidBoss/MDodongoSnake.cs new file mode 100644 index 0000000..21bffd3 --- /dev/null +++ b/InGame/GameObjects/MidBoss/MDodongoSnake.cs @@ -0,0 +1,441 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Dungeon; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + class MDodongoSnake : GameObject + { + private readonly List _collidingObjects = new List(); + + private readonly BodyComponent _body; + private readonly BodyDrawComponent _bodyDrawComponent; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _damageState; + private readonly CSprite _sprite; + private readonly AiTriggerRandomTime _directionTrigger; + private readonly CBox _eatBox; + + private readonly DictAtlasEntry _spriteHead; + private readonly DictAtlasEntry _spriteBody0; + private readonly DictAtlasEntry _spriteBody1; + private readonly DictAtlasEntry _spriteBody2; + + private readonly string _saveKey; + private readonly int _color; + + private Vector2 _bodyPosition; + private Vector2 _bodyExplosionPosition; + private Vector2 _turningPosition; + private Vector2 _bodyOffset; + private Vector2 _lastHeadPosition; + + private int _direction; + private float _movementSpeed = 0.375f; + + private float _explosionCounter; + + private const float TailDistance = 12; + private float _bodyDistance; + private bool _wallCollision = true; + private bool _stopDraggin = true; + private bool _playedSwollowSound; + private bool _playerInRoom; + + private int _lives = 3; + + // @TODO: it looks like the body gets left behind when we move out of the screen + public MDodongoSnake() : base("snake blue") { } + + public MDodongoSnake(Map.Map map, int posX, int posY, string saveKey, int color, bool resetKey) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-22, -8 - 22, 44, 44); + + _bodyPosition = EntityPosition.Position; + _lastHeadPosition = EntityPosition.Position; + + _saveKey = saveKey; + _color = color; + + var strColor = _color == 0 ? "blue" : "green"; + + // was the boss already defeated? + if (!string.IsNullOrEmpty(_saveKey) && Game1.GameManager.SaveManager.GetString(_saveKey) == "1") + { + if (resetKey) + { + Game1.GameManager.SaveManager.SetString(_saveKey, "0"); + } + else + { + IsDead = true; + return; + } + } + + _spriteHead = Resources.GetSprite("snake " + strColor); + _spriteBody0 = Resources.GetSprite("snake body " + strColor); + _spriteBody1 = Resources.GetSprite("snake body"); + _spriteBody2 = Resources.GetSprite("snake big " + strColor); + + _eatBox = new CBox(EntityPosition, -1, -8, 2, 4, 8); + + _sprite = new CSprite("snake " + strColor, EntityPosition, new Vector2(-8, -16)); + + _body = new BodyComponent(EntityPosition, -7, -13, 14, 12, 8) + { + MoveCollision = OnCollision, + Drag = 0.65f, + DragAir = 0.95f, + Gravity = -0.15f, + FieldRectangle = map.GetField(posX, posY), + AvoidTypes = Values.CollisionTypes.Hole | Values.CollisionTypes.NPCWall + }; + + var stateMoving = new AiState(UpdateMoving); + stateMoving.Trigger.Add(_directionTrigger = new AiTriggerRandomTime(ChangeDirection, 1000, 1500)); + var stateExplosion = new AiState(UpdateExplosion); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("moving", stateMoving); + _aiComponent.States.Add("explosion", stateExplosion); + + _damageState = new AiDamageState(this, _body, _aiComponent, _sprite, 8, false) + { + OnDeath = OnDeath + }; + + _bodyDrawComponent = new BodyDrawComponent(_body, _sprite, Values.LayerPlayer); + + var damageCollider = new CBox(EntityPosition, -7, -11, 0, 14, 11, 8, true); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageCollider, HitType.Enemy, 4)); + + var hittableBox = new CBox(EntityPosition, -7, -15, 0, 14, 14, 8, true); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _sprite) { ShadowWidth = 16, ShadowHeight = 6 }); + + ChangeDirection(); + _aiComponent.ChangeState("moving"); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType pushType) + { + return true; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + return Values.HitCollision.RepellingParticle; + } + + private void OnCollision(Values.BodyCollision collision) + { + _wallCollision = true; + _directionTrigger.CurrentTime = Math.Min(_directionTrigger.CurrentTime, 250); + } + + private void ChangeDirection() + { + _direction = Game1.RandomNumber.Next(0, 4); + + _body.VelocityTarget = AnimationHelper.DirectionOffset[_direction] * _movementSpeed; + + _turningPosition = EntityPosition.Position; + + if (_wallCollision) + { + _stopDraggin = true; + _wallCollision = false; + } + } + + private void ToExploding() + { + _playedSwollowSound = false; + _aiComponent.ChangeState("explosion"); + _bodyExplosionPosition = _bodyPosition; + _damageState.SetDamageState(); + } + + private void UpdateExplosion() + { + _body.VelocityTarget = Vector2.Zero; + _explosionCounter += Game1.DeltaTime; + + // swollow sound effect + if (!_playedSwollowSound && _explosionCounter > 55 / 0.06) + { + _playedSwollowSound = true; + Game1.GameManager.PlaySoundEffect("D360-42-2A"); + } + + if (_explosionCounter > 94 / 0.06 && _explosionCounter - Game1.DeltaTime < 94 / 0.06) + { + Game1.GameManager.PlaySoundEffect("D378-12-0C"); + + var particlePosition = EntityPosition.Position + AnimationHelper.DirectionOffset[_direction] * 13; + Map.Objects.SpawnObject(new ObjAnimator(Map, + (int)particlePosition.X, (int)particlePosition.Y, -8, -16, Values.LayerPlayer, "Particles/spawn", "run", true)); + } + + if (_explosionCounter > 76 / 0.06 && _explosionCounter - Game1.DeltaTime < 76 / 0.06) + { + _lives--; + + // enemy is dead? + if (_lives <= 0) + { + OnDeath(); + return; + } + } + + if (_explosionCounter > 112 / 0.06) + { + _explosionCounter = 0; + ChangeDirection(); + _aiComponent.ChangeState("moving"); + _bodyPosition = _bodyExplosionPosition; + } + } + + private void OnDeath() + { + if (!string.IsNullOrEmpty(_saveKey)) + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + // stop the boss music + Game1.GameManager.SetMusic(-1, 2); + + Game1.GameManager.PlaySoundEffect("D378-26-1A"); + + // spawn fairy + Game1.GameManager.PlaySoundEffect("D360-27-1B"); + Map.Objects.SpawnObject(new ObjDungeonFairy(Map, (int)_bodyExplosionPosition.X, (int)_bodyExplosionPosition.Y + 8, 0)); + + // shake the screen + Game1.GameManager.ShakeScreen(225, 4, 1, 5, 2.5f); + + // spawn explosion effect + Map.Objects.SpawnObject(new ObjAnimator(Map, + (int)_bodyExplosionPosition.X, (int)_bodyExplosionPosition.Y - 8, Values.LayerPlayer, "Particles/explosionBomb", "run2", true)); + + Map.Objects.DeleteObjects.Add(this); + } + + private void UpdateMoving() + { + // start/stop music when the player enters/leaves the room + if (_body.FieldRectangle.Contains(MapManager.ObjLink.BodyRectangle)) + { + _playerInRoom = true; + if (Game1.GameManager.GetCurrentMusic() != 79) + Game1.GameManager.SetMusic(79, 2); + } + else if (_playerInRoom) + { + _playerInRoom = false; + Game1.GameManager.SetMusic(-1, 2); + } + + EatBombs(); + + var offset = 0.5f; + var speed = 55; + _sprite.DrawOffset.X = -8 + ((_direction == 0 || _direction == 2) ? MathF.Sin((float)(Game1.TotalGameTime / speed)) * offset : 0); + _sprite.DrawOffset.Y = -16 + ((_direction == 1 || _direction == 3) ? MathF.Sin((float)(Game1.TotalGameTime / speed)) * offset : 0); + + _bodyOffset.X = (_direction == 0 || _direction == 2) ? MathF.Sin((float)(Game1.TotalGameTime / speed) + MathF.PI * 0.9f) * offset : 0; + _bodyOffset.Y = (_direction == 1 || _direction == 3) ? MathF.Sin((float)(Game1.TotalGameTime / speed) + MathF.PI * 0.9f) * offset : 0; + + // updated body distance + var distance = (_lastHeadPosition - EntityPosition.Position).Length(); + _bodyDistance += distance; + + if (distance < 0.001f) + { + _sprite.DrawOffset.X = -8; + _sprite.DrawOffset.Y = -16; + } + + if (_bodyDistance > TailDistance) + { + _bodyDistance = TailDistance; + _stopDraggin = false; + } + + if (!_stopDraggin || _wallCollision) + { + _bodyDistance -= _movementSpeed * Game1.TimeMultiplier; + if (_bodyDistance < 0) + _bodyDistance = 0; + } + + // drag the body behind the head + if (_turningPosition != Vector2.Zero) + { + // update position + var directionTurningPoint = _turningPosition - EntityPosition.Position; + var turningPointDistance = directionTurningPoint.Length(); + if (turningPointDistance > _bodyDistance) + { + directionTurningPoint.Normalize(); + _bodyPosition = EntityPosition.Position + directionTurningPoint * _bodyDistance; + _turningPosition = Vector2.Zero; + } + else + { + // update position + var direction = _bodyPosition - _turningPosition; + if (direction != Vector2.Zero) + { + direction.Normalize(); + _bodyPosition = _turningPosition + direction * (_bodyDistance - turningPointDistance); + } + } + } + else + { + // update position + var direction = _bodyPosition - EntityPosition.Position; + + if (direction != Vector2.Zero) + { + direction.Normalize(); + _bodyPosition = EntityPosition.Position + direction * _bodyDistance; + } + } + + _lastHeadPosition = EntityPosition.Position; + } + + private void EatBombs() + { + _collidingObjects.Clear(); + Map.Objects.GetComponentList(_collidingObjects, + (int)EntityPosition.Position.X - 8, (int)EntityPosition.Position.Y - 16, 16, 16, BodyComponent.Mask); + + foreach (var collidingObject in _collidingObjects) + { + var body = (BodyComponent)collidingObject.Components[BodyComponent.Index]; + + if (collidingObject.GetType() == typeof(ObjBomb) && _eatBox.Box.Intersects(body.BodyBox.Box)) + { + var bomb = (ObjBomb)collidingObject; + if (bomb.Body.IsActive) + { + bomb.IsActive = false; + bomb.Map.Objects.DeleteObjects.Add(bomb); + + ToExploding(); + } + } + } + } + + private void Draw(SpriteBatch spriteBatch) + { + _sprite.SourceRectangle.X = _spriteHead.ScaledRectangle.X; + _sprite.SourceRectangle.Y = _spriteHead.ScaledRectangle.Y; + + if (_direction == 1) + _sprite.SourceRectangle.X += 18; + else if (_direction == 3) + _sprite.SourceRectangle.X += 36; + + _sprite.SpriteEffect = _direction == 2 ? SpriteEffects.FlipHorizontally : SpriteEffects.None; + + var bodyDrawPosition = _bodyPosition + new Vector2(-8, -16) + _bodyOffset; + var bodyRectangle = _spriteBody0.ScaledRectangle; + + // explosion going on? + if (_explosionCounter > 0) + { + _sprite.DrawOffset = new Vector2(-8, -16); + + // change the color to green + if (_explosionCounter < 102 / 0.06) + { + var dir = _color == 0 ? 1 : -1; + _sprite.SourceRectangle.Y += 18 * dir; + bodyRectangle.Y += 18 * dir; + } + + var targetPosition = EntityPosition.Position - new Vector2( + AnimationHelper.DirectionOffset[_direction].X * 13, + AnimationHelper.DirectionOffset[_direction].Y * 12); + var distance = (_bodyExplosionPosition - targetPosition).Length(); + + if (distance > 0) + { + var amount = Math.Min(1, (1 * Game1.TimeMultiplier) / distance); + _bodyExplosionPosition = Vector2.Lerp(_bodyExplosionPosition, targetPosition, amount); + } + + if (_explosionCounter < 60 / 0.06) + { + + } + else if (_explosionCounter < 66 / 0.06) + { + bodyRectangle = _spriteBody1.ScaledRectangle; + _sprite.DrawOffset += AnimationHelper.DirectionOffset[_direction] * 2; + } + else if (_explosionCounter < 86 / 0.06) + { + bodyRectangle = _spriteBody2.ScaledRectangle; + _sprite.DrawOffset += AnimationHelper.DirectionOffset[_direction] * 4; + } + else if (_explosionCounter < 92 / 0.06) + { + bodyRectangle = _spriteBody1.ScaledRectangle; + _sprite.DrawOffset += AnimationHelper.DirectionOffset[_direction] * 2; + } + else if (_explosionCounter < 98 / 0.06) + { + + } + + bodyDrawPosition = _bodyExplosionPosition + new Vector2(-bodyRectangle.Width / 2, -8 - bodyRectangle.Height / 2); + } + + var drawBodyFirst = bodyDrawPosition.Y + bodyRectangle.Height <= EntityPosition.Y || (_explosionCounter > 0 && _direction != 1); + + // draw the body + if (drawBodyFirst) + spriteBatch.Draw(_spriteHead.Texture, bodyDrawPosition, bodyRectangle, Color.White); + + // draw the head + _bodyDrawComponent.Draw(spriteBatch); + + // draw the body + if (!drawBodyFirst) + spriteBatch.Draw(_spriteHead.Texture, bodyDrawPosition, bodyRectangle, Color.White); + + } + + private void OnDeath(bool pieceOfPower) + { + _aiComponent.ChangeState("death"); + + Game1.GameManager.PlaySoundEffect("D370-16-10"); + } + } +} diff --git a/InGame/GameObjects/MidBoss/MKingMoblin.cs b/InGame/GameObjects/MidBoss/MKingMoblin.cs new file mode 100644 index 0000000..eb82e10 --- /dev/null +++ b/InGame/GameObjects/MidBoss/MKingMoblin.cs @@ -0,0 +1,367 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Dungeon; +using ProjectZ.InGame.GameObjects.Enemies; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.MidBoss +{ + class MKingMoblin : GameObject + { + private readonly BodyComponent _body; + private readonly BodyDrawComponent _bodyDrawComponent; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _damageState; + private readonly CSprite _sprite; + private readonly DamageFieldComponent _damageField; + private readonly Animator _animator; + + private readonly Vector2 _spawnPosition; + + private Vector2 _moveDirection; + + private readonly string _triggerKey; + private readonly string _saveKey; + + private const int Lives = 8; + + private double _bounceTime; + private int _direction; + private bool _endWaiting; + + public MKingMoblin() : base("king_moblin") { } + + public MKingMoblin(Map.Map map, int posX, int posY, string triggerKey, string saveKey) : base(map) + { + // was the boss already defeated? + if (!string.IsNullOrEmpty(saveKey) && Game1.GameManager.SaveManager.GetString(saveKey) == "1") + { + IsDead = true; + return; + } + + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-12, -24, 24, 24); + + _triggerKey = triggerKey; + _saveKey = saveKey; + + _spawnPosition = EntityPosition.Position; + + _animator = AnimatorSaveLoad.LoadAnimator("MidBoss/bigMoblin"); + _animator.Play("wait"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-8, -16)); + + _body = new BodyComponent(EntityPosition, -10, -16, 20, 16, 8) + { + MoveCollision = OnCollision, + Drag = 0.65f, + DragAir = 0.95f, + Gravity = -0.15f, + FieldRectangle = map.GetField(posX, posY) + }; + + var stateWaiting = new AiState(UpdateWaiting); + var stateWalk = new AiState(UpdateWalk); + var stateSpear = new AiState(UpdateSpear); + var statePostSpear = new AiState(); + statePostSpear.Trigger.Add(new AiTriggerCountdown(500, null, ToWalking)); + var statePreAttack = new AiState(UpdatePreAttack); + var stateAttack = new AiState(); + stateAttack.Trigger.Add(new AiTriggerCountdown(550, null, ToWalking)); + var stateBounce = new AiState(UpdateBound); + var stateLook = new AiState(UpdateLook); + + _aiComponent = new AiComponent(); + + _aiComponent.States.Add("waiting", stateWaiting); + _aiComponent.States.Add("walk", stateWalk); + _aiComponent.States.Add("spear", stateSpear); + _aiComponent.States.Add("postSpear", statePostSpear); + _aiComponent.States.Add("preAttack", statePreAttack); + _aiComponent.States.Add("attack", stateAttack); + _aiComponent.States.Add("bounce", stateBounce); + _aiComponent.States.Add("look", stateLook); + + _damageState = new AiDamageState(this, _body, _aiComponent, _sprite, Lives, true, false) + { + ExplostionWidth = 22, + ExplostionHeight = 18 + }; + _damageState.AddBossDamageState(OnDeath); + + _aiComponent.ChangeState("waiting"); + + var hittableBox = new CBox(EntityPosition, -10, -14, 0, 20, 14, 8, true); + var damageCollider = new CBox(EntityPosition, -7, -11, 0, 14, 11, 8, true); + _bodyDrawComponent = new BodyDrawComponent(_body, _sprite, Values.LayerPlayer); + + if (!string.IsNullOrEmpty(_triggerKey)) + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush) { RepelMultiplier = 1 }); + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(damageCollider, HitType.Enemy, 4) { OnDamagedPlayer = OnDamagedPlayer }); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _sprite) { ShadowWidth = 16, ShadowHeight = 6 }); + } + + private void KeyChanged() + { + // activate the boss after entering the room + if (IsActive && + _aiComponent.CurrentStateId == "waiting" && + Game1.GameManager.SaveManager.GetString(_triggerKey) == "1") + { + _endWaiting = true; + } + } + + private void OnDamagedPlayer() + { + if (_aiComponent.CurrentStateId == "attack") + { + Game1.GameManager.PlaySoundEffect("D360-11-0B"); + ToWalking(); + } + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type != PushableComponent.PushType.Impact) + return false; + + var mult = _body.IsGrounded ? 3.5f : 1.5f; + _body.Velocity = new Vector3(direction.X * mult, direction.Y * mult, 0); + + return true; + } + + private void UpdateWaiting() + { + if (_body.IsGrounded) + { + if (_endWaiting) + { + ToWalking(); + Game1.GameManager.StartDialogPath("mc_boss_enter"); + return; + } + + { + // the farther away the enemy is from the origin the more likely it becomes that he will move towards the center position + var directionToStart = _spawnPosition - EntityPosition.Position; + var radiusToCenter = MathF.Atan2(directionToStart.Y, directionToStart.X); + + var maxDistanceX = 15.0f; + var maxDistanceY = 15.0f; + var distanceMultiplier = Math.Clamp( + Math.Min( + (maxDistanceX - Math.Abs(directionToStart.X)) / maxDistanceX, + (maxDistanceY - Math.Abs(directionToStart.Y)) / maxDistanceY), 0, 1); + + var dir = radiusToCenter + (Math.PI - Game1.RandomNumber.Next(0, 628) / 100f) * distanceMultiplier; + _body.VelocityTarget = new Vector2((float)Math.Cos(dir), (float)Math.Sin(dir)) * 0.125f * Game1.TimeMultiplier; + } + + _direction = EntityPosition.X < MapManager.ObjLink.EntityPosition.X ? 2 : 0; + _animator.Play("idle_" + _direction); + _body.Velocity = new Vector3(0, 0, 1.25f); + } + } + + private void ToWalking() + { + _aiComponent.ChangeState("walk"); + + _damageField.PushMultiplier = 1.75f; + _direction = EntityPosition.X < MapManager.ObjLink.EntityPosition.X ? 2 : 0; + _animator.Play("idle_" + _direction); + _body.Velocity = new Vector3(0, 0, 1.25f); + } + + private void UpdateWalk() + { + // start new jump + if (_body.IsGrounded) + { + // if we are on the same height as the player start attacking + var distance = MapManager.ObjLink.EntityPosition.Y - EntityPosition.Y; + if (Math.Abs(distance) < 16) + { + _direction = EntityPosition.X < MapManager.ObjLink.EntityPosition.X ? 2 : 0; + + if (Game1.RandomNumber.Next(0, 4) == 0) + { + ToThrowSpear(); + return; + } + if (Game1.RandomNumber.Next(0, 4) == 0) + { + ToPreAttack(); + return; + } + } + + _animator.Play("idle_" + _direction); + + var targetPosition = new Vector2(MapManager.ObjLink.EntityPosition.X + (_direction == 0 ? 50 : -50), MapManager.ObjLink.EntityPosition.Y); + _moveDirection = targetPosition - EntityPosition.Position; + if (_moveDirection != Vector2.Zero) + _moveDirection.Normalize(); + _moveDirection *= 0.5f; + + _body.Velocity = new Vector3(0, 0, 1.25f); + } + + _body.VelocityTarget = _moveDirection; + } + + private void ToThrowSpear() + { + _aiComponent.ChangeState("spear"); + + _body.VelocityTarget = Vector2.Zero; + _animator.Play("throw_" + _direction); + } + + private void UpdateSpear() + { + if (!_animator.IsPlaying) + { + _animator.Play("idle_" + _direction); + _aiComponent.ChangeState("postSpear"); + + // spawn spear + var spear = new EnemySpear(Map, new Vector3(EntityPosition.X, EntityPosition.Y - 9, 3), AnimationHelper.DirectionOffset[_direction] * 2f); + Map.Objects.SpawnObject(spear); + } + } + + private void ToPreAttack() + { + _aiComponent.ChangeState("preAttack"); + + _body.VelocityTarget = Vector2.Zero; + _animator.Play("arm_" + _direction); + } + + private void UpdatePreAttack() + { + Game1.GameManager.PlaySoundEffect("D360-09-09", false); + + // start attacking + if (!_animator.IsPlaying) + ToAttack(); + } + + private void ToAttack() + { + _aiComponent.ChangeState("attack"); + + _damageField.PushMultiplier = 3.5f; + _body.VelocityTarget = new Vector2(_direction == 0 ? -1 : 1, 0) * 2.5f; + _animator.Play("attack_" + _direction); + } + + private void ToBounce() + { + _aiComponent.ChangeState("bounce"); + + Game1.GameManager.PlaySoundEffect("D360-11-0B"); + _animator.Play("wall"); + + _damageField.PushMultiplier = 1.75f; + + _body.VelocityTarget = Vector2.Zero; + _body.Velocity = new Vector3(_direction == 0 ? 1.0f : -1.0f, 0, 1.75f); + + _bounceTime = Game1.TotalGameTime; + + // shake the screen + Game1.GameManager.ShakeScreen(800, 4, 1, 5, 5); + } + + private void UpdateBound() + { + if (_bounceTime + 1500 < Game1.TotalGameTime) + ToLook(); + } + + private void ToLook() + { + _aiComponent.ChangeState("look"); + + _animator.Play("look_" + _direction); + } + + private void UpdateLook() + { + if (!_animator.IsPlaying) + ToWalking(); + } + + private void OnDeath() + { + if (!string.IsNullOrEmpty(_saveKey)) + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + Game1.GameManager.StartDialogPath("mc_boss_defeat"); + + // spawn fairy + Game1.GameManager.PlaySoundEffect("D360-27-1B"); + Map.Objects.SpawnObject(new ObjDungeonFairy(Map, (int)EntityPosition.X, (int)EntityPosition.Y, 8)); + + Map.Objects.DeleteObjects.Add(this); + } + + private void Draw(SpriteBatch spriteBatch) + { + _bodyDrawComponent.Draw(spriteBatch); + + if (_aiComponent.CurrentStateId == "bounce" || _aiComponent.CurrentStateId == "damage") + { + var sourceRectangle = new Rectangle(188, 11, 4, 4); + var distance = new Vector2((float)Math.Sin(Game1.TotalGameTime / 100f) * 8, (float)Math.Cos(Game1.TotalGameTime / 100f) * 3); + + spriteBatch.Draw(Resources.SprMidBoss, new Vector2( + EntityPosition.X + distance.X - 2, EntityPosition.Y - EntityPosition.Z - 18 + distance.Y - 2), sourceRectangle, Color.White); + spriteBatch.Draw(Resources.SprMidBoss, new Vector2( + EntityPosition.X - distance.X - 2, EntityPosition.Y - EntityPosition.Z - 18 - distance.Y - 2), sourceRectangle, Color.White); + } + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_aiComponent.CurrentStateId == "damage") + return Values.HitCollision.Enemy; + if (_aiComponent.CurrentStateId != "bounce") + return Values.HitCollision.RepellingParticle; + + Game1.GameManager.PlaySoundEffect("D370-07-07"); + + _damageState.OnHit(gameObject, direction, damageType, damage, pieceOfPower); + + return Values.HitCollision.Enemy; + } + + private void OnCollision(Values.BodyCollision direction) + { + if ((direction & Values.BodyCollision.Horizontal) != 0 && _aiComponent.CurrentStateId == "attack") + ToBounce(); + } + } +} diff --git a/InGame/GameObjects/NPCs/ObjAlligator.cs b/InGame/GameObjects/NPCs/ObjAlligator.cs new file mode 100644 index 0000000..d61f554 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjAlligator.cs @@ -0,0 +1,153 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjAlligator : GameObject + { + private GameObject _gameObjectBanana; + + private readonly BodyDrawComponent _bodyDrawComponent; + private readonly Animator _animator; + private readonly DictAtlasEntry _canSprite; + + private float _eatCountdown = 2100; + + private Vector2 _canPosition; + private Vector2 _canVelocity; + private float _canGravity = 0.035f; + private bool _isCanActive; + private bool _isEating; + + private bool _startEating; + + public ObjAlligator() : base("alligator") { } + + public ObjAlligator(Map.Map map, int posX, int posY) : base(map) + { + _canSprite = Resources.GetSprite("trade2"); + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/alligator"); + _animator.Play("idle"); + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-16, -24, 32, 24); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-13, -23)); + + var body = new BodyComponent(EntityPosition, -12, -16, 20, 16, 8); + _bodyDrawComponent = new BodyDrawComponent(body, sprite, 1); + + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + AddComponent(BodyComponent.Index, body); + AddComponent(CollisionComponent.Index, new BodyCollisionComponent(body, Values.CollisionTypes.Normal | Values.CollisionTypes.PushIgnore)); + AddComponent(InteractComponent.Index, new InteractComponent(body.BodyBox, Interact)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + + SpawnBanana(); + } + + private void SpawnBanana() + { + if (Game1.GameManager.SaveManager.GetString("trade2") == "1") + return; + + _gameObjectBanana = ObjectManager.GetGameObject(Map, "banana", null); + _gameObjectBanana.EntityPosition.Set(new Vector2((int)EntityPosition.X - 8, (int)EntityPosition.Y + 20)); + Map.Objects.SpawnObject(_gameObjectBanana); + } + + private void Update() + { + if (_startEating) + { + _startEating = false; + ThrowCan(); + } + + if (_isCanActive) + { + MapManager.ObjLink.UpdatePlayer = false; + + _canPosition += _canVelocity; + _canVelocity.Y += _canGravity * Game1.TimeMultiplier; + + if (_canPosition.Y > EntityPosition.Y - 7 - _canSprite.ScaledRectangle.Height) + { + _animator.Play("eat"); + _isCanActive = false; + _isEating = true; + } + } + + if (_isEating) + { + MapManager.ObjLink.UpdatePlayer = false; + + _eatCountdown -= Game1.DeltaTime; + if (_eatCountdown <= 0) + { + _isEating = false; + _animator.Play("idle"); + Game1.GameManager.StartDialogPath("alligator_after_eat"); + } + } + } + + private void ThrowCan() + { + _animator.Play("open"); + _isCanActive = true; + _canPosition = new Vector2( + EntityPosition.X - 2 - _canSprite.ScaledRectangle.Width, + EntityPosition.Y - 10 - _canSprite.ScaledRectangle.Height); + _canVelocity = new Vector2(0, -1f); + + Game1.GameManager.PlaySoundEffect("D360-36-24"); + } + + private void KeyChanged() + { + var value = Game1.GameManager.SaveManager.GetString("alligator_eat"); + if (value != null && value == "eat") + { + _startEating = true; + Game1.GameManager.SaveManager.SetString("alligator_eat", "nop"); + } + + var traded = Game1.GameManager.SaveManager.GetString("trade2"); + if (traded == "1" && _gameObjectBanana != null) + { + // remove the banana + Map.Objects.DeleteObjects.Add(_gameObjectBanana); + _gameObjectBanana = null; + } + } + + private bool Interact() + { + Game1.GameManager.StartDialogPath("alligator"); + return true; + } + + private void Draw(SpriteBatch spriteBatch) + { + // draw the alligator + _bodyDrawComponent.Draw(spriteBatch); + + // draw the can + if (_isCanActive) + DrawHelper.DrawNormalized(spriteBatch, _canSprite, _canPosition, Color.White); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjBallChildrenAttacked.cs b/InGame/GameObjects/NPCs/ObjBallChildrenAttacked.cs new file mode 100644 index 0000000..84450b9 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjBallChildrenAttacked.cs @@ -0,0 +1,182 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjBallChildrenAttacked : GameObject + { + private readonly AiComponent _aiComponent; + + private readonly ObjPersonNew _firstPerson; + private readonly ObjPersonNew _secondPerson; + + private readonly Rectangle _fieldRectangle; + + private readonly Vector2 _startPosition0; + private readonly Vector2 _startPosition1; + + private readonly Vector2 _centerPosition; + + private Vector2 _moveDirection0; + private Vector2 _moveDirection1; + private float _moveDistance0; + private float _moveDistance1; + + private const int MoveTime = 500; + + private float _npcGroundCount; + + private bool _musicPlaying; + + public ObjBallChildrenAttacked() : base("green_child") { } + + public ObjBallChildrenAttacked(Map.Map map, int posX, int posY, string spawnCondition) : base(map) + { + // check if the entity should get spawned + if (!string.IsNullOrEmpty(spawnCondition)) + { + var condition = SaveLoad.SaveCondition.GetConditionNode(spawnCondition); + if (!condition.Check()) + { + IsDead = true; + return; + } + } + + EntityPosition = new CPosition(posX, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _fieldRectangle = map.GetField(posX, posY); + + _centerPosition = new Vector2(posX + 24, posY); + + _firstPerson = new ObjPersonNew(Map, posX, posY, null, "npc_green_boy", "npc_kid_attacked", null, new Rectangle(0, 0, 14, 10)); + _secondPerson = new ObjPersonNew(Map, posX + 48, posY, null, "npc_red_boy", "npc_kid_attacked", null, new Rectangle(0, 0, 14, 10)); + + _firstPerson.DisableRotating(); + _secondPerson.DisableRotating(); + + _firstPerson.Animator.SpeedMultiplier = 2; + _secondPerson.Animator.SpeedMultiplier = 2; + + Map.Objects.SpawnObject(_firstPerson); + Map.Objects.SpawnObject(_secondPerson); + + _startPosition0 = _firstPerson.EntityPosition.Position; + _startPosition1 = _secondPerson.EntityPosition.Position; + + var stateIdle = new AiState(UpdateIdle); + var stateMove = new AiState { Init = InitMove }; + stateMove.Trigger.Add(new AiTriggerCountdown(MoveTime, MoveTick, MoveEnd)); + var stateMoved = new AiState(UpdateJumping); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("move", stateMove); + _aiComponent.States.Add("moved", stateMoved); + _aiComponent.ChangeState("idle"); + + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + private void Update() + { + // start/stop playing music + if (_fieldRectangle.Contains(MapManager.ObjLink.EntityPosition.Position)) + { + if (!_musicPlaying) + { + _musicPlaying = true; + Game1.GameManager.SetMusic(13, 2); + } + } + else + { + if (_musicPlaying) + { + _musicPlaying = false; + Game1.GameManager.SetMusic(-1, 2); + } + } + } + + private void InitMove() + { + _moveDirection0 = MapManager.ObjLink.EntityPosition.Position - _firstPerson.EntityPosition.Position; + _moveDirection1 = MapManager.ObjLink.EntityPosition.Position - _secondPerson.EntityPosition.Position; + + if (_moveDirection0 != Vector2.Zero) + _moveDirection0.Normalize(); + if (_moveDirection1 != Vector2.Zero) + _moveDirection1.Normalize(); + + // scale the distance the boys move so that they are approximately at the same height + _moveDistance0 = 14 / (1 - MathF.Abs(_moveDirection0.X) / 1.85f); + _moveDistance1 = 14 / (1 - MathF.Abs(_moveDirection1.X) / 1.85f); + } + + private void MoveTick(double counter) + { + MapManager.ObjLink.FreezePlayer(); + + var moveAmount = 1 - (float)(counter / MoveTime); + var person0Position = _startPosition0 + _moveDirection0 * _moveDistance0 * moveAmount; + var person1Position = _startPosition1 + _moveDirection1 * _moveDistance1 * moveAmount; + + _firstPerson.EntityPosition.Set(person0Position); + _secondPerson.EntityPosition.Set(person1Position); + } + + private void MoveEnd() + { + MoveTick(1); + _aiComponent.ChangeState("moved"); + Game1.GameManager.StartDialogPath("npc_kid_attacked"); + } + + private void UpdateIdle() + { + UpdateJumping(); + + // start walking towards the player? + var playerDirection = MapManager.ObjLink.EntityPosition.Position - _centerPosition; + var playerDistance = playerDirection.Length(); + if (playerDistance < 56) + { + if (playerDistance > 40) + _aiComponent.ChangeState("move"); + else + MoveEnd(); + } + } + + private void UpdateJumping() + { + if (_firstPerson.Body.IsGrounded) + { + _npcGroundCount -= Game1.DeltaTime; + if (_npcGroundCount < 0) + { + _firstPerson.Body.Velocity.Z = 1f; + _secondPerson.Body.Velocity.Z = 1f; + _npcGroundCount = 200; + } + } + + // look towards the player + var playerDistance = MapManager.ObjLink.EntityPosition.Position - _firstPerson.EntityPosition.Position; + if (playerDistance.Length() < 64) + { + var direction = playerDistance.Y < 0 ? "1" : "3"; + _firstPerson.Animator.Play("stand_" + direction); + _secondPerson.Animator.Play("stand_" + direction); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjBallGame.cs b/InGame/GameObjects/NPCs/ObjBallGame.cs new file mode 100644 index 0000000..ffd0915 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjBallGame.cs @@ -0,0 +1,152 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjBallGame : GameObject + { + private readonly Rectangle _shadowSourceRectangle = new Rectangle(0, 0, 65, 66); + private readonly DrawShadowSpriteComponent _shadowComponent; + private readonly AiComponent _aiComponent; + + private readonly ObjPersonNew _firstPerson; + private readonly ObjPersonNew _secondPerson; + + private readonly Vector2 _ballStart; + private readonly Vector2 _ballEnd; + + private float _throwCount; + private int _throwTime = 650; + private int _throwHeight = 12; + private int _throwDirection = 1; + + public ObjBallGame() : base("green_child") { } + + public ObjBallGame(Map.Map map, int posX, int posY, string spawnCondition) : base(map) + { + // check if the entity should get spawned + if (!string.IsNullOrEmpty(spawnCondition)) + { + var condition = SaveLoad.SaveCondition.GetConditionNode(spawnCondition); + if (!condition.Check()) + { + IsDead = true; + return; + } + } + + EntityPosition = new CPosition(posX, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _firstPerson = new ObjPersonNew(Map, posX, posY, null, "npc_boy_left", "npc_boy_ball_left", null, new Rectangle(0, 0, 14, 10)); + Map.Objects.SpawnObject(_firstPerson); + _secondPerson = new ObjPersonNew(Map, posX + 48, posY, null, "npc_boy_right", "npc_boy_ball_right", null, new Rectangle(0, 0, 14, 10)); + Map.Objects.SpawnObject(_secondPerson); + + var sourceRectangle = new Rectangle(338, 10, 6, 6); + + _ballStart = new Vector2(posX + 13, posY + 15); + _ballEnd = new Vector2(posX + 64 - 13, posY + 15); + + var statePreThrow = new AiState(); + statePreThrow.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("jumping"), 100, 200)); + var stateJump = new AiState(UpdateJump); + stateJump.Trigger.Add(new AiTriggerRandomTime(ToThrowJump, 500, 750)); + var stateJumpThrow = new AiState(UpdateJumpingThrowing); + stateJumpThrow.Trigger.Add(new AiTriggerRandomTime(ToThrow, 50, 200)); + var stateThrow = new AiState(UpdateThrow); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("preThrow", statePreThrow); + _aiComponent.States.Add("jumping", stateJump); + _aiComponent.States.Add("throwJump", stateJumpThrow); + _aiComponent.States.Add("throw", stateThrow); + _aiComponent.ChangeState("throw"); + + AddComponent(AiComponent.Index, _aiComponent); + var sprite = new CSprite(Resources.SprNpCs, EntityPosition, + sourceRectangle, new Vector2(-sourceRectangle.Width / 2, -sourceRectangle.Height)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerPlayer)); + + _shadowComponent = new DrawShadowSpriteComponent( + Resources.SprShadow, EntityPosition, _shadowSourceRectangle, + new Vector2(-4, -2), 1.0f, 0.0f); + _shadowComponent.Width = 8; + _shadowComponent.Height = 4; + AddComponent(DrawShadowComponent.Index, _shadowComponent); + } + + private void UpdateJump() + { + if (_throwDirection < 0 && _firstPerson.Body.IsGrounded) + _firstPerson.Body.Velocity.Z = 1f; + + if (_throwDirection > 0 && _secondPerson.Body.IsGrounded) + _secondPerson.Body.Velocity.Z = 1f; + } + + private void UpdateJumpingThrowing() + { + UpdateJump(); + UpdateThrow(); + } + + private void UpdateThrow() + { + _throwCount += Game1.DeltaTime * _throwDirection; + + if (_throwCount > _throwTime) + { + _throwDirection = -_throwDirection; + _throwCount = _throwTime; + _aiComponent.ChangeState("preThrow"); + } + else if (_throwCount < 0) + { + _throwDirection = -_throwDirection; + _throwCount = 0; + _aiComponent.ChangeState("preThrow"); + } + + var throwState = _throwCount / (float)_throwTime; + var newPosition = Vector2.Lerp(_ballStart, _ballEnd, throwState); + EntityPosition.Set(newPosition); + EntityPosition.Z = 3 + (float)Math.Sin(throwState * Math.PI) * _throwHeight; + _shadowComponent.Color = Color.White * (1 - (float)Math.Sin(throwState * Math.PI) * 0.5f); + } + + private void ToThrowJump() + { + if (_throwDirection < 0) + { + _secondPerson.Animator.Play("throw"); + StartThrow(); + } + else + { + _firstPerson.Animator.Play("throw"); + StartThrow(); + } + + _aiComponent.ChangeState("throwJump"); + } + + private void ToThrow() + { + _aiComponent.ChangeState("throw"); + } + + private void StartThrow() + { + var random = Game1.RandomNumber.Next(100, 200) / 100f; + _throwTime = (int)(random * 300); + _throwHeight = (int)(random * 6); + _throwCount = _throwCount > 0 ? _throwTime : 0; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjBat.cs b/InGame/GameObjects/NPCs/ObjBat.cs new file mode 100644 index 0000000..8edeb47 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjBat.cs @@ -0,0 +1,242 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjBat : GameObject + { + private readonly Animator _animator; + private readonly AiComponent _aiComponent; + private readonly CSprite _sprite; + + private readonly Rectangle _thunderTop = new Rectangle(444, 118, 14, 16); + private readonly Rectangle _thunderBottom = new Rectangle(476, 107, 32, 32); + + private readonly Vector2 _spawnPosition; + private readonly Vector2 _goalPosition; + + private readonly string _strKey; + private const int SpawnTime = 2500; + private const int DespawnTime = 750; + + private float _punishCount; + private bool _showThunder; + + public ObjBat() : base("npc_bat") { } + + public ObjBat(Map.Map map, int posX, int posY, string strKey) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 8, 0); + EntitySize = new Rectangle(-8, -8, 16, 16); + + // was already spawned? + _strKey = strKey; + if (!string.IsNullOrEmpty(_strKey) && + Game1.GameManager.SaveManager.GetString(_strKey) == "1") + { + IsDead = true; + return; + } + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/bat"); + _animator.Play("spawn"); + + _spawnPosition = new Vector2(posX + 8, posY + 8); + _goalPosition = new Vector2(_spawnPosition.X, _spawnPosition.Y - 35); + + _sprite = new CSprite(EntityPosition) { IsVisible = false }; + var animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero) { UpdateWithOpenDialog = true }; + + var stateIdle = new AiState(); + var stateSpawning = new AiState(UpdateLockPlayer) { Init = InitSpawn }; + stateSpawning.Trigger.Add(new AiTriggerCountdown(SpawnTime, TickSpawn, () => TickSpawn(0))); + var stateWaiting = new AiState(UpdateLockPlayer); + stateWaiting.Trigger.Add(new AiTriggerCountdown(1500, null, ToBat)); + var stateBat = new AiState(UpdateLockPlayer); + stateBat.Trigger.Add(new AiTriggerCountdown(1300, null, StartDialog)); + var stateThunder = new AiState(UpdateThunder); + var statePreDespawn = new AiState(UpdateLockPlayer); + statePreDespawn.Trigger.Add(new AiTriggerCountdown(125, null, () => _aiComponent.ChangeState("despawn"))); + var stateDespawn = new AiState() { Init = InitDespawn }; + stateDespawn.Trigger.Add(new AiTriggerCountdown(DespawnTime, TickDespawn, () => TickDespawn(0))); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("spawning", stateSpawning); + _aiComponent.States.Add("waiting", stateWaiting); + _aiComponent.States.Add("bat", stateBat); + _aiComponent.States.Add("thunder", stateThunder); + _aiComponent.States.Add("preDespawn", statePreDespawn); + _aiComponent.States.Add("despawn", stateDespawn); + _aiComponent.ChangeState("idle"); + + var hitBox = new CBox(EntityPosition, -8, -8, 0, 16, 16, 8); + AddComponent(HittableComponent.Index, new HittableComponent(hitBox, OnHit)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + //AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(_sprite)); + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + + Game1.GameManager.SaveManager.SetString("npcBatThunder", "0"); + } + + private void OnKeyChange() + { + var thunderState = Game1.GameManager.SaveManager.GetString("npcBatThunder"); + if (_aiComponent.CurrentStateId == "bat" && thunderState == "1") + ToThunder(); + else if (_aiComponent.CurrentStateId == "thunder" && thunderState == "0") + EndThunder(); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + // spawn the bat? + if (_aiComponent.CurrentStateId == "idle" && damageType == HitType.MagicPowder) + { + _aiComponent.ChangeState("spawning"); + + return Values.HitCollision.Enemy; + } + + return Values.HitCollision.None; + } + + private void InitSpawn() + { + SaveGameSaveLoad.FillSaveState(Game1.GameManager); + Game1.GameManager.SaveManager.EnableHistory(); + + if (!string.IsNullOrEmpty(_strKey)) + Game1.GameManager.SaveManager.SetString(_strKey, "1"); + + Game1.GameManager.PlaySoundEffect("D360-06-06"); + + _sprite.IsVisible = true; + + // spawn effect + var objAnimation = new ObjAnimator(Map, + (int)_spawnPosition.X - 8, (int)_spawnPosition.Y - 8, Values.LayerBottom, "Particles/spawn", "run", true); + Map.Objects.SpawnObject(objAnimation); + } + + private void TickSpawn(double time) + { + // update fairy position + if (time > 0) + { + var amount = (float)(time / SpawnTime); + var newPosition = Vector2.Lerp(_goalPosition, _spawnPosition, amount); + newPosition.X -= MathF.Sin(amount * 2 * MathF.PI * 4.5f) * 1.5f; + EntityPosition.Set(newPosition); + } + else + { + EntityPosition.Set(_goalPosition); + + _aiComponent.ChangeState("waiting"); + } + } + + private void UpdateLockPlayer() + { + MapManager.ObjLink.LockPlayer(); + } + + private void ToBat() + { + _aiComponent.ChangeState("bat"); + _animator.Play("bat"); + + Game1.GameManager.PlaySoundEffect("D378-12-0C"); + + // spawn effect + var objAnimation = new ObjAnimator(Map, + (int)EntityPosition.X, (int)EntityPosition.Y, Values.LayerTop, "Particles/explosionBomb", "run", true); + Map.Objects.SpawnObject(objAnimation); + } + + private void StartDialog() + { + Game1.GameManager.StartDialogPath("npcBat"); + } + + private void ToThunder() + { + _aiComponent.ChangeState("thunder"); + _animator.Play("attack"); + _showThunder = true; + + Game1.GameManager.PlaySoundEffect("D378-38-26"); + } + + private void UpdateThunder() + { + if (_showThunder) + { + _punishCount += Game1.DeltaTime; + Game1.GameManager.UseShockEffect = _punishCount % 100 < 50; + } + } + + private void EndThunder() + { + _aiComponent.ChangeState("preDespawn"); + _animator.Play("bat"); + _showThunder = false; + Game1.GameManager.UseShockEffect = false; + } + + private void InitDespawn() + { + Game1.GameManager.PlaySoundEffect("D360-59-3B"); + } + + private void TickDespawn(double state) + { + if (state > 0) + { + var amount = (float)(state / DespawnTime); + var newPosition = Vector2.Lerp(new Vector2(_goalPosition.X, _goalPosition.Y - 32), _goalPosition, MathF.Sin(amount * (MathF.PI / 2))); + EntityPosition.Set(newPosition); + _sprite.Color = Color.White * (float)Math.Clamp(amount / 0.25, 0, 1); + } + else + { + Map.Objects.DeleteObjects.Add(this); + } + } + + private void Draw(SpriteBatch spriteBatch) + { + // draw the alligator + _sprite.Draw(spriteBatch); + + // draw the thunder effect + if (!_showThunder) + return; + + var offsetY = 3; + var animationOffset = _punishCount % 133 < 66; + if (_punishCount > 0) + spriteBatch.Draw(Resources.SprNpCs, new Vector2(EntityPosition.X - 7, EntityPosition.Y + offsetY), + new Rectangle(_thunderTop.X + (animationOffset ? _thunderTop.Width + 1 : 0), _thunderTop.Y, _thunderTop.Width, _thunderTop.Height), Color.White); + if (_punishCount > 66) + spriteBatch.Draw(Resources.SprNpCs, new Vector2(EntityPosition.X - 7, EntityPosition.Y + offsetY + 16), + new Rectangle(_thunderTop.X + (animationOffset ? _thunderTop.Width + 1 : 0), _thunderTop.Y, _thunderTop.Width, _thunderTop.Height), Color.White); + if (_punishCount > 133) + spriteBatch.Draw(Resources.SprNpCs, new Vector2(EntityPosition.X - 16, EntityPosition.Y + offsetY + 32), + new Rectangle(_thunderBottom.X + (animationOffset ? _thunderBottom.Width + 1 : 0), _thunderBottom.Y, _thunderBottom.Width, _thunderBottom.Height), Color.White); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjBees.cs b/InGame/GameObjects/NPCs/ObjBees.cs new file mode 100644 index 0000000..2888f5e --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjBees.cs @@ -0,0 +1,145 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjBees : GameObject + { + private readonly BodyComponent _body; + private readonly Animator _animator; + private readonly GameObject _targetObject; + private readonly CSprite _sprite; + private Vector2 _targetOffset; + private Vector2 _directionOffset; + + private float _acceleration = 0.065f; + private float _moveSpeed = 1; + private float _offsetSpeed = 0.025f; + private float _targetDist = 12; + private int _offsetDist = 4; + + private float _fadeTime; + private float _fadeCounter; + private float _soundCounter; + + private bool _nearTarget; + private bool _followMode; + private bool _angryMode; + private bool _playSound; + + public ObjBees(Map.Map map, Vector2 position, GameObject targetObject, bool playSound) : base(map) + { + EntityPosition = new CPosition(position.X, position.Y, 0); + EntitySize = new Rectangle(-3, -5, 7, 7); + + _targetObject = targetObject; + _playSound = playSound; + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/bee"); + _animator.Play("idle"); + + _body = new BodyComponent(EntityPosition, -3, -5, 7, 7, 8) + { + CollisionTypes = Values.CollisionTypes.None, + VelocityTarget = new Vector2(-0.75f, 0.65f) + }; + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(0, 0)); + + AddComponent(BodyComponent.Index, _body); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(AnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerTop)); + } + + public void FadeAway(float fadeTime) + { + _fadeTime = fadeTime; + } + + public void SetAngryMode() + { + _angryMode = true; + _acceleration = 0.065f * 3.5f; + _moveSpeed = 3; + _targetDist = 8; + _offsetSpeed = 0.05f; + _offsetDist = 1; + } + + public void SetFollowMode(Vector2 offset) + { + _followMode = true; + _targetOffset = offset; + _acceleration = 0.35f + Game1.RandomNumber.Next(0, 11) / 200f; + _moveSpeed = 2.1f + Game1.RandomNumber.Next(0, 21) / 100f; + _targetDist = 8; + _offsetSpeed = 0.05f; + _offsetDist = 1; + } + + private void Update() + { + UpdateFade(); + + if (_angryMode && _playSound) + { + _soundCounter -= Game1.DeltaTime; + if(_soundCounter < 0) + { + _soundCounter += 25; + Game1.GameManager.PlaySoundEffect("D360-34-22", true, MathF.Sin((float)(Game1.TotalGameTime / 65)) * 0.125f + 0.875f, -MathF.Sin((float)(Game1.TotalGameTime / 65)) * 0.25f - 0.125f); + } + } + + // move towards the target + var targetDirection = (_targetObject.EntityPosition.Position + _targetOffset) - EntityPosition.Position; + var targetDistance = targetDirection.Length(); + if (targetDistance > _targetDist) + { + targetDirection.Normalize(); + + if (!_nearTarget) + { + _nearTarget = true; + _directionOffset = new Vector2(-targetDirection.Y, targetDirection.X); + } + _directionOffset = new Vector2(-targetDirection.Y, targetDirection.X); + + _body.VelocityTarget = AnimationHelper.MoveToTarget(_body.VelocityTarget, targetDirection * _moveSpeed, _acceleration * Game1.TimeMultiplier); + _body.VelocityTarget += _directionOffset * _offsetSpeed * Game1.TimeMultiplier; + } + else if (targetDirection != Vector2.Zero) + { + if (_nearTarget) + { + _nearTarget = false; + if (!_followMode) + _targetOffset = new Vector2( + Game1.RandomNumber.Next(0, _offsetDist * 2 + 1) - _offsetDist, + Game1.RandomNumber.Next(0, _offsetDist * 2 + 1) - _offsetDist); + } + } + } + + private void UpdateFade() + { + if (_fadeTime > 0) + { + _fadeCounter += Game1.DeltaTime; + if (_fadeCounter >= _fadeTime) + Map.Objects.DeleteObjects.Add(this); + + var percentage = _fadeCounter / _fadeTime; + _sprite.Color = Color.White * (1 - percentage); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjBird.cs b/InGame/GameObjects/NPCs/ObjBird.cs new file mode 100644 index 0000000..8714f3a --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjBird.cs @@ -0,0 +1,295 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjBird : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _damageState; + private readonly AiTriggerSwitch _changeDirectionSwitch; + private readonly DamageFieldComponent _damageField; + private readonly Animator _animator; + private readonly CSprite _sprite; + + private int _direction; + + private float _attackCounter; + private float _attackingCounter; + private float _attackTransparency; + private bool _attackMode; + private int _hitCounter; + + public ObjBird() : base("bird") { } + + public ObjBird(Map.Map map, int posX, int posY) : base(map) + { + var rectangle = new Rectangle(0, 0, 14, 8); + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -32, 16, 32); + + _body = new BodyComponent(EntityPosition, -6, -8, 12, 8, 8) + { + MoveCollision = OnCollision, + Bounciness = 0.25f, + Drag = 0.9f, + Gravity = -0.1f, + CollisionTypes = + Values.CollisionTypes.Normal | + Values.CollisionTypes.Player | + Values.CollisionTypes.NPCWall + }; + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/bird"); + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-8, -15)); + + var stateIdle = new AiState() { Init = InitIdle }; + stateIdle.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("walking"), 500, 1500)); + var stateWalking = new AiState(UpdateWalking) { Init = InitWalk }; + stateWalking.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("idle"), 750, 1500)); + stateWalking.Trigger.Add(_changeDirectionSwitch = new AiTriggerSwitch(250)); + var stateFleeIdle = new AiState(UpdateFleeState) { Init = InitIdle }; + stateFleeIdle.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("fleeingWalking"), 500, 1500)); + var stateFleeWalking = new AiState(UpdateFleeState) { Init = InitWalk }; + stateFleeWalking.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("fleeingIdle"), 750, 1500)); + var stateFleeing = new AiState(UpdateFleeing); + var stateAttack = new AiState(UpdateAttack); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("walking", stateWalking); + _aiComponent.States.Add("fleeingIdle", stateFleeIdle); + _aiComponent.States.Add("fleeingWalking", stateFleeWalking); + _aiComponent.States.Add("fleeing", stateFleeing); + _aiComponent.States.Add("attack", stateAttack); + _damageState = new AiDamageState(this, _body, _aiComponent, _sprite, 2); + _aiComponent.ChangeState(Game1.RandomNumber.Next(0, 10) < 5 ? "idle" : "walking"); + + var box = new CBox(EntityPosition, -6, -12, 0, 12, 12, 8, true); + + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(box, HitType.Enemy, 2) { IsActive = false }); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _sprite)); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, OnHit)); + } + + public void InitAttackMode() + { + _aiComponent.ChangeState("attack"); + + // spawn around the player + var radiant = Game1.RandomNumber.Next(0, 628) / 100f; + var offset = new Vector2(MathF.Sin(radiant), MathF.Cos(radiant)); + + var spawnPosition = MapManager.ObjLink.EntityPosition.Position + new Vector2(0, 24) + offset * 80; + EntityPosition.Set(spawnPosition); + EntityPosition.Z = 16; + + _damageField.IsActive = true; + + var direction = MapManager.ObjLink.EntityPosition.Position - new Vector2(EntityPosition.Position.X, EntityPosition.Position.Y - 16); + if (direction != Vector2.Zero) + direction.Normalize(); + _body.VelocityTarget = direction * 1.5f; + + _body.IgnoresZ = true; + _body.CollisionTypes = Values.CollisionTypes.None; + + _direction = _body.VelocityTarget.X < 0 ? 0 : 1; + _animator.Play("walk_" + _direction); + _animator.SpeedMultiplier = 2; + } + + private void UpdateAttack() + { + _attackingCounter += Game1.DeltaTime; + + var target = _attackingCounter < 2000 ? 1 : 0; + _attackTransparency = AnimationHelper.MoveToTarget(_attackTransparency, target, 0.1f * Game1.TimeMultiplier); + _sprite.Color = Color.White * _attackTransparency; + + Game1.GameManager.PlaySoundEffect("D378-45-2D", false); + + if (_attackTransparency == 0) + Map.Objects.DeleteObjects.Add(this); + } + + private void SpawnBirds() + { + if (!_attackMode) + return; + + var playerDir = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDir.Length() > 120) + { + _attackMode = false; + + // change back into the normal mode + if (_aiComponent.CurrentStateId != "idle" && + _aiComponent.CurrentStateId != "walking") + _aiComponent.ChangeState("idle"); + } + + Game1.GameManager.PlaySoundEffect("D370-19-13", false); + + _attackCounter -= Game1.DeltaTime; + if (_attackCounter < 0) + { + _attackCounter += Game1.RandomNumber.Next(300, 550); + + var objBird = new ObjBird(Map, (int)EntityPosition.X, (int)EntityPosition.Y); + objBird.InitAttackMode(); + Map.Objects.SpawnObject(objBird); + } + } + + private void InitIdle() + { + // stop and wait + _body.VelocityTarget = Vector2.Zero; + _animator.Play("idle_" + _direction); + } + + private void InitWalk() + { + // change the direction + var rotation = Game1.RandomNumber.Next(0, 628) / 100f; + _body.VelocityTarget = new Vector2( + (float)Math.Sin(rotation), + (float)Math.Cos(rotation)) * Game1.RandomNumber.Next(25, 40) / 100f; + + UpdateAnimation(); + } + + private void UpdateWalking() + { + // jump while walking + if (_body.IsGrounded) + _body.Velocity.Z = 0.65f; + } + + private void UpdateFleeState() + { + SpawnBirds(); + + // start fleeing from the player + var distance = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + if (distance.Length() < 32) + _aiComponent.ChangeState("fleeing"); + } + + private void UpdateFleeing() + { + SpawnBirds(); + + // flee from the player + var playerDir = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + + // stop fleeing + if (playerDir.Length() > 48) + { + _aiComponent.ChangeState("fleeingIdle"); + return; + } + + if (playerDir != Vector2.Zero) + playerDir.Normalize(); + _body.VelocityTarget = playerDir; + + UpdateAnimation(); + } + + private void UpdateAnimation() + { + _direction = _body.VelocityTarget.X < 0 ? 0 : 1; + _animator.Play("walk_" + _direction); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_damageState.IsInDamageState()) + return Values.HitCollision.None; + + _damageState.SetDamageState(); + + // start spawning other birds + _hitCounter++; + if (_hitCounter > 35) + _attackMode = true; + + Game1.GameManager.PlaySoundEffect("D360-03-03"); + Game1.GameManager.PlaySoundEffect("D370-19-13"); + _aiComponent.ChangeState("fleeing"); + + Game1.GameManager.StartDialogPath("bird_hit"); + + _body.Velocity.X = direction.X * 3.5f; + _body.Velocity.Y = direction.Y * 3.5f; + + return Values.HitCollision.Blocking; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Continues) + { + // push the bird away + _body.Velocity = new Vector3(direction.X, direction.Y, 0) * 0.65f; + + // try to walk away from the pusher + if (_aiComponent.CurrentStateId != "idle") + return true; + + _aiComponent.ChangeState("walking"); + + var offsetAngle = MathHelper.ToRadians(Game1.RandomNumber.Next(45, 85) * (_direction * 2 - 1)); + var newDirection = new Vector2( + direction.X * (float)Math.Cos(offsetAngle) - + direction.Y * (float)Math.Sin(offsetAngle), + direction.X * (float)Math.Sin(offsetAngle) + + direction.Y * (float)Math.Cos(offsetAngle)) * 0.5f; + _body.VelocityTarget = newDirection; + + UpdateAnimation(); + } + else if (type == PushableComponent.PushType.Impact) + { + _body.Velocity = new Vector3(direction.X, direction.Y, _body.Velocity.Z); + } + + return true; + } + + private void OnCollision(Values.BodyCollision moveCollision) + { + if ((moveCollision & Values.BodyCollision.Floor) != 0) + return; + + // can only change the direction every so often + if (!_changeDirectionSwitch.State) + return; + _changeDirectionSwitch.Reset(); + + // rotate after wall collision + if ((moveCollision & Values.BodyCollision.Horizontal) != 0) + _body.VelocityTarget.X = -_body.VelocityTarget.X * 0.5f; + else if ((moveCollision & Values.BodyCollision.Vertical) != 0) + _body.VelocityTarget.Y = -_body.VelocityTarget.Y * 0.5f; + + UpdateAnimation(); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjBowWow.cs b/InGame/GameObjects/NPCs/ObjBowWow.cs new file mode 100644 index 0000000..e58e222 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjBowWow.cs @@ -0,0 +1,464 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Enemies; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + class ObjBowWow : GameObject + { + private readonly List _enemyList = new List(); + private GameObject _enemyTarget; + + private readonly ObjChain _chain; + + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiTriggerSwitch _changeDirectionSwitch; + + private Animator _animator; + + private Vector2 _chainPull; + private Vector2 _origin; + private Vector2 _currentDirectionOffset; + private Vector2 _treasurePosition; + + private float _outsideCounter; + private int _direction; + private bool _followMode; + + public ObjBowWow() : base("bowwow") { } + + public ObjBowWow(Map.Map map, int posX, int posY, string mode) : base(map) + { + EntityPosition = new CPosition(posX, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _origin = new Vector2(posX + 8, posY + 8); + + var state = Game1.GameManager.SaveManager.GetString("bowWow"); + + // cave bowwow + if (mode == "cave") + { + // only spawn at the right state + if (state == "1") + { + EntityPosition.Set(new Vector2(EntityPosition.X - 8, EntityPosition.Y)); + _followMode = false; + } + else + { + IsDead = true; + } + } + else + { + // bowwow is in the cave + if (state == "1") + IsDead = true; + // bowwow is following the player + if (state == "2" || state == "3") + _followMode = true; + } + + if (string.IsNullOrEmpty(mode) && state != "2" && state != "3") + IsDead = true; + + if (IsDead) + return; + + _body = new BodyComponent(EntityPosition, -7, -10, 14, 10, 16) + { + MoveCollision = OnCollision, + Gravity = -0.175f, + CollisionTypes = Values.CollisionTypes.Normal | Values.CollisionTypes.NPCWall + }; + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/BowWow"); + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -16)); + + var stateIdle = new AiState(UpdateIdle); + stateIdle.Trigger.Add(new AiTriggerRandomTime(EndIdle, 500, 1500)); + var stateWalking = new AiState(UpdateWalking) { Init = InitWalking }; + stateWalking.Trigger.Add(new AiTriggerRandomTime(EndWalking, 500, 1000)); + stateWalking.Trigger.Add(_changeDirectionSwitch = new AiTriggerSwitch(250)); + var stateAttack = new AiState(UpdateAttack); + var stateTreasure = new AiState(UpdateTreasure); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("walking", stateWalking); + _aiComponent.States.Add("attack", stateAttack); + _aiComponent.States.Add("treasure", stateTreasure); + _aiComponent.ChangeState("walking"); + + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite) { ShadowWidth = 12, ShadowHeight = 5 }); + // add key change listener + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + + if (!_followMode) + { + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, OnHit)); + } + + // spawn the chain + Map.Objects.SpawnObject(_chain = new ObjChain(map, _origin)); + _currentDirectionOffset = AnimationHelper.DirectionOffset[_direction]; + + SetFollowMode(_followMode); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + return Values.HitCollision.RepellingParticle; + } + + public override void Init() + { + // set the position to the one of the player + if (_followMode && MapManager.ObjLink.NextMapPositionEnd.HasValue) + { + EntityPosition.Set(MapManager.ObjLink.NextMapPositionEnd.Value); + _chain.SetChainPosition(MapManager.ObjLink.NextMapPositionEnd.Value); + } + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X, direction.Y, 0.25f); + + return true; + } + + private void KeyChanged() + { + var state = Game1.GameManager.SaveManager.GetString("bowWow"); + if (state != null && state == "2") + SetFollowMode(true); + } + + private void SetFollowMode(bool follow) + { + _followMode = follow; + _body.CollisionTypes = follow ? Values.CollisionTypes.None : (Values.CollisionTypes.Normal | Values.CollisionTypes.NPCWall); + } + + private void ToIdle() + { + _aiComponent.ChangeState("idle"); + + // stop and wait + _body.VelocityTarget.X = 0; + _body.VelocityTarget.Y = 0; + } + + private void UpdateIdle() + { + UpdatePosition(); + } + + private void EndIdle() + { + _treasurePosition = GetTreasurePosition(); + if (_treasurePosition != Vector2.Zero) + { + var direction = _treasurePosition - EntityPosition.Position; + if (direction != Vector2.Zero) + direction.Normalize(); + _body.VelocityTarget = direction * 1.5f; + + // update the animation + _direction = AnimationHelper.GetDirection(_body.VelocityTarget); + _animator.Play("walk_" + _direction); + + _aiComponent.ChangeState("treasure"); + return; + } + + if (!_followMode || Game1.RandomNumber.Next(0, 100) < 35) + _aiComponent.ChangeState("walking"); + else + ToAttack(); + } + + private void InitWalking() + { + float rotation = 1; + if (_followMode) + { + // the farther away the enemy is from the origin the more likely it becomes that he will move towards the center position + var origin = MapManager.ObjLink.EntityPosition.Position - new Vector2(0, 4); + var directionToStart = origin - EntityPosition.Position; + var radiusToCenter = MathF.Atan2(directionToStart.Y, directionToStart.X); + + var maxDistanceX = 64.0f; + var maxDistanceY = 64.0f; + var distanceMultiplier = MathHelper.Clamp( + MathF.Min( + (maxDistanceX - MathF.Abs(directionToStart.X)) / maxDistanceX, + (maxDistanceY - MathF.Abs(directionToStart.Y)) / maxDistanceY), 0, 1); + + rotation = radiusToCenter + (MathF.PI - Game1.RandomNumber.Next(0, 628) / 100f) * distanceMultiplier; + } + else + { + rotation = Game1.RandomNumber.Next(0, 628) / 100f; + } + + + // change the direction + SetWalkDirection(new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation))); + } + + private void SetWalkDirection(Vector2 direction) + { + _body.VelocityTarget = direction * Game1.RandomNumber.Next(25, 40) / 25f; + + _direction = AnimationHelper.GetDirection(_body.VelocityTarget); + _animator.Play("walk_" + _direction); + } + + private void UpdateWalking() + { + if (_body.IsGrounded) + _body.Velocity.Z = 1.25f; + + UpdatePosition(); + } + + private void EndWalking() + { + if (!_followMode || Game1.RandomNumber.Next(0, 100) < 35) + _aiComponent.ChangeState("walking"); + else + ToAttack(); + + ToIdle(); + } + + private void ToAttack() + { + // search for an enemy to attack + Map.Objects.GetGameObjectsWithTag(_enemyList, Values.GameObjectTag.Enemy, + (int)MapManager.ObjLink.EntityPosition.Position.X - 50, + (int)MapManager.ObjLink.EntityPosition.Position.Y - 50, 100, 100); + + // choose a random enemy to attack + if (_enemyList.Count > 0) + { + var randomIndex = Game1.RandomNumber.Next(0, _enemyList.Count); + _enemyTarget = _enemyList[randomIndex]; + + // try finding a goponga flower and attack them first + for (var i = 0; i < _enemyList.Count; i++) + { + if (!_enemyTarget.IsActive) + _enemyTarget = _enemyList[(randomIndex + i) % _enemyList.Count]; + + if (_enemyTarget is EnemyGopongaFlower || _enemyTarget is EnemyGopongaFlowerGiant) + break; + } + } + + if (_enemyTarget != null && _enemyTarget.IsActive) + { + // set the attack direction + var damageState = (HittableComponent)_enemyTarget.Components[HittableComponent.Index]; + var direction = damageState.HittableBox.Box.Center - new Vector2(EntityPosition.X, EntityPosition.Y - 8); + if (direction != Vector2.Zero) + direction.Normalize(); + _body.VelocityTarget = direction * 3; + + // update the animation + _direction = AnimationHelper.GetDirection(_body.VelocityTarget); + _animator.Play("walk_" + _direction); + + _aiComponent.ChangeState("attack"); + + return; + } + + _enemyTarget = null; + + ToIdle(); + } + + private Vector2 GetTreasurePosition() + { + var digPositionX = (int)EntityPosition.X / 16; + var digPositionY = (int)EntityPosition.Y / 16; + + for (var y = digPositionY - 3; y < digPositionY + 3; y++) + { + if (y < 0 || Map.DigMap.GetLength(1) <= y) + continue; + + for (int x = digPositionX - 3; x < digPositionX + 3; x++) + { + if (x < 0 || Map.DigMap.GetLength(0) <= x) + continue; + + // do not look at the current position + if (x == digPositionX && y == digPositionY) + continue; + + if (Map.HoleMap.ArrayTileMap[x, y, 0] < 0 && Map.DigMap[x, y].Contains(':')) + { + // check if the item has already been dug out + var split = Map.DigMap[x, y].Split(':'); + if (Game1.GameManager.SaveManager.GetString(split[1], "0") != "1") + return new Vector2(x * 16 + 8, y * 16 + 8); + } + } + } + + return Vector2.Zero; + } + + private void UpdateAttack() + { + var damageState = (HittableComponent)_enemyTarget.Components[HittableComponent.Index]; + var direction = damageState.HittableBox.Box.Center - new Vector2(EntityPosition.X, EntityPosition.Y - 8); + + // attack the enemy if we are close enough + if (direction.Length() < 5) + { + // already removed from the map? + if (_enemyTarget.Map != null) + damageState?.Hit(this, _body.VelocityTarget * 0.1f, HitType.BowWow, 8, false); + + ToIdle(); + } + + if (_body.VelocityTarget == Vector2.Zero) + { + ToIdle(); + } + + UpdatePosition(); + } + + private void UpdateTreasure() + { + var direction = _treasurePosition - EntityPosition.Position; + + // move to the treasure + if (direction.Length() < 5) + { + // already removed from the map? + Game1.GameManager.StartDialogPath("bowWow_dig"); + ToIdle(); + } + + UpdatePosition(); + } + + private void UpdatePosition() + { + if (_followMode) + _origin = MapManager.ObjLink.EntityPosition.Position - new Vector2(0, 4); + + // limit the position + var distance = (EntityPosition.Position + + new Vector2(_body.VelocityTarget.X + _body.Velocity.X, _body.VelocityTarget.Y + _body.Velocity.Y) * Game1.TimeMultiplier - new Vector2(0, 4)) - _origin; + var dist = distance.Length(); + if (dist > 46) + { + // chain pull + var dir = distance; + dir.Normalize(); + var newPosition = _origin + dir * 46 + new Vector2(0, 4); + + var direction = newPosition - EntityPosition.Position; + if (direction.Length() > 0) + direction.Normalize(); + + var mult = 0.125f + Math.Clamp((dist - 46) / 4, 0, 4); + _chainPull = direction * mult; + + if (_followMode) + { + // are we moving outside of the range? + if (dist < (distance + _body.VelocityTarget).Length()) + _body.VelocityTarget = AnimationHelper.MoveToTarget(_body.VelocityTarget, Vector2.Zero, Game1.TimeMultiplier); + + _outsideCounter -= Game1.DeltaTime; + if (_outsideCounter <= 0) + { + _outsideCounter += 350; + SetWalkDirection(direction); + _body.VelocityTarget *= 1.5f; + _aiComponent.ChangeState("walking", true); + } + } + } + else + { + _outsideCounter = 350; + } + + _body.AdditionalMovementVT = _chainPull; + _chainPull *= (float)Math.Pow(0.75f, Game1.TimeMultiplier); + + UpdateChain(); + } + + private void UpdateChain() + { + // update the chain + var directionOffset = AnimationHelper.DirectionOffset[_direction] * new Vector2(6, 3); + _currentDirectionOffset = Vector2.Lerp(_currentDirectionOffset, directionOffset, Game1.TimeMultiplier * 0.25f); + + var startPosition = new Vector3(_origin.X, _origin.Y, _followMode ? MapManager.ObjLink.EntityPosition.Z : 0); + var goalPosition = new Vector3( + EntityPosition.Position.X - _currentDirectionOffset.X, + EntityPosition.Position.Y - 4 - _currentDirectionOffset.Y, + EntityPosition.Z); + + startPosition.Z = MathHelper.Clamp(startPosition.Z, 0, 12); + + _chain.UpdateChain(startPosition, goalPosition); + } + + private void OnCollision(Values.BodyCollision moveCollision) + { + // rotate after wall collision + // top collision + if ((moveCollision & Values.BodyCollision.Horizontal) != 0) + { + if (!_changeDirectionSwitch.State) + return; + _changeDirectionSwitch.Reset(); + + _body.VelocityTarget.X = -_body.VelocityTarget.X * 0.5f; + } + // vertical collision + else if ((moveCollision & Values.BodyCollision.Vertical) != 0) + { + _body.VelocityTarget.Y = -_body.VelocityTarget.Y * 0.5f; + } + + if ((moveCollision & (Values.BodyCollision.Vertical | Values.BodyCollision.Horizontal)) != 0) + { + _direction = AnimationHelper.GetDirection(_body.VelocityTarget); + _animator.Play("walk_" + _direction); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjBowWowSmall.cs b/InGame/GameObjects/NPCs/ObjBowWowSmall.cs new file mode 100644 index 0000000..9714b16 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjBowWowSmall.cs @@ -0,0 +1,169 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + class ObjBowWowSmall : GameObject + { + private readonly Animator _animator; + private readonly AiComponent _aiComponent; + private readonly BodyComponent _body; + private readonly AiTriggerSwitch _changeDirectionSwitch; + + private string _traded; + private string _name; + private int _direction; + + public ObjBowWowSmall() : base("smallBowWow") { } + + public ObjBowWowSmall(Map.Map map, int posX, int posY, string name) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _name = name; + + _body = new BodyComponent(EntityPosition, -5, -8, 10, 8, 8) + { + MoveCollision = OnCollision, + CollisionTypes = Values.CollisionTypes.Normal | + Values.CollisionTypes.NPCWall, + FieldRectangle = map.GetField(posX, posY), + Gravity = -0.15f + }; + + OnKeyChange(); + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/bowWowSmall"); + _animator.Play("walk_" + _traded + "0"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, Vector2.Zero); + + var stateIdle = new AiState(); + stateIdle.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("walking"), 500, 1500)); + var stateWalking = new AiState(UpdateWalking) { Init = InitWalk }; + stateWalking.Trigger.Add(new AiTriggerRandomTime(ToIdle, 750, 1500)); + stateWalking.Trigger.Add(_changeDirectionSwitch = new AiTriggerSwitch(250)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("walking", stateWalking); + _aiComponent.ChangeState(Game1.RandomNumber.Next(0, 10) < 5 ? "idle" : "walking"); + + if (!string.IsNullOrEmpty(_name)) + { + var interactionBox = new CBox(EntityPosition, -8, -16, 16, 16, 8); + AddComponent(InteractComponent.Index, new InteractComponent(interactionBox, Interact)); + } + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(_body.BodyBox, Values.CollisionTypes.Normal)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, OnHit)); + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + } + + private void OnKeyChange() + { + // show the ribbon on the head? + _traded = (_name == "bowWow3" && Game1.GameManager.SaveManager.GetString("trade1") == "1") ? "r_" : ""; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + _body.Velocity.X += direction.X; + _body.Velocity.Y += direction.Y; + + return Values.HitCollision.Blocking; + } + + private void ToIdle() + { + _aiComponent.ChangeState("idle"); + + // stop and wait + _body.VelocityTarget.X = 0; + _body.VelocityTarget.Y = 0; + } + + private void InitWalk() + { + // change the direction + var rotation = Game1.RandomNumber.Next(0, 628) / 100f; + _body.VelocityTarget = new Vector2( + (float)Math.Sin(rotation), + (float)Math.Cos(rotation)) * Game1.RandomNumber.Next(25, 40) / 50f; + _direction = _body.VelocityTarget.X < 0 ? 0 : 1; + + _animator.Play("walk_" + _traded + _direction); + } + + private void UpdateWalking() + { + // jump up and down while walking + if (_body.IsGrounded) + _body.Velocity.Z = 0.85f; + } + + private void OnCollision(Values.BodyCollision moveCollision) + { + // rotate after wall collision + // top collision + if (moveCollision.HasFlag(Values.BodyCollision.Horizontal)) + { + if (!_changeDirectionSwitch.State) + return; + _changeDirectionSwitch.Reset(); + + _body.VelocityTarget.X = -_body.VelocityTarget.X * 0.5f; + _direction = (_direction + 1) % 2; + _animator.Play("walk_" + _traded + _direction); + } + // vertical collision + else if (moveCollision.HasFlag(Values.BodyCollision.Vertical)) + { + _body.VelocityTarget.Y = -_body.VelocityTarget.Y * 0.5f; + } + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + // push bowwow away + _body.Velocity = new Vector3(direction.X, direction.Y, 0) * 0.65f; + + if (_aiComponent.CurrentStateId == "walking") + return false; + + _aiComponent.ChangeState("walking"); + + var offsetAngle = MathHelper.ToRadians(Game1.RandomNumber.Next(45, 85) * (_direction * 2 - 1)); + var newDirection = new Vector2( + direction.X * (float)Math.Cos(offsetAngle) - direction.Y * (float)Math.Sin(offsetAngle), + direction.X * (float)Math.Sin(offsetAngle) + direction.Y * (float)Math.Cos(offsetAngle)) * 0.5f; + _body.VelocityTarget = newDirection; + + _direction = _body.VelocityTarget.X < 0 ? 0 : 1; + _animator.Play("walk_" + _traded + _direction); + + return true; + } + + private bool Interact() + { + Game1.GameManager.PlaySoundEffect("D370-24-18"); + Game1.GameManager.StartDialogPath(_name); + + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjButterfly.cs b/InGame/GameObjects/NPCs/ObjButterfly.cs new file mode 100644 index 0000000..4b634b4 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjButterfly.cs @@ -0,0 +1,101 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjButterfly : GameObject + { + private Animator _animator; + private readonly Vector2 _startPosition; + private Vector2 _direction; + + private float _currentRotation; + private float _directionChange; + + private float _currentSpeed; + private float _lastSpeed; + private float _speedGoal; + + private float _flyCounter; + + private int _flyTime; + + private const int MinSpeed = 25; + private const int MaxSpeed = 45; + + // the butterfly will stay around this distance from the start point + private int _startDistance; + + public ObjButterfly() : base("butterfly") { } + + public ObjButterfly(Map.Map map, int posX, int posY) : base(map) + { + _startPosition = new Vector2(posX, posY); + EntityPosition = new CPosition(posX + 8, posY + 8 + 15, 15); + EntitySize = new Rectangle(-4, -24, 8, 24); + + _startDistance = Game1.RandomNumber.Next(25, 100); + _currentRotation = (Game1.RandomNumber.Next(0, 100) / 100f) * (float)(Math.PI * 2); + + _currentSpeed = Game1.RandomNumber.Next(MinSpeed, MaxSpeed) / 100f; + _lastSpeed = _currentSpeed; + _speedGoal = Game1.RandomNumber.Next(MinSpeed, MaxSpeed) / 100f; + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/butterfly"); + _animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, Vector2.Zero); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerTop)); + } + + public void Update() + { + _flyCounter -= Game1.DeltaTime; + + if (_flyCounter < 0) + { + _flyTime = Game1.RandomNumber.Next(500, 1000); + _flyCounter += _flyTime; + + // set a new speed goal + _lastSpeed = _speedGoal; + _speedGoal = Game1.RandomNumber.Next(MinSpeed, MaxSpeed) / 100f; + + var startDifference = EntityPosition.Position - _startPosition; + var targetRotation = Math.Atan2(startDifference.Y, startDifference.X); + var randomDirection = ((Game1.RandomNumber.Next(0, 20) - 10) / 6f) * ((float)Math.PI / (60 * (_flyCounter / 1000f))); + + var rotationDifference = (float)targetRotation - _currentRotation; + while (rotationDifference < 0) + rotationDifference += (float)Math.PI * 2; + rotationDifference = rotationDifference % (float)(Math.PI * 2); + rotationDifference -= (float)Math.PI; + + var newRotation = rotationDifference / (60 * (_flyCounter / 1000f)); + + // calculate the new rotation direction of the butterfly + // the farther away it is from the start position the more likely it is to rotate to face the start position + _directionChange = MathHelper.Lerp(randomDirection, newRotation, startDifference.Length() / _startDistance); + } + + // update the speed + _currentSpeed = MathHelper.Lerp(_speedGoal, _lastSpeed, _flyCounter / (float)_flyTime); + + // update direction + _currentRotation += _directionChange * Game1.TimeMultiplier; + _currentRotation = _currentRotation % (float)(Math.PI * 2); + _direction = new Vector2((float)Math.Cos(_currentRotation), (float)Math.Sin(_currentRotation)) * + (_animator.CurrentFrameIndex == 0 ? _currentSpeed : _currentSpeed * 1.125f); + EntityPosition.Move(_direction); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjChickenDude.cs b/InGame/GameObjects/NPCs/ObjChickenDude.cs new file mode 100644 index 0000000..5ef8f33 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjChickenDude.cs @@ -0,0 +1,212 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjChickenDude : GameObject + { + private readonly ObjAnimator _objChicken; + + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + + private Vector2 _direction; + private int _aniDirection; + + private string _dialogId; + private double _flyCounter; + private bool _flyingMode; + + private double _dialogCounter; + + private int FlyTime = 1000; + + private int _powderDir = -1; + + public ObjChickenDude() : base("npc_chicken_dude") { } + + public ObjChickenDude(Map.Map map, int posX, int posY, string dialogId) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _dialogId = dialogId; + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/npc_chicken_dude"); + _animator.Play("idle"); + + if (!string.IsNullOrEmpty(_dialogId) && Game1.GameManager.SaveManager.GetString(_dialogId) == "2") + { + _flyingMode = true; + _animator.Play("fly_forward_1"); + + _objChicken = new ObjAnimator(map, posX, posY, Values.LayerPlayer, "NPCs/cock", "stand_0", false); + _objChicken.Animator.SpeedMultiplier = 2; + map.Objects.SpawnObject(_objChicken); + + EntityPosition.Z = 16; + EntityPosition.AddPositionListener(typeof(ObjChickenDude), UpdateChickenPosition); + UpdateChickenPosition(EntityPosition); + + NewDirection(); + } + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -5, -10, 10, 10, 8) + { + Gravity = -0.15f, + Drag = 0.95f, + DragAir = 0.995f, + IgnoresZ = true, + JumpStartHeight = 8, + CollisionTypes = Values.CollisionTypes.Normal | Values.CollisionTypes.NPCWall, + MoveCollision = OnMoveCollision + }; + + var stateIdle = new AiState() { Init = InitIdle }; + stateIdle.Trigger.Add(new AiTriggerCountdown(250, null, () => _aiComponent.ChangeState("powder"))); + var statePowder = new AiState() { Init = InitPowder }; + statePowder.Trigger.Add(new AiTriggerCountdown(850, null, () => _aiComponent.ChangeState("idle"))); + var stateFlying = new AiState(UpdateFlying) { Init = InitIdle }; + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("powder", statePowder); + _aiComponent.States.Add("flying", stateFlying); + + _aiComponent.ChangeState(_flyingMode ? "flying" : "idle"); + + if (!string.IsNullOrEmpty(_dialogId) && !_flyingMode) + AddComponent(InteractComponent.Index, new InteractComponent(_body.BodyBox, Interact)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(CollisionComponent.Index, new BodyCollisionComponent(_body, Values.CollisionTypes.Normal | Values.CollisionTypes.PushIgnore)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite)); + } + + private void InitIdle() + { + _animator.Play("idle_" + _powderDir); + } + + private void InitPowder() + { + // change direction? + if (Game1.RandomNumber.Next(0, 3) == 0) + _powderDir = -_powderDir; + + _animator.Play("powder_" + _powderDir); + + var spawnPosition = new Vector2(EntityPosition.X + _powderDir * 10, EntityPosition.Y); + Map.Objects.SpawnObject(new ObjPowder(Map, spawnPosition.X, spawnPosition.Y, 0, false)); + } + + private void NewDirection() + { + var radDirection = Game1.RandomNumber.Next(0, 100) / 100f * MathF.PI * 2; + _direction = new Vector2(MathF.Sin(radDirection), MathF.Cos(radDirection)); + } + + private void StartMoving() + { + // do not move while the dialog is open + if (Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen) + return; + + _body.Velocity.X = _direction.X * 0.65f; + _body.Velocity.Y = _direction.Y * 0.65f; + } + + private void UpdateChickenPosition(CPosition newPosition) + { + _objChicken.EntityPosition.Set(new Vector3(newPosition.X, newPosition.Y, newPosition.Z + 16)); + } + + private void UpdateFlying() + { + DialogTriggerUpdate(); + + _flyCounter -= Game1.DeltaTime; + var _hoverCounter = (_flyCounter + FlyTime - FlyTime / 4) % FlyTime; + + if (_direction.X != 0) + _aniDirection = _direction.X < 0 ? -1 : 1; + + // we align the animation with the forward movement + if (FlyTime / 4 < _hoverCounter && _hoverCounter < FlyTime - FlyTime / 4) + _animator.Play("fly_stop_" + _aniDirection); + else + _animator.Play("fly_forward_" + _aniDirection); + + _objChicken.Animator.Play("stand_" + (_aniDirection == -1 ? 0 : 2)); + + // move up/down + EntityPosition.Z = 13 + (1.5f + MathF.Sin((float)_hoverCounter / FlyTime * MathF.PI * 2) * 1.5f); + + if (_flyCounter < 0) + { + _flyCounter += FlyTime; + // change the direction randomly + if (Game1.RandomNumber.Next(0, 4) == 0) + NewDirection(); + + StartMoving(); + } + } + + private void DialogTriggerUpdate() + { + if (Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen) + return; + + // start the dialgo when we are near the player + // make sure there to pause between the dialogs + if (_dialogCounter > 0) + _dialogCounter -= Game1.DeltaTime; + else + { + var playerDirection = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + if (playerDirection.Length() < 24) + { + Game1.GameManager.StartDialogPath(_dialogId); + _dialogCounter = 3500; + _body.Velocity = Vector3.Zero; + } + } + } + + private void OnMoveCollision(Values.BodyCollision collision) + { + // change the direction when we hit a wall + if ((collision & Values.BodyCollision.Horizontal) != 0) + { + _body.Velocity.X = -_body.Velocity.X; + _direction.X = -_direction.X; + } + if ((collision & Values.BodyCollision.Vertical) != 0) + { + _body.Velocity.Y = -_body.Velocity.Y; + _direction.Y = -_direction.Y; + } + } + + private bool Interact() + { + Game1.GameManager.StartDialogPath(_dialogId); + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjCock.cs b/InGame/GameObjects/NPCs/ObjCock.cs new file mode 100644 index 0000000..55f0fc4 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjCock.cs @@ -0,0 +1,383 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + public class ObjCock : GameObjectFollower + { + private ObjCockParticle _objParticle; + + private readonly BodyDrawComponent _drawComponent; + private readonly BodyDrawShadowComponent _shadowCompnent; + private readonly CarriableComponent _carriableCompnent; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly Animator _animator; + private readonly CSprite _sprite; + + private readonly string _saveKey; + + private const int CarryHeight = 14; + + private int _blinkTime; + private int _direction; + + private bool _isThrown; + private bool _slowReturn; + private bool _freezePlayer; + private bool _isActive = true; + + private const int FollowDistance = 18; + + public ObjCock() : base("cock") { } + + public ObjCock(Map.Map map, int posX, int posY, string saveKey) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _saveKey = saveKey; + // skeleton was already awakend? + if (_saveKey != null && Game1.GameManager.SaveManager.GetString(_saveKey) == "1") + { + IsDead = true; + return; + } + + // TODO_CHECK: must align with the player body + _body = new BodyComponent(EntityPosition, -4, -10, 8, 10, 8) + { + Bounciness = 0f, + Gravity = -0.075f, + Drag = 0.85f, + IsSlider = true, + CollisionTypes = Values.CollisionTypes.None, + }; + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/cock"); + _animator.Play("stand_3"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + // blink for ~1000ms + _blinkTime = (1000 / AiDamageState.BlinkTime) * AiDamageState.BlinkTime; + + var stateSkeleton = new AiState(); + var stateParticle = new AiState(UpdateParticle) { Init = InitParticle }; + var stateBlinking = new AiState(); + stateBlinking.Trigger.Add(new AiTriggerCountdown(_blinkTime, TickBlink, EndBlink)); + var statePreSpawn = new AiState(); + statePreSpawn.Trigger.Add(new AiTriggerCountdown(1100, null, ToSpawn)); + var stateSpawn = new AiState(); + stateSpawn.Trigger.Add(new AiTriggerCountdown(750, null, StartFollowing)); + // buffer state to not be one frame into a jump while showing the textbox + var statePreFollowing = new AiState(); + statePreFollowing.Trigger.Add(new AiTriggerCountdown(100, null, EndPreFollowing)); + var stateFollowing = new AiState(UpdateWalking) { Init = InitWalk }; + var stateThrown = new AiState(UpdateThrown); + var statePickedUp = new AiState(UpdatePickedUp); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("skeleton", stateSkeleton); + _aiComponent.States.Add("particle", stateParticle); + _aiComponent.States.Add("blinking", stateBlinking); + _aiComponent.States.Add("preSpawn", statePreSpawn); + _aiComponent.States.Add("spawn", stateSpawn); + _aiComponent.States.Add("preFollowing", statePreFollowing); + _aiComponent.States.Add("following", stateFollowing); + _aiComponent.States.Add("thrown", stateThrown); + _aiComponent.States.Add("pickedUp", statePickedUp); + + AddComponent(CarriableComponent.Index, _carriableCompnent = new CarriableComponent( + new CRectangle(EntityPosition, new Rectangle(-6, -14, 12, 14)), CarryInit, CarryUpdate, CarryThrow) + { CarryHeight = CarryHeight }); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(OcarinaListenerComponent.Index, new OcarinaListenerComponent(OnSongPlayed)); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(new CBox(EntityPosition, -8, -16, 16, 16, 8), Values.CollisionTypes.Normal)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, _drawComponent = new BodyDrawComponent(_body, _sprite, Values.LayerBottom)); + AddComponent(DrawShadowComponent.Index, _shadowCompnent = new BodyDrawShadowComponent(_body, _sprite) { IsActive = false }); + + // no saveKey => spawned by the player in the following state + if (_saveKey == null) + { + ToActiveState(); + _aiComponent.ChangeState("following"); + } + else + { + _animator.Play("skeleton"); + _aiComponent.ChangeState("skeleton"); + } + } + + public override void SetPosition(Vector2 position) + { + EntityPosition.Set(position); + } + + private void SetActive(bool isActive) + { + _isActive = isActive; + _drawComponent.IsActive = isActive; + _shadowCompnent.IsActive = isActive; + _carriableCompnent.IsActive = isActive; + } + + private void OnSongPlayed(int songIndex) + { + if (songIndex == 2 && _aiComponent.CurrentStateId == "skeleton") + _aiComponent.ChangeState("particle"); + } + + private void Update() + { + // do not follow the player into dungeons + if (Map.DungeonMode && _isActive) + SetActive(false); + if (!Map.DungeonMode && !_isActive) + SetActive(true); + + if (_freezePlayer) + MapManager.ObjLink.FreezePlayer(); + } + + private void ToActiveState() + { + ((DrawComponent)Components[DrawComponent.Index]).Layer = Values.LayerPlayer; + ((BodyDrawShadowComponent)Components[DrawShadowComponent.Index]).IsActive = true; + RemoveComponent(CollisionComponent.Index); + } + + private void InitParticle() + { + _freezePlayer = true; + + Game1.GameManager.SetMusic(84, 2); + + // spawn the particle + _objParticle = new ObjCockParticle(Map, new Vector2(EntityPosition.X, EntityPosition.Y - 8)); + Map.Objects.SpawnObject(_objParticle); + } + + private void UpdateParticle() + { + // start blinking when the particle hits the skeleton + if (!_objParticle.IsRunning()) + _aiComponent.ChangeState("blinking"); + } + + private void TickBlink(double time) + { + _sprite.SpriteShader = ((_blinkTime - time) % (AiDamageState.BlinkTime * 2) < AiDamageState.BlinkTime) ? Resources.DamageSpriteShader0 : null; + } + + private void EndBlink() + { + _sprite.SpriteShader = null; + _aiComponent.ChangeState("preSpawn"); + } + + private void ToSpawn() + { + // explosion + _animator.Play("spawn"); + ToActiveState(); + + Game1.GameManager.PlaySoundEffect("D378-12-0C"); + Game1.GameManager.SetMusic(-1, 2); + + // spawn explosion effect + var objAnimation = new ObjAnimator(Map, (int)EntityPosition.X, (int)EntityPosition.Y - 8, Values.LayerTop, "Particles/explosionBomb", "run", true); + Map.Objects.SpawnObject(objAnimation); + + _aiComponent.ChangeState("spawn"); + } + + private void StartFollowing() + { + Game1.GameManager.PlaySoundEffect("D368-16-10"); + + // add the rooster as a follower + var itemRooster = new GameItemCollected("rooster") { Count = 1 }; + MapManager.ObjLink.PickUpItem(itemRooster, false); + + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + _aiComponent.ChangeState("preFollowing"); + } + + private void EndPreFollowing() + { + _freezePlayer = false; + _animator.Play("stand_3"); + _aiComponent.ChangeState("following"); + } + + private void InitWalk() + { + SetThrowState(false); + } + + private void UpdateWalking() + { + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + var distance = playerDirection.Length(); + var playerSpeed = MapManager.ObjLink.LastMoveVector.Length(); + + // slowly transition to the full speed + var movementSpeed = MathHelper.Clamp((distance - FollowDistance) / 4, -2, 2); + if (Math.Abs(distance - FollowDistance) > FollowDistance + 4) + movementSpeed = MathHelper.Clamp(distance / (FollowDistance + 4), -2, 2); + // slowly walk back to the player after been thrown + if (_slowReturn) + movementSpeed = MathHelper.Clamp(movementSpeed, playerSpeed, 1); + + if (movementSpeed > 0 && !_isThrown) + { + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + + _body.Velocity.X = playerDirection.X * movementSpeed; + _body.Velocity.Y = playerDirection.Y * movementSpeed; + + _direction = AnimationHelper.GetDirection(playerDirection); + _animator.Play("stand_" + _direction); + } + + // stop slow return when we reached the player or the player is moving faster away than we are moving + if (!_isThrown && (distance <= FollowDistance || playerSpeed > 1)) + _slowReturn = false; + + // fly over deep water + if ((_body.CurrentFieldState & MapStates.FieldStates.DeepWater) != 0) + { + _body.IsGrounded = false; + _body.IgnoresZ = true; + var targetPosZ = 7.5f + MathF.Sin(((float)Game1.TotalGameTime / 1000) * MathF.PI * 2) * 1.5f; + EntityPosition.Z = AnimationHelper.MoveToTarget(EntityPosition.Z, targetPosZ, 1 * Game1.TimeMultiplier); + } + else + { + _body.IgnoresZ = false; + } + + // jump + if (_body.IsGrounded) + { + var jumpHeight = MathHelper.Clamp(distance / 18, 1, 2); + // while returning from a throw do not jump high + if (_slowReturn) + jumpHeight = 1; + + _body.Velocity.Z = jumpHeight; + } + } + + public void TargetVelocity(Vector2 targetVelocity, float maxSpeed, int direction) + { + // move towards the target velocity + var target = _body.VelocityTarget + targetVelocity * 0.05f * Game1.TimeMultiplier; + if (target.Length() > maxSpeed) + { + target.Normalize(); + target *= maxSpeed; + } + + _body.VelocityTarget = target; + + _direction = direction; + _animator.Play("stand_" + _direction); + } + + private void UpdatePickedUp() + { + if (!MapManager.ObjLink.IsFlying()) + MapManager.ObjLink.StartFlying(this); + + Game1.GameManager.PlaySoundEffect("D378-45-2D", false); + + // move up + var targetPosZ = 36 + MathF.Sin(((float)Game1.TotalGameTime / 450) * MathF.PI * 2) * 1.5f; + EntityPosition.Z = AnimationHelper.MoveToTarget(EntityPosition.Z, targetPosZ, 0.5f * Game1.TimeMultiplier); + + // lift the player up + if (EntityPosition.Z > CarryHeight) + MapManager.ObjLink.EntityPosition.Z = EntityPosition.Z - CarryHeight; + } + + private void UpdateThrown() + { + if (_body.IsGrounded) + { + _aiComponent.ChangeState("following"); + _body.Velocity.X = 0; + _body.Velocity.Y = 0; + } + } + + private void SetThrowState(bool thrown) + { + _isThrown = thrown; + _body.DragAir = thrown ? 0.975f : 0.85f; + } + + private Vector3 CarryInit() + { + _body.IgnoresZ = true; + _body.Velocity = Vector3.Zero; + _body.VelocityTarget = Vector2.Zero; + _body.CollisionTypes = MapManager.ObjLink._body.CollisionTypes; + + _animator.SpeedMultiplier = 2.0f; + _aiComponent.ChangeState("pickedUp"); + EntityPosition.AddPositionListener(typeof(ObjCock), OnPositionChange); + + return new Vector3(EntityPosition.X, EntityPosition.Y, EntityPosition.Z); + } + + private bool CarryUpdate(Vector3 position) + { + EntityPosition.Set(new Vector3(position.X, position.Y, position.Z)); + return true; + } + + private void CarryThrow(Vector2 direction) + { + _body.Velocity = new Vector3(direction.X, direction.Y, 0); + + MapManager.ObjLink.StopFlying(); + } + + public void StopFlying() + { + _body.IgnoresZ = false; + _body.IsGrounded = false; + _body.VelocityTarget = Vector2.Zero; + _body.CollisionTypes = Values.CollisionTypes.None; + + _slowReturn = true; + SetThrowState(true); + _animator.SpeedMultiplier = 1.0f; + _aiComponent.ChangeState("thrown"); + EntityPosition.RemovePositionListener(typeof(ObjCock)); + } + + private void OnPositionChange(CPosition newPosition) + { + if (MapManager.ObjLink.IsFlying()) + MapManager.ObjLink.SetPosition(new Vector2(newPosition.X, newPosition.Y)); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjColorDungeonNPC.cs b/InGame/GameObjects/NPCs/ObjColorDungeonNPC.cs new file mode 100644 index 0000000..79609bd --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjColorDungeonNPC.cs @@ -0,0 +1,129 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjColorDungeonNPC : GameObject + { + private readonly Animator _animator; + private readonly AnimationComponent _animationComponent; + + private readonly string _personId; + private readonly bool _isRed; + + private string _npcState; + private float _movementCounter; + private float _moveTime; + private bool _isMoving; + + private Vector2 _startPosition; + private Vector2 _endPosition; + private Vector2 _centerPosition; + private Vector2 _sidePosition; + + public ObjColorDungeonNPC() : base("npc_color_dungeon") { } + + public ObjColorDungeonNPC(Map.Map map, int posX, int posY, string personId, bool isRed) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _personId = personId; + _isRed = isRed; + + _centerPosition = new Vector2(EntityPosition.X + (_isRed ? -8 : 8), EntityPosition.Y); + _sidePosition = new Vector2(EntityPosition.X + (_isRed ? 11 : -11), EntityPosition.Y); + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/npc_color_dungeon_" + (isRed ? "red" : "blue")); + _animator.Play("idle"); + + // already moved? + _npcState = Game1.GameManager.SaveManager.GetString(_personId + "_state"); + if (_npcState == "1") + EntityPosition.Set(_centerPosition); + else if (_npcState == "2") + EntityPosition.Set(_sidePosition); + + var sprite = new CSprite(EntityPosition); + _animationComponent = new AnimationComponent(_animator, sprite, Vector2.Zero); + + var body = new BodyComponent(EntityPosition, -8, -16, 16, 16, 8); + + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + AddComponent(BodyComponent.Index, body); + AddComponent(CollisionComponent.Index, new BodyCollisionComponent(body, Values.CollisionTypes.Normal)); + AddComponent(InteractComponent.Index, new InteractComponent(body.BodyBox, Interact)); + AddComponent(BaseAnimationComponent.Index, _animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + } + + private void Update() + { + if (_isMoving) + { + // stop player from moving + MapManager.ObjLink.FreezePlayer(); + + _movementCounter += Game1.DeltaTime; + var movePercentage = MathHelper.Clamp(_movementCounter / _moveTime, 0, 1); + + var newPosition = Vector2.Lerp(_startPosition, _endPosition, movePercentage); + EntityPosition.Set(newPosition); + + // finished moving? + if (movePercentage >= 1) + { + _isMoving = false; + _animator.Play("idle"); + + // finished moving to the side => say something + if (_npcState == "2") + Game1.GameManager.StartDialogPath(_isRed ? "npc_color_3" : "npc_color_4"); + } + } + } + + private bool Interact() + { + Game1.GameManager.StartDialogPath(_personId); + return true; + } + + private void KeyChanged() + { + _npcState = Game1.GameManager.SaveManager.GetString(_personId + "_state"); + // start moving? + var moveString = _personId + "_move"; + var moveValue = Game1.GameManager.SaveManager.GetString(moveString); + + if (moveValue != null) + { + _animator.Play("walk"); + + _startPosition = EntityPosition.Position; + if (_npcState == "1") + _endPosition = _centerPosition; + else + _endPosition = _sidePosition; + + _animationComponent.MirroredH = _startPosition.X < _endPosition.X; + + // 0.375 move speed + _moveTime = Math.Abs(_startPosition.X - _endPosition.X) / 0.375f / 60f * 1000; + + _isMoving = true; + _movementCounter = 0; + + Game1.GameManager.SaveManager.RemoveString(moveString); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjDancingFish.cs b/InGame/GameObjects/NPCs/ObjDancingFish.cs new file mode 100644 index 0000000..b355e32 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjDancingFish.cs @@ -0,0 +1,43 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjDancingFish : GameObject + { + public BodyComponent Body; + public readonly Animator Animator; + + public ObjDancingFish(Map.Map map, Vector2 position) : base(map) + { + EntityPosition = new CPosition(position.X, position.Y, 0); + EntitySize = new Rectangle(-12, -14, 24, 18); + + Animator = AnimatorSaveLoad.LoadAnimator("NPCs/dance fish"); + Animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(Animator, sprite, Vector2.Zero); + + Body = new BodyComponent(EntityPosition, -8, -8, 16, 8, 8) + { + IgnoresZ = true + }; + + AddComponent(BodyComponent.Index, Body); + AddComponent(CollisionComponent.Index, new BodyCollisionComponent(Body, Values.CollisionTypes.Normal)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(Body, sprite, Values.LayerBottom)); + } + + private void Update() + { + + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjDog.cs b/InGame/GameObjects/NPCs/ObjDog.cs new file mode 100644 index 0000000..053bbf8 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjDog.cs @@ -0,0 +1,282 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Base.Systems; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjDog : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiDamageState _damageState; + private readonly AiTriggerSwitch _changeDirectionSwitch; + private readonly Animator _animator; + private readonly DamageFieldComponent _damageField; + + private Vector2 _marinPosition; + + private int _direction; + + public ObjDog() : base("dog") { } + + public ObjDog(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _body = new BodyComponent(EntityPosition, -6, -8, 12, 8, 8) + { + MoveCollision = OnCollision, + Gravity = -0.15f, + Drag = 0.75f, + DragAir = 0.95f, + AvoidTypes = Values.CollisionTypes.Hole | + Values.CollisionTypes.NPCWall, + }; + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/dog"); + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, Vector2.Zero); + + var stateIdle = new AiState() { Init = InitIdle }; + stateIdle.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("walking"), 500, 1500)); + var stateWalking = new AiState(UpdateWalking) { Init = InitWalking }; + stateWalking.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("idle"), 750, 1500)); + stateWalking.Trigger.Add(_changeDirectionSwitch = new AiTriggerSwitch(250)); + var stateListening = new AiState(UpdateListening); + var statePreAttack = new AiState(); + statePreAttack.Trigger.Add(new AiTriggerCountdown(500, null, () => _aiComponent.ChangeState("attack"))); + var stateAttack = new AiState(UpdateAttack) { Init = InitAttack }; + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("walking", stateWalking); + _aiComponent.States.Add("listening", stateListening); + _aiComponent.States.Add("preAttack", statePreAttack); + _aiComponent.States.Add("attack", stateAttack); + _damageState = new AiDamageState(this, _body, _aiComponent, sprite, 2); + _aiComponent.ChangeState(Game1.RandomNumber.Next(0, 10) < 5 ? "idle" : "walking"); + + var box = new CBox(EntityPosition, -7, -14, 14, 14, 8); + + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(box, HitType.Enemy, 2) { IsActive = false }); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(InteractComponent.Index, new InteractComponent(_body.BodyBox, Interact)); + AddComponent(HittableComponent.Index, new HittableComponent(box, OnHit)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite) { ShadowWidth = 10 }); + } + + private void OnKeyChange() + { + var marinPosition = Game1.GameManager.SaveManager.GetString("marin_sing_position"); + if (!string.IsNullOrEmpty(marinPosition)) + { + var splitString = marinPosition.Split(','); + if (splitString.Length == 2) + { + int.TryParse(splitString[0], out int posX); + int.TryParse(splitString[1], out int posY); + + _marinPosition = new Vector2(posX, posY); + } + } + else + { + _marinPosition = Vector2.Zero; + } + } + + private void InitIdle() + { + // stop and wait + _body.VelocityTarget.X = 0; + _body.VelocityTarget.Y = 0; + _body.CollisionTypes = Values.CollisionTypes.Normal | Values.CollisionTypes.NPCWall; + + _animator.Play("idle_" + _direction); + } + + private void InitWalking() + { + // change the direction + var rotation = Game1.RandomNumber.Next(0, 628) / 100f; + var speed = Game1.RandomNumber.Next(40, 55) / 100f; + + _body.VelocityTarget = new Vector2((float)Math.Sin(rotation), (float)Math.Cos(rotation)) * speed; + + UpdateAnimation(); + } + + private void UpdateWalking() + { + // jump up and down while walking + if (_body.IsGrounded) + { + _body.Velocity.Z = 0.85f; + + if (_marinPosition != Vector2.Zero) + { + var direction = _marinPosition - EntityPosition.Position; + var distance = direction.Length(); + + if (distance < 24) + { + _body.Velocity.Z = 0; + _body.VelocityTarget = Vector2.Zero; + + _direction = direction.X < 0 ? 0 : 1; + _animator.Play("idle_" + _direction); + + _aiComponent.ChangeState("listening"); + } + else if (distance < 64) + { + if (direction != Vector2.Zero) + direction.Normalize(); + + _body.VelocityTarget = direction * 0.5f; + + UpdateAnimation(); + } + } + } + } + + private void UpdateListening() + { + if (_marinPosition == Vector2.Zero) + _aiComponent.ChangeState("walking"); + } + + private void InitAttack() + { + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + + _body.VelocityTarget = playerDirection * 3; + _body.CollisionTypes = Values.CollisionTypes.Normal | Values.CollisionTypes.NPCWall; + _body.IsGrounded = false; + _body.Velocity.Z = 1.45f; + + _damageField.IsActive = true; + + UpdateAnimation(); + } + + private void UpdateAttack() + { + // finished attacking? + if (_body.IsGrounded) + { + _damageField.IsActive = false; + _aiComponent.ChangeState("idle"); + } + } + + private void UpdateAnimation() + { + _direction = _body.VelocityTarget.X < 0 ? 0 : 1; + _animator.Play("idle_" + _direction); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (_aiComponent.CurrentStateId == "preAttack" || + _aiComponent.CurrentStateId == "attack") + return false; + + if (type == PushableComponent.PushType.Continues) + { + // push the dog away + SystemBody.MoveBody(_body, new Vector2(direction.X, direction.Y) * 0.33f * Game1.TimeMultiplier, _body.CollisionTypes, false, false, false); + _body.Position.NotifyListeners(); + + if (_aiComponent.CurrentStateId == "walking") + return true; + + // start moving away from the pusher + _aiComponent.ChangeState("walking"); + + var offsetAngle = MathHelper.ToRadians(Game1.RandomNumber.Next(55, 85) * (Game1.RandomNumber.Next(0, 2) * 2 - 1)); + var newDirection = new Vector2( + direction.X * (float)Math.Cos(offsetAngle) - direction.Y * (float)Math.Sin(offsetAngle), + direction.X * (float)Math.Sin(offsetAngle) + direction.Y * (float)Math.Cos(offsetAngle)) * 0.5f; + _body.VelocityTarget = newDirection; + + UpdateAnimation(); + } + else if (type == PushableComponent.PushType.Impact) + { + _aiComponent.ChangeState("idle"); + _body.VelocityTarget = Vector2.Zero; + _body.Velocity = new Vector3(direction.X, direction.Y, 0.25f); + } + + return true; + } + + private void OnCollision(Values.BodyCollision moveCollision) + { + if (_aiComponent.CurrentStateId == "attack") + return; + + // rotate after wall collision + // horizontal collision + if ((moveCollision & Values.BodyCollision.Horizontal) != 0) + { + if (!_changeDirectionSwitch.State) + return; + _changeDirectionSwitch.Reset(); + + _body.VelocityTarget.X = -_body.VelocityTarget.X; + + UpdateAnimation(); + } + // vertical collision + else if ((moveCollision & Values.BodyCollision.Vertical) != 0) + { + _body.VelocityTarget.Y = -_body.VelocityTarget.Y; + } + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + if (_aiComponent.CurrentStateId == "idle" || + _aiComponent.CurrentStateId == "walking") + { + Game1.GameManager.PlaySoundEffect("D360-03-03"); + + _aiComponent.ChangeState("preAttack"); + _damageState.SetDamageState(); + _body.Velocity = new Vector3(direction * 1.5f, 0); + + return Values.HitCollision.Enemy; + } + + return Values.HitCollision.None; + } + + private bool Interact() + { + if (_aiComponent.CurrentStateId == "listening") + Game1.GameManager.StartDialogPath("animals_absorbed"); + else + Game1.GameManager.StartDialogPath("dog"); + + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjFairy.cs b/InGame/GameObjects/NPCs/ObjFairy.cs new file mode 100644 index 0000000..28ac1c3 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjFairy.cs @@ -0,0 +1,245 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjFairy : GameObject + { + private readonly CSprite _sprite; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly ShadowBodyDrawComponent _shadowComponent; + + private readonly DictAtlasEntry _heartSource; + + private readonly string _strDialogPath; + + private const int DespawnTime = 1000; + private const int DespawnStart = 4000; + private const int HealingStart = 500; + private const int HealingStepTime = 250; + + private Color _color; + + private double _hiddenStartTime; + + private float _spawnState; + private float _heartTimer; + private float _healCounter; + private float _heartSpeed = 300; + private float _despawnCounter; + + private int _healStepAmount; + + private bool _shownDialog; + private bool _healMode; + + public ObjFairy() : base("npc_fairy") { } + + public ObjFairy(Map.Map map, int posX, int posY, string strDialogPath) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, 8); + EntitySize = new Rectangle(-11, -35, 22, 35 + 32); + + // the fairy in the color dungeon does not heal but shows a custom dialog instead + _strDialogPath = strDialogPath; + + _healMode = string.IsNullOrEmpty(strDialogPath); + + _body = new BodyComponent(EntityPosition, -5, -16, 10, 16, 8) + { + IgnoresZ = true + }; + + _heartSource = Resources.GetSprite("heart"); + + var animator = AnimatorSaveLoad.LoadAnimator("NPCs/fairy"); + animator.Play("idle"); + + _aiComponent = new AiComponent(); + + var stateHidde = new AiState(UpdateHidden) { Init = InitHidden }; + var stateIdle = new AiState(UpdateIdle); + var stateHealing = new AiState(UpdateHealing) { Init = InitHealing }; + var stateDespawning = new AiState(UpdateDespawning) { Init = InitDespawning }; + + _aiComponent.States.Add("hidden", stateHidde); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("healing", stateHealing); + _aiComponent.States.Add("despawning", stateDespawning); + + _aiComponent.ChangeState("idle"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(animator, _sprite, new Vector2(-11, -25)); + + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(ObjectCollisionComponent.Index, new ObjectCollisionComponent(new Rectangle(posX + 8 - 3, posY + 16, 6, 30), OnCollision)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerTop, EntityPosition)); + AddComponent(DrawShadowComponent.Index, _shadowComponent = new ShadowBodyDrawComponent(EntityPosition)); + } + + private void UpdatePosition() + { + // move up down + EntityPosition.Z = 12.0f + MathF.Sin((float)Game1.TotalGameTime / 1100.0f * MathF.PI) * 4.0f; + } + + private void InitHidden() + { + _hiddenStartTime = Game1.TotalGameTime; + } + + private void UpdateHidden() + { + // fade out + _spawnState = AnimationHelper.MoveToTarget(_spawnState, 0, 0.05f * Game1.TimeMultiplier); + _color = Color.White * _spawnState; + _shadowComponent.Transparency = _spawnState; + + // delay the spawning a little bit + if (_hiddenStartTime + 10000 < Game1.TotalGameTime && + Game1.GameManager.CurrentHealth < Game1.GameManager.MaxHearths * 4) + _aiComponent.ChangeState("idle"); + } + + private void UpdateIdle() + { + // fade in + _spawnState = AnimationHelper.MoveToTarget(_spawnState, 1, 0.05f * Game1.TimeMultiplier); + _color = Color.White * _spawnState; + _shadowComponent.Transparency = _spawnState; + + UpdatePosition(); + + // hide when the player has full health + if (_healMode && Game1.GameManager.CurrentHealth >= Game1.GameManager.MaxHearths * 4) + _aiComponent.ChangeState("hidden"); + } + + private void InitHealing() + { + _heartTimer = -1; + + // different speeds depending on the health of the player + var healingSteps = (DespawnStart - HealingStart) / HealingStepTime; + var neededSteps = Game1.GameManager.MaxHearths * 4 - Game1.GameManager.CurrentHealth; + _healStepAmount = Math.Clamp((int)Math.Ceiling(neededSteps / (float)healingSteps), 1, 8); + + Game1.GameManager.SetMusic(11, 2); + Game1.GameManager.StartDialogPath("fairy"); + } + + private void UpdateHealing() + { + UpdatePosition(); + + if (Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen) + return; + + MapManager.ObjLink.FreezePlayer(); + + _heartTimer += Game1.DeltaTime; + + // start healing + if (_heartTimer > HealingStart) + _healCounter += Game1.DeltaTime; + + Game1.GameManager.PlaySoundEffect("D370-06-06", false); + + if (_healCounter > HealingStepTime) + { + _healCounter -= HealingStepTime; + if (Game1.GameManager.CurrentHealth < Game1.GameManager.MaxHearths * 4) + { + Game1.GameManager.PlaySoundEffect("D370-06-06", true); + Game1.GameManager.HealPlayer(_healStepAmount); + } + } + + if (_heartTimer > DespawnStart) + { + Game1.GameManager.PlaySoundEffect("D360-38-26"); + _aiComponent.ChangeState("despawning"); + } + } + + private void InitDespawning() + { + _despawnCounter = DespawnTime; + Game1.GameManager.SetMusic(-1, 2); + } + + private void UpdateDespawning() + { + UpdatePosition(); + + // remove the fairy + _despawnCounter -= Game1.DeltaTime; + if (_despawnCounter <= 0) + { + _spawnState = 0; + _aiComponent.ChangeState("hidden"); + } + + // fade out with a blinking effect + var despawnState = MathHelper.Clamp(_despawnCounter / 500.0f, 0, 1) * + (0.75f + (float)Math.Cos(_despawnCounter / 15) * 0.25f); + + _color = Color.White * despawnState; + _shadowComponent.Transparency = despawnState; + } + + private void OnCollision(GameObject gameObject) + { + if (!string.IsNullOrEmpty(_strDialogPath)) + { + if (!_shownDialog) + Game1.GameManager.StartDialogPath(_strDialogPath); + _shownDialog = true; + return; + } + + if (_aiComponent.CurrentStateId == "idle" && _spawnState >= 1) + _aiComponent.ChangeState("healing"); + } + + private void Draw(SpriteBatch spriteBatch) + { + // draw the sprite + _sprite.Color = _color; + _sprite.Draw(spriteBatch); + + // draw the hearts + if (_aiComponent.CurrentStateId == "healing" || + _aiComponent.CurrentStateId == "despawning") + DrawHearts(spriteBatch); + } + + private void DrawHearts(SpriteBatch spriteBatch) + { + for (var i = 0; i < 10; i++) + { + if (_heartTimer < (i * _heartSpeed)) + return; + + var position = new Vector2(EntityPosition.Position.X - 3.5f, EntityPosition.Position.Y + 20); + var angle = i / 5.0 * Math.PI - (_heartTimer / _heartSpeed * Math.PI / 5.0); + + position += new Vector2((float)Math.Sin(angle), -(float)Math.Cos(angle)) * 36; + + DrawHelper.DrawNormalized(spriteBatch, _heartSource, position, _color); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjFish.cs b/InGame/GameObjects/NPCs/ObjFish.cs new file mode 100644 index 0000000..3968541 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjFish.cs @@ -0,0 +1,273 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + class ObjFish : GameObject + { + public BodyComponent Body; + public string DialogName; + + private readonly Animator _animator = new Animator(); + private readonly AiComponent _aiComponent; + private readonly AnimationComponent _animationComponent; + private readonly CSprite _sprite; + + private readonly Vector2 _startPosition; + private Vector2 _goalPosition; + + private float _speed; + + private int _direction = -1; + private int _moveDistance; + private int _speedDistance; + + private bool _interacted; + + private float _lockOnCount = 500; + private bool _isLockedOn; + + // type: 0: small fish; 1: big fish, 2: big fish with heart + public ObjFish(Map.Map map, int posX, int posY, int type, int offset, int wait) : base(map) + { + SprEditorImage = Resources.SprNpCs; + EditorIconSource = type == 0 ? new Rectangle(487, 142, 15, 11) : new Rectangle(528, 158, 16, 16); + + EntityPosition = new CPosition(posX, posY + 8, 0); + EntitySize = new Rectangle(-16, -8, 48, 16); + + _startPosition = EntityPosition.Position; + EntityPosition.Set(EntityPosition.Position + new Vector2(offset, 0)); + + Body = new BodyComponent(EntityPosition, 0, -6, 16, 11, 8) + { + IgnoreHeight = true, + }; + + var name = type == 0 ? "fish_small" : "fish_big"; + + DialogName = name; + if (type == 2) + DialogName += "_heart"; + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/" + name); + _animator.Play("swim"); + + _speed = type == 0 ? 0.9f : 0.35f; + _moveDistance = type == 0 ? 36 : 8; + _speedDistance = type == 0 ? 12 : 4; + + var offsetY = type == 0 ? -6 : -8; + _sprite = new CSprite(EntityPosition); + _animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(8, offsetY)); + + var waitCountdown = new AiTriggerCountdown(250, null, ToSwim); + + var stateSwim = new AiState(StateSwim); + var stateWait = new AiState(null); + stateWait.Trigger.Add(waitCountdown); + var stateBite = new AiState(StateBite); + var stateBitten = new AiState(StateBitten); + var stateJump = new AiState(StateJump); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("swim", stateSwim); + _aiComponent.States.Add("wait", stateWait); + _aiComponent.States.Add("bite", stateBite); + _aiComponent.States.Add("bitten", stateBitten); + _aiComponent.States.Add("jump", stateJump); + + if (wait > 0) + { + _aiComponent.ChangeState("wait"); + waitCountdown.CurrentTime = wait; + } + else + ToSwim(); + + AddComponent(BodyComponent.Index, Body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, _animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(Body, _sprite, Values.LayerPlayer)); + AddComponent(InteractComponent.Index, new InteractComponent(Body.BodyBox, Interact)); + } + + private bool Interact() + { + if (ObjLinkFishing.HasFish) + return false; + + ObjLinkFishing.HasFish = true; + + if (!_interacted) + ToBite(); + _interacted = true; + + return true; + } + + private void ToSwim() + { + _aiComponent.ChangeState("swim"); + + // set the right animation + //_animator.IsPlaying = true; + _animator.Play("swim"); + _animationComponent.MirroredH = _direction > 0; + + Body.Drag = 1.0f; + + _goalPosition = _startPosition; + if (_direction < 0) + _goalPosition += new Vector2(_moveDistance, 0); + + _direction = -_direction; + } + + private void StateSwim() + { + var distance = _goalPosition - EntityPosition.Position; + var distanceLength = distance.X * _direction; + + if (distanceLength >= _moveDistance - _speedDistance) + { + Body.Velocity.X = Math.Sign(distance.X) * ((1.0f - ((distanceLength - (_moveDistance - _speedDistance)) / _speedDistance)) * _speed + 0.05f); + } + + if (distanceLength <= 0) + { + EntityPosition.Set(_goalPosition); + Body.Velocity.X = 0; + _aiComponent.ChangeState("wait"); + return; + } + + if (distanceLength < _moveDistance / 3.0f) + { + _animator.IsPlaying = false; + } + + if (distanceLength < 16) + { + Body.Drag = 0.95f; + } + } + + private void ToBite() + { + Body.Drag = 0.975f; + _aiComponent.ChangeState("bite"); + } + + private void StateBite() + { + var goalPosition = ObjLinkFishing.HookPosition; + var flipped = goalPosition.X < EntityPosition.X + 8; + goalPosition.X += flipped ? 14 : -14; + + goalPosition += new Vector2( + (float)Math.Sin(Game1.TotalGameTime * 0.005), + (float)Math.Cos(Game1.TotalGameTime * 0.004)); + + var direction = goalPosition - new Vector2(EntityPosition.Position.X + 8, EntityPosition.Position.Y); + var swimSpeed = 0.5f; + + if (direction.Length() < 1) + { + swimSpeed = direction.Length() * 0.5f; + _isLockedOn = true; + //ToBitten(); + } + + if (_isLockedOn) + { + _lockOnCount -= Game1.DeltaTime; + + if (_lockOnCount < 0) + { + direction = ObjLinkFishing.HookPosition - new Vector2(EntityPosition.Position.X + 8, EntityPosition.Position.Y); + swimSpeed = 2.0f; + + if (direction.Length() <= 2) + { + ToBitten(); + return; + } + } + } + + if (direction != Vector2.Zero) + direction.Normalize(); + + Body.Velocity.X = direction.X * swimSpeed; + Body.Velocity.Y = direction.Y * swimSpeed; + + _animator.Play("bite"); + _animationComponent.MirroredH = flipped; + _animationComponent.UpdateSprite(); + } + + private void ToBitten() + { + _aiComponent.ChangeState("bitten"); + ObjLinkFishing.HookedFish = this; + Body.Velocity = Vector3.Zero; + } + + private void StateBitten() + { + if(ObjLinkFishing.HookedFish == null) + return; + + _animator.Play("swim"); + + //_body.Velocity.X = (float)Math.Sin(Game1.TotalTime * 0.005); + + var flipped = Body.Velocity.X < (_animationComponent.MirroredH ? 0.2f : -0.2f); + _animationComponent.MirroredH = flipped; + _animationComponent.UpdateSprite(); + + // update fish position + var position = new Vector2(EntityPosition.X + (flipped ? 0 : 16), EntityPosition.Y - 2); + ObjLinkFishing.HookPosition = position; + + // swim to the left side + var goalVelocity = (new Vector2(-16, 80) - EntityPosition.Position) - new Vector2(Body.Velocity.X, Body.Velocity.Y); + if (goalVelocity != Vector2.Zero) + goalVelocity.Normalize(); + Body.Velocity.X += goalVelocity.X * 0.025f * Game1.TimeMultiplier; + Body.Velocity.Y += goalVelocity.Y * 0.025f * Game1.TimeMultiplier; + } + + public void ToJump() + { + if(_aiComponent.CurrentStateId == "jump") + return; + + _aiComponent.ChangeState("jump"); + Body.Drag = 1.0f; + Body.Velocity = new Vector3(0.5f, -2.5f, 0.0f); + + // splash effect + Game1.GameManager.PlaySoundEffect("D360-14-0E"); + var splashAnimator = new ObjAnimator(Map, 0, 0, 0, 36, 0, "Particles/fishingSplash", "idle", true); + splashAnimator.EntityPosition.Set(new Vector2(EntityPosition.X + 8, 0)); + Map.Objects.SpawnObject(splashAnimator); + } + + private void StateJump() + { + Body.Velocity.Y += 0.1f * Game1.TimeMultiplier; + + if (Body.Velocity.Y > 0 && EntityPosition.Y > 28) + _sprite.IsVisible = false; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjFisherman.cs b/InGame/GameObjects/NPCs/ObjFisherman.cs new file mode 100644 index 0000000..558150e --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjFisherman.cs @@ -0,0 +1,84 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameSystems; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjFisherman : GameObject + { + public BodyComponent Body; + public readonly Animator Animator; + + private readonly string _personId = "npc_fisherman"; + + private float _talkCount; + private bool _isTransitioning; + + public ObjFisherman() : base("fisherman") { } + + public ObjFisherman(Map.Map map, int posX, int posY) : base(map) + { + Animator = AnimatorSaveLoad.LoadAnimator("NPCs/" + _personId); + Animator.Play("stand"); + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(Animator, sprite, new Vector2(0, 0)); + + Game1.GameManager.SaveManager.SetString("enterPond", "no"); + + Body = new BodyComponent(EntityPosition, -8, -11, 15, 11, 8); + + AddComponent(BodyComponent.Index, Body); + AddComponent(CollisionComponent.Index, new BodyCollisionComponent(Body, Values.CollisionTypes.Normal)); + AddComponent(InteractComponent.Index, new InteractComponent(Body.BodyBox, Interact)); + AddComponent(AnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(Body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + } + + private void Update() + { + if (_talkCount > 0) + _talkCount -= Game1.DeltaTime; + else + { + Animator.Play("stand"); + } + } + + private bool Interact() + { + Animator.Play("talk"); + _talkCount = 250; + + Game1.GameManager.StartDialogPath(_personId); + return true; + } + + private void KeyChanged() + { + // spawn object + if (_isTransitioning || Game1.GameManager.SaveManager.GetString("enterPond") != "yes") return; + + _isTransitioning = true; + + MapManager.ObjLink.MapTransitionStart = MapManager.ObjLink.EntityPosition.Position; + MapManager.ObjLink.MapTransitionEnd = MapManager.ObjLink.EntityPosition.Position; + MapManager.ObjLink.TransitionOutWalking = false; + + // append a map change + ((MapTransitionSystem)Game1.GameManager.GameSystems[typeof(MapTransitionSystem)]).AppendMapChange( + "pond.map", "entry", true, false, Values.MapTransitionColor, false); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjFishermanBoat.cs b/InGame/GameObjects/NPCs/ObjFishermanBoat.cs new file mode 100644 index 0000000..3bef7aa --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjFishermanBoat.cs @@ -0,0 +1,239 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjFishermanBoat : GameObject + { + private readonly ObjPhotoMouse _photoMouse; + private bool _pullMouse; + private bool _pulledMouse; + private bool _falling; + + public BodyComponent Body; + public readonly Animator Animator; + private readonly CSprite _sprite; + private readonly BodyDrawComponent _drawComponent; + private readonly BodyDrawShadowComponent _shadowComponent; + private readonly BodyCollisionComponent _collisionComponent; + private readonly InteractComponent _interactionComponent; + + private readonly Vector2 _spawnPosition; + + private readonly string _dialogId; + private string _currentAnimation; + private string _spawnCondition; + private bool _directionMode = true; + + public ObjFishermanBoat(Map.Map map, int posX, int posY, string spawnCondition, string animationId, string dialogId, Rectangle bodyRectangle) : base(map) + { + SprEditorImage = Resources.SprNpCs; + EditorIconSource = new Rectangle(276, 2, 15, 16); + + if (string.IsNullOrEmpty(animationId)) + { + IsDead = true; + return; + } + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(bodyRectangle.X - bodyRectangle.Width / 2, bodyRectangle.Y - bodyRectangle.Height, bodyRectangle.Width, bodyRectangle.Height); + + _spawnPosition = EntityPosition.Position; + + _spawnCondition = spawnCondition; + _dialogId = dialogId; + Animator = AnimatorSaveLoad.LoadAnimator("NPCs/" + animationId); + + if (Animator == null) + { + IsDead = true; + return; + } + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(Animator, _sprite, Vector2.Zero); + + Body = new BodyComponent(EntityPosition, + bodyRectangle.X - bodyRectangle.Width / 2, bodyRectangle.Y - bodyRectangle.Height, bodyRectangle.Width, bodyRectangle.Height, bodyRectangle.Height) + { + Gravity = -0.15f, + }; + + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + AddComponent(BodyComponent.Index, Body); + // only the player should collide with the npc + AddComponent(CollisionComponent.Index, _collisionComponent = new BodyCollisionComponent(Body, Values.CollisionTypes.Enemy | Values.CollisionTypes.PushIgnore)); + AddComponent(InteractComponent.Index, _interactionComponent = new InteractComponent(Body.BodyBox, Interact)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, _drawComponent = new BodyDrawComponent(Body, _sprite, Values.LayerPlayer) { WaterOutline = false }); + AddComponent(DrawShadowComponent.Index, _shadowComponent = new BodyDrawShadowComponent(Body, _sprite)); + + if (Game1.GameManager.SaveManager.GetString("photoMouseActive") == "1" && + Game1.GameManager.SaveManager.GetString("photo_sequence_bridge") == null) + { + _photoMouse = new ObjPhotoMouse(map, posX - 17, posY + 40, null, "mouseSeqBoat"); + map.Objects.SpawnObject(_photoMouse); + } + } + + private void SetActive(bool isActive) + { + _collisionComponent.IsActive = isActive; + _interactionComponent.IsActive = isActive; + _drawComponent.IsActive = isActive; + _shadowComponent.IsActive = isActive; + } + + private void Update() + { + if (_directionMode) + { + var playerDistance = new Vector2( + MapManager.ObjLink.EntityPosition.X - (EntityPosition.X), + MapManager.ObjLink.EntityPosition.Y - (EntityPosition.Y - 4)); + + var dir = 3; + + // rotate in the direction of the player + if (playerDistance.Length() < 32) + dir = AnimationHelper.GetDirection(playerDistance); + + // look at the player + if (_currentAnimation == null) + { + var animationIndex = Animator.GetAnimationIndex("stand_" + dir); + if (animationIndex >= 0) + Animator.Play(animationIndex); + else + Animator.Play("stand_" + (playerDistance.Y < 0 ? "1" : "3")); + } + } + + // finished playing + if (_currentAnimation != null && !Animator.IsPlaying) + { + _currentAnimation = null; + Game1.GameManager.SaveManager.SetString(_dialogId + "Finished", "1"); + } + + if (_pullMouse && _photoMouse != null && !_falling) + { + var targetPosition = new Vector2(EntityPosition.X - 25, EntityPosition.Y - 1); + var pullDirection = targetPosition - _photoMouse.EntityPosition.Position; + // pull slower in water + var pullSpeed = (_photoMouse.Body.CurrentFieldState & MapStates.FieldStates.DeepWater) != 0 ? 0.25f : 0.5f; + + if (pullDirection.Length() > pullSpeed * Game1.TimeMultiplier) + { + pullDirection.Normalize(); + _photoMouse.Body.VelocityTarget = pullDirection * pullSpeed; + } + else + { + if (!_pulledMouse) + { + _pulledMouse = true; + Game1.GameManager.SaveManager.SetString("mousePulledUp", "1"); + } + + _photoMouse.Body.VelocityTarget = Vector2.Zero; + _photoMouse.EntityPosition.Set(targetPosition); + } + } + } + + public void DisableRotating() + { + _directionMode = false; + } + + private bool Interact() + { + Game1.GameManager.StartDialogPath(_dialogId); + return true; + } + + private void SetVisibility(bool visible) + { + _sprite.IsVisible = visible; + _shadowComponent.IsActive = visible; + } + + private void OnKeyChange() + { + if (_spawnCondition != null) + { + var spawnValue = Game1.GameManager.SaveManager.GetString(_spawnCondition); + if (spawnValue == "1") + SetActive(true); + } + + // start new animation? + var animationString = _dialogId + "Animation"; + var animationValues = Game1.GameManager.SaveManager.GetString(animationString); + if (animationValues != null) + { + if (animationValues == "-") + { + _currentAnimation = null; + } + else if (animationValues != "") + { + SetVisibility(true); + _currentAnimation = animationValues; + Animator.Play(_currentAnimation); + } + else + { + SetVisibility(false); + _currentAnimation = null; + } + + Game1.GameManager.SaveManager.RemoveString(animationString); + } + + var pullMouseString = "mousePullUp"; + var pullMouseValue = Game1.GameManager.SaveManager.GetString(pullMouseString); + if (!string.IsNullOrEmpty(pullMouseValue)) + { + _pullMouse = true; + Game1.GameManager.SaveManager.RemoveString(pullMouseString); + } + + var fallString = "fisherman_fall"; + var fallValue = Game1.GameManager.SaveManager.GetString(fallString); + if (!string.IsNullOrEmpty(fallValue)) + { + _falling = true; + Body.Velocity = new Vector3(-1.75f, -0.75f, 0); + if (_photoMouse != null) + { + _photoMouse.Body.IgnoresZ = false; + _photoMouse.Body.Velocity.X = -0.25f; + } + Game1.GameManager.SaveManager.RemoveString(fallString); + } + + var resetString = "fisherman_reset"; + var resetValue = Game1.GameManager.SaveManager.GetString(resetString); + if (!string.IsNullOrEmpty(resetValue)) + { + _pullMouse = false; + // reset the position and remove the photo mouse + // must be ontop of the boat + EntityPosition.Set(new Vector2(_spawnPosition.X, _spawnPosition.Y - 2)); + if (_photoMouse != null) + Map.Objects.DeleteObjects.Add(_photoMouse); + Game1.GameManager.SaveManager.RemoveString(resetString); + } + + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjFrog.cs b/InGame/GameObjects/NPCs/ObjFrog.cs new file mode 100644 index 0000000..fe254b6 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjFrog.cs @@ -0,0 +1,142 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjFrog : GameObject + { + private readonly Animator _animator; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiTriggerSwitch _hitCooldown; + + private int _direction; + + public ObjFrog(Map.Map map, int posX, int posY) : base(map) + { + SprEditorImage = Resources.SprNpCs; + EditorIconSource = new Rectangle(84, 28, 14, 12); + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _body = new BodyComponent(EntityPosition, -6, -8, 12, 8, 8) + { + MoveCollision = OnCollision, + CollisionTypes = Values.CollisionTypes.Normal | + Values.CollisionTypes.NPCWall, + FieldRectangle = map.GetField(posX, posY), + MaxJumpHeight = 4f, + DragAir = 0.99f, + Drag = 0.85f, + Gravity = -0.15f + }; + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/frog"); + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-7, -12)); + + _hitCooldown = new AiTriggerSwitch(250); + + var stateSitInit = new AiState(); + stateSitInit.Trigger.Add(new AiTriggerRandomTime(ToJump, 125, 1000)); + stateSitInit.Trigger.Add(_hitCooldown); + var stateSit = new AiState(); + stateSit.Trigger.Add(_hitCooldown); + stateSit.Trigger.Add(new AiTriggerRandomTime(ToJump, 750, 1500)); + var stateJump = new AiState(UpdateJump); + stateJump.Trigger.Add(_hitCooldown); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("sitInit", stateSitInit); + _aiComponent.States.Add("sit", stateSit); + _aiComponent.States.Add("jump", stateJump); + + // start by locking into a random direction + _direction = Game1.RandomNumber.Next(0, 4); + _animator.Play("sit_" + _direction); + _aiComponent.ChangeState("sitInit"); + + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(AnimationComponent.Index, animationComponent); + //AddComponent(CollisionComponent.Index, new BodyCollisionComponent(_body, Values.CollisionTypes.Normal)); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, OnHit)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite)); + } + + private void ToSit() + { + _aiComponent.ChangeState("sit"); + + // stop and wait + _body.Velocity = Vector3.Zero; + + _animator.Play("sit_" + _direction); + } + + private void ToJump() + { + _aiComponent.ChangeState("jump"); + + // change the direction + var rotation = Game1.RandomNumber.Next(0, 628) / 100f; + var direction = new Vector2( + (float)Math.Sin(rotation), + (float)Math.Cos(rotation)) * Game1.RandomNumber.Next(25, 40) / 50f; + _direction = AnimationHelper.GetDirection(direction); + + _body.Velocity = new Vector3(direction.X * 1.5f, direction.Y * 1.5f, 1.75f); + + _animator.Play("jump_" + _direction); + } + + private void UpdateJump() + { + // finished jumping + if (_body.IsGrounded) + ToSit(); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (!_hitCooldown.State) + return Values.HitCollision.None; + + _hitCooldown.Reset(); + + _body.Velocity.X += direction.X * 4.0f; + _body.Velocity.Y += direction.Y * 4.0f; + + return Values.HitCollision.Blocking; + } + + private void OnCollision(Values.BodyCollision moveCollision) + { + if (_aiComponent.CurrentStateId != "jump") + return; + + // repel after wall collision + if (moveCollision.HasFlag(Values.BodyCollision.Horizontal)) + _body.Velocity.X *= -0.25f; + else if (moveCollision.HasFlag(Values.BodyCollision.Vertical)) + _body.Velocity.Y *= -0.25f; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction * 1.25f, _body.Velocity.Z); + + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjGhost.cs b/InGame/GameObjects/NPCs/ObjGhost.cs new file mode 100644 index 0000000..ba14cda --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjGhost.cs @@ -0,0 +1,267 @@ +using System; +using System.Globalization; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjGhost : GameObjectFollower + { + private readonly Animator _animator; + private readonly CSprite _sprite; + private readonly BodyComponent _body; + private readonly BodyDrawShadowComponent _shadowComponent; + private readonly AiComponent _aiComponent; + + private Vector2 _followVelocity; + private Vector2 _targetPosition; + + private float _moveSpeed; + private float _fadeTime; + private float _fadeCounter; + + private const int FlyHeight = 14; + + private bool _returning; + private bool _fadingIn; + + // @TODO: 2d maps? + // the position when the position dialog was started the last time + private Vector2 _lastDialogPosition; + + public ObjGhost() : base("ghost") { } + + public ObjGhost(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, FlyHeight); + EntitySize = new Rectangle(-8, -32, 16, 32); + + var ghostState = Game1.GameManager.SaveManager.GetString("ghost_state"); + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/ghost"); + + _sprite = new CSprite(EntityPosition); + _sprite.Color = Color.White * 0.75f; + var animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -4, -10, 8, 10, 8) + { + IgnoreHoles = true, + IgnoresZ = true, + Gravity = -0.15f, + CollisionTypes = Values.CollisionTypes.None + }; + + _aiComponent = new AiComponent(); + + var stateFade = new AiState(UpdateFade); + var stateMove = new AiState(UpdateMoving); + var stateStartFollow = new AiState(UpdateFollowPlayer); + var stateFollow = new AiState(UpdateFollowPlayer); + var stateReturn = new AiState(UpdateMoving) { Init = InitReturn }; + + _aiComponent.States.Add("fade", stateFade); + _aiComponent.States.Add("move", stateMove); + _aiComponent.States.Add("startFollow", stateStartFollow); + _aiComponent.States.Add("follow", stateStartFollow); + _aiComponent.States.Add("return", stateReturn); + + _aiComponent.ChangeState("follow"); + + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, _shadowComponent = new BodyDrawShadowComponent(_body, _sprite)); + } + + public override void Init() + { + _shadowComponent.IsActive = !Map.Is2dMap; + } + + public void StartFollowing() + { + // offset the position in a random direction + var radiant = Game1.RandomNumber.Next(0, 314 * 2) / 100f; + var offset = new Vector2(MathF.Sin(radiant), MathF.Cos(radiant)) * 48; + EntityPosition.Offset(offset); + _lastDialogPosition = EntityPosition.Position; + + _fadingIn = true; + _fadeCounter = 0; + _fadeTime = 500; + + // set up variables + Game1.GameManager.StartDialogPath("ghost_start_following"); + + _aiComponent.ChangeState("startFollow"); + } + + public override void SetPosition(Vector2 position) + { + _lastDialogPosition = position; + EntityPosition.Set(position); + } + + private void InitReturn() + { + var graveStone = Map.Objects.GetObjectOfType( + (int)MapManager.ObjLink.EntityPosition.X - 32, + (int)MapManager.ObjLink.EntityPosition.Y - 32, 64, 64, typeof(ObjMoveStone)); + if (graveStone != null) + { + _targetPosition = new Vector2(graveStone.EntityPosition.X + 8, graveStone.EntityPosition.Y); + _moveSpeed = 0.5f; + } + } + + private void UpdateFollowPlayer() + { + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + var playerDistance = playerDirection.Length(); + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + var movementSpeed = MathHelper.Clamp((playerDistance - 16) / 32, 0, 2); + + // move towards the player + _followVelocity = AnimationHelper.MoveToTarget(_followVelocity, playerDirection * movementSpeed, 0.1f * Game1.DeltaTime); + _body.VelocityTarget = _followVelocity; + + // fly up and down + var targetPosZ = FlyHeight + MathF.Sin(((float)Game1.TotalGameTime / 1000) * MathF.PI * 2) * 1.5f; + EntityPosition.Z = AnimationHelper.MoveToTarget(EntityPosition.Z, targetPosZ, 1 * Game1.TimeMultiplier); + + // play walk/stand animation + if (_followVelocity.Length() > 0.1f) + UpdateAnimation(_followVelocity); + + // start the dialog if we walked some amount + var dialogDistance = _lastDialogPosition - EntityPosition.Position; + if (dialogDistance.Length() > 160) + { + _lastDialogPosition = EntityPosition.Position; + Game1.GameManager.StartDialogPath("ghost_return"); + } + + // fade in + if (_fadingIn) + { + _fadeCounter += Game1.DeltaTime; + if (_fadeCounter >= _fadeTime) + { + _fadeCounter = _fadeTime; + _fadingIn = false; + } + + var percentage = _fadeCounter / _fadeTime; + _sprite.Color = Color.White * percentage; + _shadowComponent.Transparency = percentage; + } + } + + private void UpdateMoving() + { + // move towards the target position + var targetDirection = _targetPosition - EntityPosition.Position; + if (targetDirection.Length() > _moveSpeed * Game1.TimeMultiplier) + { + targetDirection.Normalize(); + _body.VelocityTarget = targetDirection * _moveSpeed; + UpdateAnimation(targetDirection * _moveSpeed); + } + // finished walking + else + { + _body.VelocityTarget = Vector2.Zero; + EntityPosition.Set(_targetPosition); + if (_returning) + _animator.Play("right"); + } + } + + private void UpdateFade() + { + if (_fadeTime <= 0) + return; + + _fadeCounter -= Game1.DeltaTime; + + if (_fadeCounter <= 0) + Map.Objects.DeleteObjects.Add(this); + else + { + EntityPosition.Z = AnimationHelper.MoveToTarget(EntityPosition.Z, 0, 0.5f * Game1.TimeMultiplier); + + var percentage = _fadeCounter / _fadeTime; + _sprite.Color = Color.White * percentage; + _shadowComponent.Transparency = percentage; + } + } + + private void UpdateAnimation(Vector2 direction) + { + var dir = Math.Abs(direction.X) / Math.Abs(direction.Y); + if (direction.Y >= 0 || dir > 0.75f) + _animator.Play(direction.X < 0 ? "left" : "right"); + else + _animator.Play(direction.X < 0 ? "up_left" : "up_right"); + } + + private void KeyChanged() + { + if (!IsActive) + return; + + // start following + var followValue = Game1.GameManager.SaveManager.GetString("ghost_follow"); + if (!string.IsNullOrEmpty(followValue)) + { + _aiComponent.ChangeState("follow"); + Game1.GameManager.SaveManager.RemoveString("ghost_follow"); + } + + // start fading away? + var fadeValue = Game1.GameManager.SaveManager.GetString("ghost_fade"); + if (!string.IsNullOrEmpty(fadeValue)) + { + _fadeTime = int.Parse(fadeValue); + _fadeCounter = _fadeTime; + _aiComponent.ChangeState("fade"); + + Game1.GameManager.SaveManager.RemoveString("ghost_fade"); + } + + // start moving? [set:ghost_move,-16,32,1] + var moveValue = Game1.GameManager.SaveManager.GetString("ghost_move"); + if (!string.IsNullOrEmpty(moveValue)) + { + var split = moveValue.Split(','); + var offsetX = int.Parse(split[0]); + var offsetY = int.Parse(split[1]); + _moveSpeed = float.Parse(split[2], CultureInfo.InvariantCulture); + _targetPosition = new Vector2(EntityPosition.X + offsetX, EntityPosition.Y + offsetY); + _aiComponent.ChangeState("move"); + + Game1.GameManager.SaveManager.RemoveString("ghost_move"); + } + + // return to the grave + var returnValue = Game1.GameManager.SaveManager.GetString("ghost_return"); + if (!string.IsNullOrEmpty(returnValue)) + { + _returning = true; + _aiComponent.ChangeState("return"); + Game1.GameManager.SaveManager.RemoveString("ghost_return"); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjGrandmother.cs b/InGame/GameObjects/NPCs/ObjGrandmother.cs new file mode 100644 index 0000000..b626145 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjGrandmother.cs @@ -0,0 +1,102 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + class ObjGrandmother : GameObject + { + private ObjAnimator _objBroom; + + private readonly Animator _animator; + private readonly string _dialogId; + + private int _direction = -1; + private bool _showBroom; + private bool _missingBroomState; + + public ObjGrandmother() : base("grandmother") { } + + public ObjGrandmother(Map.Map map, int posX, int posY, string spawnCondition, string dialogId) : base(map) + { + var condition = SaveCondition.GetConditionNode(spawnCondition); + if (!condition.Check()) + { + IsDead = true; + return; + } + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _dialogId = dialogId; + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/npc_woman_broom"); + _animator.Play("stand_-1"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, Vector2.Zero); + var body = new BodyComponent(EntityPosition, -7, -12, 14, 12, 8); + + AddComponent(BodyComponent.Index, body); + AddComponent(CollisionComponent.Index, new BodyCollisionComponent(body, Values.CollisionTypes.Normal | Values.CollisionTypes.PushIgnore)); + AddComponent(InteractComponent.Index, new InteractComponent(new CBox(EntityPosition, -7, -12, 14, 12, 8), Interact)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(body, sprite)); + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + + if (Game1.GameManager.SaveManager.GetString("missing_broom", "0") == "1") + { + _missingBroomState = true; + _animator.Play("missing_broom"); + _objBroom = new ObjAnimator(map, posX + 8, posY + 16, Values.LayerPlayer, "NPCs/broom", "show", false); + } + } + + private void OnKeyChange() + { + var showBroomValue = Game1.GameManager.SaveManager.GetString("show_broom", "0"); + if (!_showBroom && showBroomValue == "1") + { + _showBroom = true; + _animator.Play("show"); + Map.Objects.SpawnObject(_objBroom); + } + if (_showBroom && showBroomValue == "0") + { + _missingBroomState = false; + _showBroom = false; + _animator.Play("stand_" + _direction); + Map.Objects.DeleteObjects.Add(_objBroom); + } + } + + private void Update() + { + if (_missingBroomState) + return; + + // look at the player + var box = new RectangleF(EntityPosition.X - 16 * _direction - 8, EntityPosition.Y - 32, 16, 48); + if (MapManager.ObjLink.BodyRectangle.Intersects(box)) + { + _direction = EntityPosition.X < MapManager.ObjLink.PosX ? 1 : -1; + _animator.Play("stand_" + _direction); + } + } + + private bool Interact() + { + Game1.GameManager.StartDialogPath(_dialogId); + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjHippo.cs b/InGame/GameObjects/NPCs/ObjHippo.cs new file mode 100644 index 0000000..80563f8 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjHippo.cs @@ -0,0 +1,58 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + class ObjHippo : GameObject + { + private readonly Animator _animator; + + private int _direction = -1; + + public ObjHippo() : base("hippo") { } + + public ObjHippo(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-12, -24, 24, 24); + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/npc_hippo"); + _animator.Play("idle_" + _direction); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, Vector2.Zero); + + var body = new BodyComponent(EntityPosition, -9, -13, 18, 12, 8); + + AddComponent(BodyComponent.Index, body); + AddComponent(CollisionComponent.Index, new BodyCollisionComponent(body, Values.CollisionTypes.Normal | Values.CollisionTypes.PushIgnore)); + AddComponent(InteractComponent.Index, new InteractComponent(new CBox(EntityPosition, -9, -5, 18, 5, 8), Interact)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(body, sprite)); + } + + private void Update() + { + var box = new RectangleF(EntityPosition.X + _direction * 14 - 4, EntityPosition.Y - 14, 8, 18); + if (MapManager.ObjLink.BodyRectangle.Intersects(box)) + { + _direction = -_direction; + _animator.Play("idle_" + _direction); + } + } + + private bool Interact() + { + Game1.GameManager.StartDialogPath("npc_hippo"); + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjHoneycomb.cs b/InGame/GameObjects/NPCs/ObjHoneycomb.cs new file mode 100644 index 0000000..f10a6c5 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjHoneycomb.cs @@ -0,0 +1,176 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjHoneycomb : GameObject + { + private readonly CSprite _sprite; + + private ObjBees[] _objBee = new ObjBees[6]; + private ObjPersonNew _objFollowerTarget; + + private bool _spawnBees; + private int _spawnIndex; + private double _spawnCounter; + private const int SpawnTime = 175; + + private bool _fallDown; + private double _fallCounter; + private const double FallTime = 250; + + public ObjHoneycomb() : base("trade5Map") { } + + public ObjHoneycomb(Map.Map map, int posX, int posY, string saveKey) : base(map) + { + EntityPosition = new CPosition(posX, posY + 24, 0); + EntitySize = new Rectangle(0, -32, 16, 32); + + if (!string.IsNullOrEmpty(saveKey) && + Game1.GameManager.SaveManager.GetString(saveKey) == "1") + { + SpawnItem(); + IsDead = true; + return; + } + + var body = new BodyComponent(EntityPosition, 0, 0, 14, 14, 8); + _sprite = new CSprite("trade5Map", EntityPosition, new Vector2(0, -24)); + + AddComponent(BodyComponent.Index, body); + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerPlayer)); + } + + public override void Init() + { + // get tarin to parent the stick to + var objTarin = Map.Objects.GetObjectOfType((int)EntityPosition.X, (int)EntityPosition.Y, 32, 32, typeof(ObjPersonNew)); + if (objTarin != null) + { + var objStick = new ObjPersonNew(Map, (int)objTarin.EntityPosition.X, (int)objTarin.EntityPosition.Y, null, "tarin stick", "tarinStick", "pHidden", new Rectangle(0, 0, 8, 8)); + ((BodyCollisionComponent)objStick.Components[CollisionComponent.Index]).IsActive = false; + objStick.EntityPosition.SetParent(objTarin.EntityPosition, Vector2.Zero, true); + Map.Objects.SpawnObject(objStick); + } + + _objFollowerTarget = new ObjPersonNew(Map, (int)EntityPosition.X, (int)EntityPosition.Y - 24, null, "bee target", "beeTarget", null, new Rectangle(0, 0, 8, 8)); + Map.Objects.SpawnObject(_objFollowerTarget); + + SpawnBee(0); + } + + private void OnKeyChange() + { + var honeycombFall = Game1.GameManager.SaveManager.GetString("honeycombFall"); + if (honeycombFall != null && honeycombFall == "1") + { + _fallDown = true; + Game1.GameManager.SaveManager.RemoveString("honeycombFall"); + } + var honeycombHit = Game1.GameManager.SaveManager.GetString("honeycombHit"); + if (honeycombHit != null && honeycombHit == "1") + { + _sprite.DrawOffset.X -= 1; + Game1.GameManager.SaveManager.RemoveString("honeycombHit"); + } + var honeycombReset = Game1.GameManager.SaveManager.GetString("honeycombReset"); + if (honeycombReset != null && honeycombReset == "1") + { + if (!_spawnBees) + { + _objFollowerTarget.EntityPosition.Set(new Vector2(EntityPosition.X - 12, EntityPosition.Y - 0)); + _spawnBees = true; + _spawnCounter = SpawnTime; + _spawnIndex = 1; + _objBee[0].SetAngryMode(); + } + _sprite.DrawOffset.X += 1; + Game1.GameManager.SaveManager.RemoveString("honeycombReset"); + } + var honeycombAttack = Game1.GameManager.SaveManager.GetString("honeycombAttack"); + if (honeycombAttack != null && honeycombAttack == "1") + { + for (var i = 0; i < _objBee.Length; i++) + StartFollowing(i); + Game1.GameManager.SaveManager.RemoveString("honeycombAttack"); + } + var honeycombFade = Game1.GameManager.SaveManager.GetString("honeycombFade"); + if (!string.IsNullOrEmpty(honeycombFade)) + { + var fadeTime = int.Parse(honeycombFade); + for (var i = 0; i < _objBee.Length; i++) + _objBee[i].FadeAway(fadeTime); + Game1.GameManager.SaveManager.RemoveString("honeycombFade"); + } + } + + public void Update() + { + if (_fallDown) + { + _fallCounter += Game1.DeltaTime; + _sprite.DrawOffset.X = -MathF.Sin((float)(_fallCounter / FallTime) * MathF.PI * 2); + + if (_fallCounter > FallTime) + { + SpawnItem(); + Map.Objects.DeleteObjects.Add(this); + } + } + + // look at tarin + if (_spawnBees && _spawnCounter > 2350) + { + var playerDirection = new Vector2(_objFollowerTarget.EntityPosition.X, _objFollowerTarget.EntityPosition.Y + 16) - MapManager.ObjLink.EntityPosition.Position; + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + + var playerDir = AnimationHelper.GetDirection(playerDirection, MathF.PI * 1.175f); + MapManager.ObjLink.SetWalkingDirection(playerDir); + } + + if (_spawnBees) + _spawnCounter += Game1.DeltaTime; + if (_spawnCounter < SpawnTime || _spawnIndex >= 6) + return; + + SpawnBee(_spawnIndex); + _objBee[_spawnIndex].SetAngryMode(); + + _spawnCounter -= SpawnTime; + _spawnIndex++; + } + + private void SpawnBee(int index) + { + _objBee[index] = new ObjBees(Map, new Vector2((int)EntityPosition.X + 8, (int)EntityPosition.Y - 12), _objFollowerTarget, index == 0); + Map.Objects.SpawnObject(_objBee[index]); + } + + private void StartFollowing(int index) + { + var radiants = index / 6f * MathF.PI * 2; + var offset = new Vector2(MathF.Sin(radiants), MathF.Cos(radiants)) * Game1.RandomNumber.Next(4, 7); + _objBee[index].SetFollowMode(offset); + } + + private void SpawnItem() + { + var objItem = new ObjItem(Map, (int)EntityPosition.X, (int)EntityPosition.Y, null, "ow_honeycomb", "trade5", null); + if (!objItem.IsDead) + { + objItem.EntityPosition.Set(new Vector3(EntityPosition.X + 8, EntityPosition.Y + 8, 16)); + ((BodyComponent)objItem.Components[BodyComponent.Index]).Bounciness = 0; + Map.Objects.SpawnObject(objItem); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjLetterBird.cs b/InGame/GameObjects/NPCs/ObjLetterBird.cs new file mode 100644 index 0000000..648d45d --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjLetterBird.cs @@ -0,0 +1,161 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjLetterBird : GameObject + { + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiTriggerSwitch _changeDirectionSwitch; + private readonly Animator _animator; + + private float _flyCounter; + private int _flyTime = 850; + private int _direction; + + public ObjLetterBird() : base("letter_bird") { } + + public ObjLetterBird(Map.Map map, int posX, int posY, string animationId) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _body = new BodyComponent(EntityPosition, -6, -8, 12, 8, 8) + { + MoveCollision = OnCollision, + CollisionTypes = Values.CollisionTypes.Normal | + Values.CollisionTypes.NPCWall, + Bounciness = 0.25f, + Drag = 0.9f, + Gravity = -0.15f, + }; + + _animator = AnimatorSaveLoad.LoadAnimator(animationId); + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -16)); + + var stateIdle = new AiState() { Init = InitIdle }; + stateIdle.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("walking"), 500, 1500)); + + var stateWalking = new AiState(UpdateWalking) { Init = InitWalking }; + stateWalking.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("idle"), 750, 1500)); + stateWalking.Trigger.Add(_changeDirectionSwitch = new AiTriggerSwitch(250)); + + var stateFly = new AiState(UpdateFlying); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("walking", stateWalking); + _aiComponent.States.Add("flying", stateFly); + _aiComponent.ChangeState("idle"); + + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(AnimationComponent.Index, animationComponent); + AddComponent(CollisionComponent.Index, new BodyCollisionComponent(_body, Values.CollisionTypes.Normal)); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush) { RepelMultiplier = 0.5f }); + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, OnHit)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite)); + } + + private void InitIdle() + { + // stop and wait + _body.VelocityTarget = Vector2.Zero; + _animator.Play("idle_" + _direction); + } + + private void InitWalking() + { + // change the direction + var rotation = Game1.RandomNumber.Next(0, 628) / 100f; + _body.VelocityTarget = new Vector2( + (float)Math.Sin(rotation), + (float)Math.Cos(rotation)) * Game1.RandomNumber.Next(35, 55) / 100f; + _direction = _body.VelocityTarget.X < 0 ? 0 : 1; + + _animator.Play("idle_" + _direction); + } + + private void UpdateWalking() + { + if (_body.IsGrounded) + _body.Velocity.Z = 1.0f; + } + + private void ToFlying() + { + _body.IgnoresZ = true; + _direction = _body.VelocityTarget.X < 0 ? 0 : 1; + _animator.Play("fly_" + _direction); + _aiComponent.ChangeState("flying"); + } + + private void UpdateFlying() + { + _flyCounter += Game1.DeltaTime; + EntityPosition.Z = (float)Math.Sin((_flyCounter / _flyTime) * Math.PI) * 8; + + // finished flying? + if (_flyCounter >= _flyTime) + { + _flyCounter = 0; + _body.IgnoresZ = false; + _aiComponent.ChangeState("walking"); + } + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + // flee from the player + var playerDir = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + if (playerDir != Vector2.Zero) + playerDir.Normalize(); + + _body.VelocityTarget = playerDir * 0.75f; + + ToFlying(); + + return Values.HitCollision.Blocking; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Continues) + _body.Velocity = new Vector3(direction.X, direction.Y, 0) * 0.65f; + else if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction.X, direction.Y, _body.Velocity.Z) * 1.5f; + + return true; + } + + private void OnCollision(Values.BodyCollision moveCollision) + { + // can only change the direction every so often + if (!_changeDirectionSwitch.State || _aiComponent.CurrentStateId != "walking") + return; + _changeDirectionSwitch.Reset(); + + // rotate after wall collision + if ((moveCollision & Values.BodyCollision.Horizontal) != 0) + _body.VelocityTarget.X = -_body.VelocityTarget.X * 0.5f; + else if ((moveCollision & Values.BodyCollision.Vertical) != 0) + _body.VelocityTarget.Y = -_body.VelocityTarget.Y * 0.5f; + + if ((moveCollision & (Values.BodyCollision.Vertical | Values.BodyCollision.Horizontal)) != 0) + { + _direction = _body.VelocityTarget.X < 0 ? 0 : 1; + _animator.Play("idle_" + _direction); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjLetterBoy.cs b/InGame/GameObjects/NPCs/ObjLetterBoy.cs new file mode 100644 index 0000000..9696ab6 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjLetterBoy.cs @@ -0,0 +1,79 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + class ObjLetterBoy : GameObject + { + private readonly Animator _animator; + private readonly string _dialogId; + + private float _lookCounter; + private bool _look; + + public ObjLetterBoy() : base("letter_boy") { } + + public ObjLetterBoy(Map.Map map, int posX, int posY, string dialogId) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-12, -24, 24, 40); + + _dialogId = dialogId; + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/npc_letter_boy"); + _animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, Vector2.Zero); + var body = new BodyComponent(EntityPosition, -8, -13, 16, 12, 8); + + AddComponent(BodyComponent.Index, body); + AddComponent(CollisionComponent.Index, new BodyCollisionComponent(body, Values.CollisionTypes.Normal | Values.CollisionTypes.PushIgnore)); + AddComponent(InteractComponent.Index, new InteractComponent(new CBox(EntityPosition, -7, -10, 14, 24, 8), Interact)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(body, sprite)); + } + + private void Update() + { + // look at the player + var box = new RectangleF(EntityPosition.X - 14, EntityPosition.Y - 8, 28, 16); + if (MapManager.ObjLink.BodyRectangle.Intersects(box)) + { + if (!_look) + { + _lookCounter = 250; + _look = true; + var _direction = EntityPosition.X < MapManager.ObjLink.PosX ? 1 : -1; + _animator.Play("look_" + _direction); + } + } + else if (_look) + { + if (_lookCounter > 0) + { + _lookCounter -= Game1.DeltaTime; + } + else + { + _look = false; + _animator.Play("idle"); + } + } + } + + private bool Interact() + { + Game1.GameManager.StartDialogPath(_dialogId); + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjLinkFishing.cs b/InGame/GameObjects/NPCs/ObjLinkFishing.cs new file mode 100644 index 0000000..3d28f71 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjLinkFishing.cs @@ -0,0 +1,296 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.GameSystems; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjLinkFishing : GameObject + { + public static ObjFish HookedFish; + public static Vector2 HookPosition; + public static bool HasFish; + + private readonly CSprite _sprite; + private readonly Animator _animator; + + private readonly Rectangle _hookSource = new Rectangle(384, 210, 16, 13); + private readonly Rectangle _hookSourceHooked = new Rectangle(389, 211, 8, 8); + private readonly Vector2 _hookStartPosition = new Vector2(117, 40); + + private Vector2 _hookVelocity; + + private int _fishCount; + + private bool _isFishing; + private bool _isTransitioning; + private bool _wasInWater; + private bool _pulledOut; + + public ObjLinkFishing(Map.Map map, int posX, int posY) : base(map) + { + SprEditorImage = Resources.SprLink; + EditorIconSource = new Rectangle(313, 133, 25, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("link fishing"); + _animator.Play("idle"); + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + HookedFish = null; + HookPosition = _hookStartPosition; + HasFish = false; + + Game1.GameManager.SaveManager.SetString("leavePond", "no"); + Game1.GameManager.SaveManager.SetString("emptyPond", "0"); + + // set camera target position + map.CameraTarget = new Vector2(80, 64); + + MapManager.ObjLink.NextMapPositionStart = map.CameraTarget; + MapManager.ObjLink.NextMapPositionEnd = map.CameraTarget; + MapManager.ObjLink.TransitionInWalking = false; + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-18, -16)); + + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + } + + public override void Init() + { + var marin = MapManager.ObjLink.GetMarin(); + if (marin != null) + marin.IsHidden = true; + } + + private void Update() + { + // hide the real player + MapManager.ObjLink.UpdatePlayer = false; + MapManager.ObjLink.IsVisible = false; + + var direction = new Vector2(122, 38) - HookPosition; + + if (!_isFishing) + { + // start hook throw animation + if (ControlHandler.ButtonPressed(CButtons.A)) + { + _animator.Play("throw"); + } + + // set the hook position to the animation + if (_animator.IsPlaying && _animator.CurrentAnimation.Id == "throw" && _animator.CurrentFrameIndex <= 5) + { + HookPosition = EntityPosition.Position + new Vector2(-18, -16) + new Vector2( + _animator.CollisionRectangle.X, _animator.CollisionRectangle.Y); + } + + // throw hook + if (_animator.CurrentFrameIndex == 5) + { + Game1.GameManager.PlaySoundEffect("D360-08-08"); + _hookVelocity = new Vector2(-2.0f, -1f); + _isFishing = true; + HasFish = false; + } + } + + if (_isFishing) + { + if (!_pulledOut) + { + if (!_animator.IsPlaying) + { + _animator.Play(HookedFish == null ? "idle" : "hooked"); + } + + if (ControlHandler.ButtonPressed(CButtons.A)) + { + _animator.Play(HookedFish == null ? "pull_right" : "hooked_pull"); + + if (!(HasFish && HookedFish == null) && direction.Length() <= 4) + { + PulledInHook(); + return; + } + + // pull in the hook + if (direction != Vector2.Zero) + direction.Normalize(); + _hookVelocity = direction * 2.0f; + } + } + + if (_pulledOut) + { + if (!_animator.IsPlaying) + { + // show victory message + Game1.GameManager.StartDialogPath(HookedFish.DialogName); + + ResetFishing(); + + // remove the fish from the map + Map.Objects.DeleteObjects.Add(HookedFish); + HookedFish = null; + } + } + // not fish hooked + else if (HookedFish == null) + { + // pull the hook up + if (HookPosition.Y >= 40 && ControlHandler.ButtonPressed(CButtons.Right)) + { + _animator.Play("pull_up"); + _hookVelocity = new Vector2(0, -2.0f); + } + + // hook is in the air? + if (HookPosition.Y < 32) + { + _hookVelocity *= (float)Math.Pow(0.99, Game1.TimeMultiplier); + _hookVelocity.Y += 0.035f * Game1.TimeMultiplier; + } + else + { + _hookVelocity *= (float)Math.Pow(0.75, Game1.TimeMultiplier); + _hookVelocity.Y += 0.05f * Game1.TimeMultiplier; + + if (!_wasInWater) + { + _wasInWater = true; + var splashAnimator = new ObjAnimator(Map, 0, 0, 0, 36, 0, "Particles/fishingSplash", "idle", true); + splashAnimator.EntityPosition.Set(new Vector2(HookPosition.X + 2, 0)); + Map.Objects.SpawnObject(splashAnimator); + } + } + + HookPosition += _hookVelocity * Game1.TimeMultiplier; + + // floor + if (HookPosition.Y > 110) + { + HookPosition.Y = 110; + _hookVelocity.Y = 0; + } + + // notify fish inside the hook range + var interactBox = new Box(HookPosition.X - 8, HookPosition.Y - 1, 0, 22, 6, 8); + Map.Objects.InteractWithObject(interactBox); + } + else + { + HookedFish.Body.Velocity.X += _hookVelocity.X * 0.2f; + HookedFish.Body.Velocity.Y += _hookVelocity.Y * 0.2f; + _hookVelocity = Vector2.Zero; + + // lost the fish? + if (HookedFish.EntityPosition.X <= -8) + { + HasFish = false; + Map.Objects.DeleteObjects.Add(HookedFish); + HookedFish = null; + LoosedFish(); + } + } + } + } + + private void Draw(SpriteBatch spriteBatch) + { + _sprite.Draw(spriteBatch); + + if (_pulledOut) + return; + + var source = _hookSource; + // hock is up/down + if (_hookVelocity.Y >= 0) + source.Y += 16; + // rotate color + else if (_isFishing && HookPosition.Y >= 28) + source.X += 16 * (Game1.TotalGameTime % 200 < 100 ? 1 : 0); + + if (HookedFish == null) + spriteBatch.Draw(Resources.SprLink, HookPosition - new Vector2(9, 6), source, Color.White); + else + spriteBatch.Draw(Resources.SprLink, HookPosition - new Vector2(4, 6), _hookSourceHooked, Color.White); + + //spriteBatch.Draw(Resources.SprWhite, new Vector2(HookPosition.X - 2, HookPosition.Y - 2), new Rectangle(0, 0, 4, 4), Color.Yellow * 0.5f); + } + + private void PulledInHook() + { + if (HookedFish != null) + { + _animator.Play("pullout"); + + _pulledOut = true; + + IncrementFishCount(); + + HookedFish.ToJump(); + } + else + { + ResetFishing(); + Game1.GameManager.StartDialogPath("fishing_empty"); + } + } + + private void LoosedFish() + { + ResetFishing(); + + IncrementFishCount(); + + Game1.GameManager.StartDialogPath("fishing_loss"); + } + + private void ResetFishing() + { + _pulledOut = false; + _wasInWater = false; + _isFishing = false; + HookPosition = _hookStartPosition; + _animator.Play("idle"); + } + + private void IncrementFishCount() + { + _fishCount++; + // is the pond empty + if (_fishCount >= 5) + Game1.GameManager.SaveManager.SetString("emptyPond", "1"); + } + + private void KeyChanged() + { + // spawn object + if (_isTransitioning || Game1.GameManager.SaveManager.GetString("leavePond") != "yes") return; + + _isTransitioning = true; + + MapManager.ObjLink.MapTransitionStart = MapManager.ObjLink.EntityPosition.Position; + MapManager.ObjLink.MapTransitionEnd = MapManager.ObjLink.EntityPosition.Position; + + // append a map change + ((MapTransitionSystem)Game1.GameManager.GameSystems[typeof(MapTransitionSystem)]).AppendMapChange("overworld.map", "pond"); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjLostBoy.cs b/InGame/GameObjects/NPCs/ObjLostBoy.cs new file mode 100644 index 0000000..6ba6e1d --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjLostBoy.cs @@ -0,0 +1,86 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + class ObjLostBoy : GameObject + { + private readonly BodyComponent _body; + private readonly Animator _animator; + private readonly CSprite _sprite; + + private int _direction; + private bool _eating; + + public ObjLostBoy() : base("lost_boy") { } + + public ObjLostBoy(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/npc_lost_boy"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -7, -12, 14, 12, 8); + + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + AddComponent(BodyComponent.Index, _body); + AddComponent(CollisionComponent.Index, new BodyCollisionComponent(_body, Values.CollisionTypes.Normal)); + AddComponent(InteractComponent.Index, new InteractComponent(_body.BodyBox, Interact)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _sprite)); + } + + private void Update() + { + if (_eating) + return; + + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + var playerDistance = playerDirection.Length(); + + if (playerDistance < 32) + { + if (MapManager.ObjLink.EntityPosition.X > EntityPosition.X - 4 - _direction * 4) + _direction = 2; + else + _direction = 0; + + _animator.Play("hand_" + _direction); + } + else + { + _animator.Play("wave_" + _direction); + } + } + + private void KeyChanged() + { + // start eating animation? + var strEat = "npc_lost_boy_eat"; + var eatValue = Game1.GameManager.SaveManager.GetString(strEat); + if (eatValue != null) + { + _eating = true; + _animator.Play("eat_0"); + Game1.GameManager.SaveManager.RemoveString(strEat); + } + } + + private bool Interact() + { + Game1.GameManager.StartDialogPath("npc_lost_boy"); + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjMamu.cs b/InGame/GameObjects/NPCs/ObjMamu.cs new file mode 100644 index 0000000..0f82461 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjMamu.cs @@ -0,0 +1,223 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjMamu : GameObject + { + private readonly BodyComponent _body; + private readonly Animator _animator; + + private readonly ObjPersonNew _leftFrog; + private readonly ObjPersonNew _rightFrog; + + private Rectangle _interactRectangle; + private bool _wasColliding; + + private readonly string _saveKey; + + struct AnimationKeyframe + { + public float Time; + public string Left; + public string Right; + public string Middle; + + public AnimationKeyframe(float time, string left, string right, string middle) + { + Time = time; + Left = left; + Right = right; + Middle = middle; + } + } + + private AnimationKeyframe[] _songKeyframes = new AnimationKeyframe[] + { + new AnimationKeyframe(0f , "idle", "idle", "right"), + new AnimationKeyframe(0.9f , "right", "idle", "right"), + new AnimationKeyframe(1.85f, "right", "right", "right"), + new AnimationKeyframe(3.2f , "right", "right", "idleleft"), + new AnimationKeyframe(3.75f, "idle", "idle", "left"), + new AnimationKeyframe(4.2f , "idle", "idle", "idleright"), + new AnimationKeyframe(4.7f , "left", "idle", "right"), + new AnimationKeyframe(5.15f, "idle", "idle", "idleleft"), + new AnimationKeyframe(5.65f, "right", "left", "left"), + new AnimationKeyframe(6.1f , "idle", "idle", "idleright"), + new AnimationKeyframe(6.55f, "left", "right", "right"), + new AnimationKeyframe(7f , "idle", "idle", "idleleft"), + new AnimationKeyframe(7.5f , "right", "left", "left"), + new AnimationKeyframe(8f , "idle", "idle", "idleright"), + new AnimationKeyframe(8.45f, "left", "right", "right"), + new AnimationKeyframe(8.9f , "idle", "idle", "idleleft"), + new AnimationKeyframe(9.4f , "right", "left", "left"), + new AnimationKeyframe(9.85f, "idle", "idle", "idleright"), + new AnimationKeyframe(10.3f, "left", "right", "right"), + new AnimationKeyframe(10.8f, "idle", "idle", "idleleft"), + new AnimationKeyframe(11.25f, "right", "left", "left"), + new AnimationKeyframe(11.7f , "idle", "idle", "idleright"), + new AnimationKeyframe(12.2f , "left", "right", "right"), + new AnimationKeyframe(12.65f, "idle", "idle", "right"), + new AnimationKeyframe(13.1f , "right", "left", "right"), + new AnimationKeyframe(13.6f , "right", "idle", "right"), + new AnimationKeyframe(14.1f , "right", "right", "right"), + new AnimationKeyframe(14.1f , "right", "right", "right"), + new AnimationKeyframe(14.5f , "right", "right", "idleright"), + new AnimationKeyframe(15f , "idle", "idle", "right"), + new AnimationKeyframe(15.45f, "idle", "idle", "idleleft"), + new AnimationKeyframe(15.95f, "right", "idle", "left"), + new AnimationKeyframe(16.4f , "idle", "idle", "idleright"), + new AnimationKeyframe(16.85f, "left", "right", "right"), + new AnimationKeyframe(17.35f, "idle", "idle", "idleleft"), + new AnimationKeyframe(17.8f , "right", "left", "left"), + new AnimationKeyframe(18.3f , "idle", "idle", "idleright"), + new AnimationKeyframe(18.75f, "left", "right", "right"), + new AnimationKeyframe(19.3f , "idle", "idle", "idleleft"), + new AnimationKeyframe(19.7f , "right", "left", "left"), + new AnimationKeyframe(20.15f, "idle", "idle", "idleright"), + new AnimationKeyframe(20.6f , "left", "right", "right"), + new AnimationKeyframe(21.1f , "idle", "idle", "idleleft"), + new AnimationKeyframe(21.55f, "right", "left", "left"), + new AnimationKeyframe(22f , "idle", "idle", "idleright"), + new AnimationKeyframe(22.5f , "left", "right", "right"), + new AnimationKeyframe(22.95f, "idle", "idle", "idleleft"), + new AnimationKeyframe(23.4f , "right", "left", "left"), + new AnimationKeyframe(23.9f , "idle", "idle", "left"), + new AnimationKeyframe(24.4f , "left", "right", "left"), + new AnimationKeyframe(24.85f, "left", "idle", "left"), + new AnimationKeyframe(25.3f, "left", "left", "left"), + new AnimationKeyframe(26.3f, "idle", "idle", "idle") + }; + + private float _startDelay; + private float _songCounter; + private int _songIndex; + private bool _isPlaying; + private bool _startedPlaying; + + public ObjMamu() : base("mamu") { } + + public ObjMamu(Map.Map map, int posX, int posY, string saveKey) : base(map) + { + _saveKey = saveKey; + if (!string.IsNullOrEmpty(_saveKey) && + Game1.GameManager.SaveManager.GetString(_saveKey) == "1") + { + IsDead = true; + return; + } + + EntityPosition = new CPosition(posX + 16, posY + 32, 0); + EntitySize = new Rectangle(-16, -32, 32, 32); + + _interactRectangle = new Rectangle(posX + 16 - 12, posY + 16, 24, 32); + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/mamu"); + _animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -16, -32, 32, 32, 8); + + var interactBox = new CBox(posX + 2, posY + 16, 0, 28, 16, 8); + AddComponent(InteractComponent.Index, new InteractComponent(interactBox, OnInteract)); + + AddComponent(BodyComponent.Index, _body); + AddComponent(CollisionComponent.Index, new BodyCollisionComponent(_body, Values.CollisionTypes.Normal)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + + _leftFrog = new ObjPersonNew(map, posX - 32, posY + 42, null, "singing frog", null, "idle", new Rectangle(0, 0, 14, 12)); + map.Objects.SpawnObject(_leftFrog); + + _rightFrog = new ObjPersonNew(map, posX + 48, posY + 42, null, "singing frog", null, "idle", new Rectangle(0, 0, 14, 12)); + map.Objects.SpawnObject(_rightFrog); + + } + + private bool OnInteract() + { + Game1.GameManager.StartDialogPath("mamu"); + + return true; + } + + private void OnKeyChange() + { + var startSing = Game1.GameManager.SaveManager.GetString("mamu_sing"); + if (!_startedPlaying && startSing == "1") + { + _startDelay = 2500; + Game1.GameManager.SaveManager.RemoveString("mamu_sing"); + } + } + + private void StartSong() + { + Game1.GameManager.SetMusic(52, 2); + _isPlaying = true; + _startedPlaying = true; + } + + private void Update() + { + if (!_startedPlaying && MapManager.ObjLink.IsGrounded()) + { + var colliding = MapManager.ObjLink.BodyRectangle.Intersects(_interactRectangle); + if (!_wasColliding && colliding) + { + Game1.GameManager.StartDialogPath("mamu"); + } + + _wasColliding = colliding; + } + + if (_startDelay != 0) + { + _startDelay -= Game1.DeltaTime; + if (_startDelay <= 0) + { + _startDelay = 0; + StartSong(); + } + + MapManager.ObjLink.FreezePlayer(); + Game1.GameManager.InGameOverlay.DisableInventoryToggle = true; + } + + if (!_isPlaying) + return; + + MapManager.ObjLink.FreezePlayer(); + Game1.GameManager.InGameOverlay.DisableInventoryToggle = true; + + _songCounter += Game1.DeltaTime; + + // new keyframe? + if (_songCounter >= _songKeyframes[_songIndex].Time * 1000) + { + // set the animations + _leftFrog.Animator.Play(_songKeyframes[_songIndex].Left); + _animator.Play(_songKeyframes[_songIndex].Middle); + _rightFrog.Animator.Play(_songKeyframes[_songIndex].Right); + + // finished playing? + _songIndex++; + if (_songIndex >= _songKeyframes.Length) + { + _isPlaying = false; + Game1.GameManager.StartDialogPath("mamu_finished"); + } + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjManbo.cs b/InGame/GameObjects/NPCs/ObjManbo.cs new file mode 100644 index 0000000..e6e8e6d --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjManbo.cs @@ -0,0 +1,266 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjManbo : GameObject + { + struct AnimationKeyframe + { + public float Time; + public int Animation; + + public AnimationKeyframe(float time, int animation) + { + Time = time; + Animation = animation; + } + } + + // 0 idle + // 1 close mouth + // 2 angry + // 3 eye + private AnimationKeyframe[] _songKeyframes = new AnimationKeyframe[] + { + new AnimationKeyframe( 0.00f, 0), + new AnimationKeyframe( 2.65f, 1), + new AnimationKeyframe( 3.35f, 2), + new AnimationKeyframe( 4.05f, 1), + new AnimationKeyframe( 4.55f, 0), + new AnimationKeyframe( 8.00f, 3), + new AnimationKeyframe(13.35f, 3), + new AnimationKeyframe(18.75f, 3), + new AnimationKeyframe(22.75f, 3), + new AnimationKeyframe(24.55f, 2), + new AnimationKeyframe(25.25f, 1) + }; + + private readonly BodyComponent _body; + private readonly Animator _animator; + private readonly Animator _animatorEye; + private readonly Animator _animatorMouth; + private readonly DictAtlasEntry _spriteTextbox; + + private readonly ObjDancingFish _leftFish; + private readonly ObjDancingFish _rightFish; + private ObjOnPushDialog _objPushDialog; + + private float _songCounter; + private int _songIndex; + private int _animationIndex; + + private int _fishAnimationIndex; + private int _fishAnimationDirection = -1; + private int _lastEyeIndex; + + private Vector2 _startPosition; + + private bool _isPlaying; + private bool _startedPlaying; + + public ObjManbo() : base("manbo") { } + + public ObjManbo(Map.Map map, int posX, int posY, string saveKey) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 32, 48); + + _startPosition = new Vector2(posX, posY); + + _spriteTextbox = Resources.GetSprite("manbo oh"); + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/manbo"); + _animatorEye = AnimatorSaveLoad.LoadAnimator("NPCs/manbo"); + _animatorMouth = AnimatorSaveLoad.LoadAnimator("NPCs/manbo"); + _animator.Play("fish_static"); + _animatorEye.Play("eye"); + _animatorMouth.Play("mouth_idle"); + + _body = new BodyComponent(EntityPosition, 0, 12, 32, 24, 8) + { + IgnoresZ = true + }; + + var interactBox = new CBox(posX, posY, 0, 32, 48, 8); + AddComponent(InteractComponent.Index, new InteractComponent(interactBox, OnInteract)); + + AddComponent(BodyComponent.Index, _body); + AddComponent(CollisionComponent.Index, new BodyCollisionComponent(_body, Values.CollisionTypes.Normal)); + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + + _leftFish = new ObjDancingFish(map, new Vector2(posX - 25, posY + 70)); + _rightFish = new ObjDancingFish(map, new Vector2(posX + 23, posY + 70)); + map.Objects.SpawnObject(_leftFish); + map.Objects.SpawnObject(_rightFish); + + if (Game1.GameManager.SaveManager.GetString("manbo") != "1") + { + _objPushDialog = new ObjOnPushDialog(map, posX - 24, posY - 32, 32, 90 + 32, "manbo"); + map.Objects.SpawnObject(_objPushDialog); + } + } + + private bool OnInteract() + { + Game1.GameManager.StartDialogPath("manbo"); + + return true; + } + + private void OnKeyChange() + { + var startSing = Game1.GameManager.SaveManager.GetString("manbo_start_song"); + if (!_startedPlaying && startSing == "1") + { + Game1.GameManager.SaveManager.SetString("manbo_start_song", "0"); + StartSong(); + } + } + + private void StartSong() + { + Game1.GameManager.SetMusic(47, 2); + _isPlaying = true; + _startedPlaying = true; + + _animator.Play("fish"); + PlayFishAnimation("forward"); + + if (_objPushDialog != null) + { + Map.Objects.DeleteObjects.Add(_objPushDialog); + _objPushDialog = null; + } + } + + private void Update() + { + _lastEyeIndex = _animatorEye.CurrentFrameIndex; + + _animator.Update(); + _animatorMouth.Update(); + _animatorEye.Update(); + + if (_animationIndex == 2 && _songIndex > 6) + { + PlayFishAnimation("splash"); + } + + // fish eye roll animation + if (_animationIndex == 3) + { + if (_lastEyeIndex < _animatorEye.CurrentFrameIndex) + { + _fishAnimationIndex += _fishAnimationDirection; + + if (_fishAnimationIndex == 1) + PlayFishAnimation("left"); + else if (_fishAnimationIndex == 2) + PlayFishAnimation("forward"); + else if (_fishAnimationIndex == 3) + PlayFishAnimation("right"); + } + + if (!_animatorEye.IsPlaying) + { + PlayAnimation(0); + } + } + + if (_isPlaying) + { + MapManager.ObjLink.FreezePlayer(); + Game1.GameManager.InGameOverlay.DisableInventoryToggle = true; + + _songCounter += Game1.DeltaTime; + + // new keyframe? + if (_songCounter >= _songKeyframes[_songIndex].Time * 1000) + { + if (_animationIndex == 2) + PlayFishAnimation("idle"); + + // set the animations + PlayAnimation(_songKeyframes[_songIndex].Animation); + + // finished playing? + _songIndex++; + if (_songIndex >= _songKeyframes.Length) + { + _isPlaying = false; + _animator.Play("fish_static"); + Game1.GameManager.StartDialogPath("manbo_finished"); + } + } + } + } + + private void PlayFishAnimation(string animationId) + { + _leftFish.Animator.Play(animationId); + _rightFish.Animator.Play(animationId); + } + + private void PlayAnimation(int animationIndex) + { + _animationIndex = animationIndex; + + // 0 idle + // 1 close mouth + // 2 angry + // 3 eye + switch (_animationIndex) + { + case 0: + _animator.Continue(); + _animatorEye.Play("eye"); + _animatorMouth.Play("mouth_slow"); + break; + case 1: + _animator.Pause(); + _animatorEye.Play("eye"); + _animatorMouth.Play("mouth_closed"); + break; + case 2: + _animator.Continue(); + _animatorEye.Play("eye_angry"); + _animatorMouth.Play("mouth_slow"); + break; + case 3: + _lastEyeIndex = 1; + _fishAnimationDirection = -_fishAnimationDirection; + _animator.Pause(); + _animatorEye.Play("eye_roll"); + _animatorMouth.Play("mouth_slow"); + break; + } + } + + private void Draw(SpriteBatch spriteBatch) + { + _animator.Draw(spriteBatch, EntityPosition.Position, Color.White); + _animatorMouth.Draw(spriteBatch, new Vector2(EntityPosition.X, EntityPosition.Y + 17), Color.White); + _animatorEye.Draw(spriteBatch, new Vector2(EntityPosition.X + 1, EntityPosition.Y + 12), Color.White); + + if (_animationIndex == 2) + { + DrawHelper.DrawNormalized(spriteBatch, _spriteTextbox, new Vector2(_startPosition.X - 24, _startPosition.Y - 8), Color.White); + if (_songIndex > 6) + { + DrawHelper.DrawNormalized(spriteBatch, _spriteTextbox, new Vector2(_startPosition.X - 56, _startPosition.Y + 42), Color.White); + DrawHelper.DrawNormalized(spriteBatch, _spriteTextbox, new Vector2(_startPosition.X - 8, _startPosition.Y + 42), Color.White); + } + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjMarin.cs b/InGame/GameObjects/NPCs/ObjMarin.cs new file mode 100644 index 0000000..88a4ab9 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjMarin.cs @@ -0,0 +1,961 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Systems; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.GameSystems; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + public class ObjMarin : GameObjectFollower + { + private enum States { Idle, Sequence, Fade, Singing, SingingFinal, AnimalSinging, SingingDuo, PostDuo, SingingWalrus, FollowPlayer, Jumping, Saved, DungeonReturn }; + private States _currentState = States.Idle; + + struct MoveStep + { + public bool OffsetMode; + public float MoveSpeed; + public Vector2 Offset; + public Vector2 Position; + } + private Queue _nextMoveStep = new Queue(); + + public override bool IsActive + { + get => base.IsActive; + set + { + base.IsActive = value; + if (value) + Activate(); + } + } + + public bool IsHidden; + private bool _wasHidden; + + public bool EnterDungeonMessage; + + private bool _enterDungeonMessage; + private bool _dungeonLeaveSequence; + + private Rectangle _field; + + private Vector2 _returnStart; + private Vector2 _returnEnd; + + private Vector2 _railJumpStartPosition; + private Vector2 _railJumpTargetPosition; + private float _railJumpSpeed; + private float _railJumpHeight; + private float _railJumpPercentage; + private bool _isRailJumping; + private float _holeAbsorbCounter; + private bool _holeAbsorb; + + private bool _fountainSequence; + private bool _fountainMouse; + private bool _fountainSeqInit; + + private float _returnCounter; + private bool _returnInit; + private bool _returnFinished; + + private double _dungeonEnterTime; + private int _dungeonEnterLives; + + private readonly BodyComponent _body; + private readonly Animator _animator; + private readonly BodyDrawComponent _bodyDrawComponent; + private readonly CSprite _sprite; + private readonly BodyDrawShadowComponent _shadowComponent; + + private readonly DictAtlasEntry _spriteNote; + + private Vector2 _followVelocity; + + private Vector2 _targetPosition; + private float _moveSpeed; + + private float _fadeTime; + private float _fadeCounter; + + private float _noteCount; + private float _noteEndTime; + private int _lastDirection = -1; + private int _cycleTime = 1000; + + private float _duoCounter; + private int _duoIndex; + private int _walkDirection; + + private bool _isSinging; + private bool _isSingingWithSound; + + private bool _helpDialogShown; + private bool _isPulled; + private int _pullOffsetY; + + private bool _isMoving; + + public ObjMarin() : base("marin") { } + + public ObjMarin(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _spriteNote = Resources.GetSprite("note"); + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/marin"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + if (map != null) + _field = map.GetField(posX, posY); + + _body = new BodyComponent(EntityPosition, -7, -10, 14, 10, 8) + { + //CollisionTypes = Values.CollisionTypes.None + MoveCollision = OnCollision, + IgnoreHoles = true, + Gravity = -0.15f + }; + _bodyDrawComponent = new BodyDrawComponent(_body, _sprite, 1); + + var mariaState = Game1.GameManager.SaveManager.GetString("maria_state"); + + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + AddComponent(BodyComponent.Index, _body); + AddComponent(CollisionComponent.Index, new BodyCollisionComponent(_body, Values.CollisionTypes.Normal | Values.CollisionTypes.PushIgnore)); + AddComponent(InteractComponent.Index, new InteractComponent(_body.BodyBox, Interact)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + AddComponent(DrawShadowComponent.Index, _shadowComponent = new BodyDrawShadowComponent(_body, _sprite)); + } + + public override void Init() + { + Game1.GameManager.SaveManager.RemoveString("marin_sing_position"); + + _enterDungeonMessage = false; + EnterDungeonMessage = false; + + _sprite.IsVisible = true; + + // fall with the player from the ceiling? + if (MapManager.ObjLink.EntityPosition.Z > 0) + { + EntityPosition.Z = MapManager.ObjLink.EntityPosition.Z; + _body.Velocity.Z = 0.5f; + _body.IsGrounded = false; + _fountainSequence = true; + _fountainMouse = + Game1.GameManager.SaveManager.GetString("photoMouseActive", "0") == "1" && + Game1.GameManager.SaveManager.GetString("photo_sequence_fountain", "0") == "0"; + _fountainSeqInit = false; + + _followVelocity = Vector2.Zero; + _walkDirection = 3; + _animator.Play("jump_down_" + _walkDirection); + } + + // is disabled for the current room? + var wasHidden = IsHidden; + if (IsHidden) + { + IsHidden = false; + base.IsActive = false; + } + else if (_wasHidden) + { + base.IsActive = true; + } + _wasHidden = wasHidden; + + if (_dungeonLeaveSequence) + base.IsActive = true; + + if (IsActive) + Activate(); + } + + public void LeaveDungeonSequence(Vector2 position) + { + _returnInit = true; + _returnFinished = false; + _returnCounter = 0; + + _returnStart = new Vector2(position.X + 40, position.Y + 24); + _returnEnd = new Vector2(position.X + 8, position.Y + 28); + + _dungeonLeaveSequence = true; + Game1.GameManager.SaveManager.SetString("maria_dungeon", "0"); + + _animator.Play("wait"); + } + + public void OnAppendMapChange() + { + if (_currentState == States.FollowPlayer && (_enterDungeonMessage || EnterDungeonMessage)) + { + _body.VelocityTarget = Vector2.Zero; + _currentState = States.Idle; + Game1.GameManager.SaveManager.SetString("maria_dungeon", "1"); + Game1.GameManager.StartDialogPath("marin_dungeon"); + _dungeonEnterTime = Game1.TotalGameTime; + _dungeonEnterLives = Game1.GameManager.CurrentHealth; + + // stop walking + _animator.Stop(); + } + } + + public override void SetPosition(Vector2 position) + { + if (_currentState == States.DungeonReturn) + return; + + EntityPosition.Set(position); + } + + private void Activate() + { + var mariaState = Game1.GameManager.SaveManager.GetString("maria_state"); + + // singing for the animals + // TODO: fade in music + if (mariaState == "3") + { + if (Components[CollisionComponent.Index] != null) + RemoveComponent(CollisionComponent.Index); + + var marinDungeonState = Game1.GameManager.SaveManager.GetString("maria_dungeon"); + if (!string.IsNullOrEmpty(marinDungeonState) && marinDungeonState == "1") + { + IsActive = false; + return; + } + + if (_dungeonLeaveSequence) + { + _dungeonLeaveSequence = false; + _currentState = States.DungeonReturn; + return; + } + + _currentState = States.FollowPlayer; + _followVelocity = Vector2.Zero; + + if (MapManager.ObjLink.NextMapPositionStart.HasValue && + MapManager.ObjLink.NextMapPositionEnd.HasValue) + { + var direction = MapManager.ObjLink.NextMapPositionEnd.Value - + MapManager.ObjLink.NextMapPositionStart.Value; + if (direction != Vector2.Zero) + _walkDirection = AnimationHelper.GetDirection(direction); + _animator.Play("walk_" + _walkDirection); + } + } + else if (mariaState == "4") + { + var animal0 = new ObjPersonNew(Map, (int)EntityPosition.X + 8, (int)EntityPosition.Y - 32, null, "animal_rabbit", "animals_absorbed", "dance_3", new Rectangle(0, 0, 12, 12)); + var animal1 = new ObjPersonNew(Map, (int)EntityPosition.X - 8, (int)EntityPosition.Y + 32, null, "animal_rabbit", "animals_absorbed", "dance_1", new Rectangle(0, 0, 12, 12)); + var animal2 = new ObjPersonNew(Map, (int)EntityPosition.X - 40, (int)EntityPosition.Y + 16, null, "animal_rabbit", "animals_absorbed", "dance_1", new Rectangle(0, 0, 12, 12)); + var animal3 = new ObjPersonNew(Map, (int)EntityPosition.X - 40, (int)EntityPosition.Y - 32, null, "animal 02", "animals_absorbed", "dance", new Rectangle(0, 0, 12, 12)); + var animal4 = new ObjPersonNew(Map, (int)EntityPosition.X + 24, (int)EntityPosition.Y + 16, null, "animal 03", "animals_absorbed", "dance", new Rectangle(0, 0, 12, 12)); + + Map.Objects.SpawnObject(animal0); + Map.Objects.SpawnObject(animal1); + Map.Objects.SpawnObject(animal2); + Map.Objects.SpawnObject(animal3); + Map.Objects.SpawnObject(animal4); + + _currentState = States.AnimalSinging; + + StartSinging(); + // TODO: blend in with distance + //Game1.GameManager.SetMusic(46, 2); + } + else if (mariaState == "5") + { + _currentState = States.Jumping; + _animator.Play("land"); + ((BodyCollisionComponent)Components[BodyCollisionComponent.Index]).IsActive = false; + } + } + + private void Update() + { + // rotate towards the player + if (_currentState == States.Idle) + { + var playerDistance = new Vector2( + MapManager.ObjLink.EntityPosition.X - (EntityPosition.X), + MapManager.ObjLink.EntityPosition.Y - (EntityPosition.Y - 4)); + + var dir = 3; + + // rotate in the direction of the player + if (playerDistance.Length() < 32) + dir = AnimationHelper.GetDirection(playerDistance); + + if (_lastDirection != dir) + { + // look at the player + _animator.Play("stand_" + dir); + _lastDirection = dir; + } + } + else if (_currentState == States.AnimalSinging) + { + // start/stop depending on the distance to the player + var nearPlayer = _field.Contains(MapManager.ObjLink.EntityPosition.Position); + if (!_isSingingWithSound && nearPlayer) + { + _isSingingWithSound = true; + Game1.GameManager.SetMusic(46, 2); + } + else if (_isSingingWithSound && !nearPlayer) + { + _isSingingWithSound = false; + Game1.GameManager.SetMusic(-1, 2); + } + } + else if (_currentState == States.Singing) + { + // stop singing if the player is too far away + var distance = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + if (distance.Length() > 80) + { + StopSinging(); + _currentState = States.Idle; + } + } + else if (_currentState == States.SingingDuo) + { + UpdateSingingDuo(); + } + else if (_currentState == States.FollowPlayer) + { + UpdateFollowPlayer(); + } + else if (_currentState == States.Jumping) + { + var playerPosition = MapManager.ObjLink.EntityPosition.Position; + var playerDirection = EntityPosition.Position - playerPosition; + var distance = playerDirection.Length(); + if (distance < 72 && !_helpDialogShown) + { + _helpDialogShown = true; + Game1.GameManager.StartDialogPath("marin_help"); + } + else if (distance > 128) + { + _helpDialogShown = false; + } + + if (!_isPulled && distance < 16 && playerDirection.X > 8) + { + _isPulled = true; + _pullOffsetY = (int)playerDirection.Y; + _animator.Play("stand_0"); + } + + if (_isPulled) + { + EntityPosition.Set(new Vector2(playerPosition.X + 14, playerPosition.Y + _pullOffsetY)); + if (!MapManager.ObjLink.IsUsingHookshot()) + { + _isPulled = false; + _currentState = States.Saved; + Game1.GameManager.StartDialogPath("marin_saved"); + } + } + + if (_animator.CurrentAnimation.Id == "jump" && _body.IsGrounded) + { + _animator.Play("land"); + } + if (_animator.CurrentAnimation.Id == "land" && !_animator.IsPlaying) + { + _animator.Play("jump"); + _body.Velocity.Z = 1.25f; + } + } + else if (_currentState == States.DungeonReturn) + { + UpdateReturn(); + } + + UpdateMoving(); + + UpdateFade(); + + if (_isSinging || _noteCount < _noteEndTime) + _noteCount += Game1.DeltaTime; + else + _noteCount = _noteEndTime; + } + + private void UpdateReturn() + { + // freeze the player (need to make sure to play the transition animation) + var transitionSystem = (MapTransitionSystem)Game1.GameManager.GameSystems[typeof(MapTransitionSystem)]; + if (!transitionSystem.IsTransitioningIn()) + MapManager.ObjLink.FreezePlayer(); + + _returnCounter += Game1.DeltaTime; + + if (_returnInit) + { + _returnInit = false; + EntityPosition.Set(_returnStart); + } + + if (_returnFinished) + { + _walkDirection = 1; + _animator.Play("stand_1"); + + if (_returnCounter > 2500) + { + // show message after having 4 or less lives and having walked into the dungeon with more than 4 + // there are two different dialogs; the second one appear not as often as the first one + var heartsDialog = Game1.GameManager.CurrentHealth <= 4 && (_dungeonEnterLives >= 4 || _dungeonEnterLives == 0); + var randomDialog = Game1.RandomNumber.Next(0, 5); + Game1.GameManager.SaveManager.SetString("marin_dungeon_hearts", heartsDialog ? (randomDialog < 4 ? "1" : "2") : "0"); + + // show a different message after two minutes; does not work correctly if the savestate is loaded + var longTimeDialog = _dungeonEnterTime + 120000 < Game1.TotalGameTime; + Game1.GameManager.SaveManager.SetString("marin_dungeon_time", longTimeDialog ? "1" : "0"); + + _currentState = States.FollowPlayer; + Game1.GameManager.StartDialogPath("marin_dungeon_leave"); + } + + return; + } + + // start walking + if (_returnCounter > 1500) + { + _animator.Play("walk_0"); + var newPosition = AnimationHelper.MoveToTarget(EntityPosition.Position, _returnEnd, 0.75f * Game1.TimeMultiplier); + EntityPosition.Set(newPosition); + + if (newPosition == _returnEnd) + _returnFinished = true; + } + } + + private void UpdateFade() + { + if (_fadeTime <= 0) + return; + + _fadeCounter -= Game1.DeltaTime; + + if (_fadeCounter <= 0) + Map.Objects.DeleteObjects.Add(this); + else + { + var percentage = _fadeCounter / _fadeTime; + _sprite.Color = Color.White * percentage; + _shadowComponent.Transparency = percentage; + } + } + + private void UpdateMoving() + { + if (!_isMoving) + return; + + // move towards the target position + var targetDistance = _targetPosition - EntityPosition.Position; + if (targetDistance.Length() > _moveSpeed * Game1.TimeMultiplier) + { + targetDistance.Normalize(); + _body.VelocityTarget = targetDistance * _moveSpeed; + + var dir = AnimationHelper.GetDirection(targetDistance); + _animator.Play("walk_" + dir); + } + // finished walking + else + { + _body.VelocityTarget = Vector2.Zero; + EntityPosition.Set(_targetPosition); + + if (_nextMoveStep.Count > 0) + DequeueMove(); + else + { + _isMoving = false; + SetMovingString(false); + } + } + } + + private void DequeueMove() + { + var move = _nextMoveStep.Dequeue(); + _moveSpeed = move.MoveSpeed; + + if (!move.OffsetMode) + _targetPosition = move.Position; + else + _targetPosition = EntityPosition.Position + move.Offset; + } + + private void SetMovingString(bool state) + { + Game1.GameManager.SaveManager.SetString("marinMoving", state ? "1" : "0"); + } + + private void UpdateSingingDuo() + { + _duoCounter += Game1.DeltaTime; + if (_duoIndex == 0 && _duoCounter > 7500) + { + _duoIndex++; + _isSinging = false; + _animator.Play("idle"); + MapManager.ObjLink.StartOcarinaDuo(); + } + else if (_duoIndex == 1 && _duoCounter > 16000) + { + _duoIndex++; + _isSinging = true; + _animator.Play("sing"); + } + else if (_duoIndex == 2 && _duoCounter > 32000) + { + _duoIndex++; + _isSinging = false; + _animator.Play("idle"); + } + else if (_duoIndex == 3 && _duoCounter > 33000) + { + _currentState = States.PostDuo; + MapManager.ObjLink.StopOcarinaDuo(); + Game1.GameManager.StartDialogPath("marin_singing_end"); + Game1.GameManager.SetMusic(-1, 2); + + Game1.GameManager.SaveManager.RemoveString("marin_sing_position"); + } + + if (_duoIndex == 0) + MapManager.ObjLink.FreezePlayer(); + } + + private void OnCollision(Values.BodyCollision collision) + { + if ((collision & Values.BodyCollision.Vertical) != 0) + { + _followVelocity.X += Math.Abs(_followVelocity.Y) * MathF.Sign(_followVelocity.X); + _followVelocity.Y = 0; + } + if ((collision & Values.BodyCollision.Horizontal) != 0) + { + _followVelocity.Y += Math.Abs(_followVelocity.X) * MathF.Sign(_followVelocity.Y); + _followVelocity.X = 0; + } + } + + private void UpdateFollowPlayer() + { + if (((MapTransitionSystem)Game1.GameManager.GameSystems[typeof(MapTransitionSystem)]).IsTransitioningIn()) + { + _body.VelocityTarget = Vector2.Zero; + return; + } + + // make sure that the player does not walk before marin hits the ground + // he could potentially collect the heart + if (_fountainMouse) + MapManager.ObjLink.FreezePlayer(); + + if (!_fountainSeqInit && _fountainSequence) + { + _fountainSeqInit = true; + EntityPosition.Set(new Vector2(EntityPosition.X, EntityPosition.Y - 8)); + } + + if (_fountainSequence && _body.IsGrounded) + { + _fountainSequence = false; + _fountainMouse = false; + + var playerDist = MapManager.ObjLink.EntityPosition.Position - new Vector2(EntityPosition.Position.X, EntityPosition.Position.Y + 4); + var fallenOnLink = playerDist.Length() < 8; + + Game1.GameManager.SaveManager.SetString("fallen_on_link", (fallenOnLink ? "1" : "0")); + + Game1.GameManager.StartDialogPath("seq_fountain"); + + if (fallenOnLink) + { + Game1.GameManager.ShakeScreen(450, 0, 2, 0, 5); + Game1.GameManager.PlaySoundEffect("D360-11-0B"); + } + } + + // jump + if (MapManager.ObjLink.CurrentState == ObjLink.State.Jumping && + ((!MapManager.ObjLink.IsRailJumping() && MapManager.ObjLink._body.Velocity.Z < 0) || + MapManager.ObjLink.GetRailJumpAmount() > 0.45f) && _body.IsGrounded) + { + Game1.GameManager.PlaySoundEffect("D360-36-24"); + _body.Velocity.Z = 2.35f; + + if (MapManager.ObjLink.IsRailJumping()) + { + _isRailJumping = true; + _holeAbsorb = false; + + _body.IgnoreHeight = true; + _body.IgnoresZ = true; + _body.IsGrounded = false; + _body.VelocityTarget = Vector2.Zero; + + _railJumpPercentage = 0; + _railJumpStartPosition = EntityPosition.Position; + _railJumpTargetPosition = MapManager.ObjLink.RailJumpTarget(); + _railJumpSpeed = MapManager.ObjLink.RailJumpSpeed(); + _railJumpHeight = MapManager.ObjLink.RailJumpHeight(); + + _walkDirection = MapManager.ObjLink.Direction; + _animator.Play("stand_" + _walkDirection); + } + } + + if (_isRailJumping) + { + _railJumpPercentage += Game1.TimeMultiplier * _railJumpSpeed; + var amount = MathF.Sin(_railJumpPercentage * (MathF.PI * 0.3f)) / MathF.Sin(MathF.PI * 0.3f); + var newPosition = Vector2.Lerp(_railJumpStartPosition, _railJumpTargetPosition, amount); + EntityPosition.Set(newPosition); + + EntityPosition.Z = MathF.Sin(_railJumpPercentage * MathF.PI) * _railJumpHeight; + + // finished rail jump? + if (_railJumpPercentage >= 1) + { + _isRailJumping = false; + _body.IgnoreHeight = false; + _body.IgnoresZ = false; + _body.Velocity.Z = -1f; + EntityPosition.Set(_railJumpTargetPosition); + + } + + if (MapManager.ObjLink.IsHoleAbsorb()) + { + _holeAbsorb = true; + _holeAbsorbCounter = 175; + } + + return; + } + + // fall into a hole with link? + if (_holeAbsorb) + { + _holeAbsorbCounter -= Game1.DeltaTime; + if (_holeAbsorbCounter >= 0) + return; + + var fallAnimation = new ObjAnimator(Map, 0, 0, Values.LayerBottom, "Particles/fall", "idle", true); + fallAnimation.EntityPosition.Set(new Vector2( + _body.Position.X + _body.OffsetX + _body.Width / 2.0f - 5, + _body.Position.Y + _body.OffsetY + _body.Height / 2.0f - 5)); + Map.Objects.SpawnObject(fallAnimation); + + _sprite.IsVisible = false; + _holeAbsorb = false; + + return; + } + + if (MapManager.ObjLink.IsRailJumping()) + return; + + // landed on the ground? + if (_body.IsGrounded && !_body.WasGrounded) + { + Game1.GameManager.PlaySoundEffect("D378-07-07"); + } + + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + var playerDistance = Math.Abs(playerDirection.X) + Math.Abs(playerDirection.Y); + if (playerDirection != Vector2.Zero) + playerDirection.Normalize(); + var walkSpeedMult = playerDistance / 16; + var targetVelocity = Vector2.Zero; + + var collisionCheckDist = 8; + var collidingBox = Box.Empty; + // check for future collisions + var collisionH = SystemBody.Collision(_body, + EntityPosition.X + playerDirection.X * collisionCheckDist, + EntityPosition.Y, 0, _body.CollisionTypes, false, ref collidingBox); + var collisionV = SystemBody.Collision(_body, + EntityPosition.X, + EntityPosition.Y + playerDirection.Y * collisionCheckDist, 0, _body.CollisionTypes, false, ref collidingBox); + + // disable the collision if we are too far away from the player; this will prevent situations where we are stuck + var ignoreCollisions = MapManager.ObjLink.IsRailJumping() || playerDistance > 24; + _body.CollisionTypes = ignoreCollisions ? Values.CollisionTypes.None : Values.CollisionTypes.Normal; + + if (playerDistance > 16) + { + targetVelocity = playerDirection * walkSpeedMult; + // try to avoid future collisions by walking around the colliding object + if (!ignoreCollisions && collisionH) + { + targetVelocity.Y += (Math.Abs(targetVelocity.X) * MathF.Sign(targetVelocity.Y)) * 0.5f; + targetVelocity.X *= 0.5f; + } + else if (!ignoreCollisions && collisionV) + { + targetVelocity.X += (Math.Abs(targetVelocity.Y) * MathF.Sign(targetVelocity.X)) * 0.5f; + targetVelocity.Y *= 0.5f; + } + } + + _followVelocity = Vector2.Lerp(_followVelocity, targetVelocity, 0.45f * Game1.TimeMultiplier); + _body.VelocityTarget = _followVelocity; + + if (_followVelocity.Length() > 0.1f) + _walkDirection = AnimationHelper.GetDirection(_followVelocity); + + // play walk/stand animation + // jump animation + if (MapManager.ObjLink.IsJumping() && _followVelocity.Length() < 0.1f) + { + _animator.Play("jump_up_" + _walkDirection); + } + else if (!_body.IsGrounded) + { + if (_body.Velocity.Z > 0) + _animator.Play("jump_up_" + _walkDirection); + else + _animator.Play("jump_down_" + _walkDirection); + } + else if (_followVelocity.Length() > 0.1f) + { + _animator.Play("walk_" + _walkDirection); + _animator.SpeedMultiplier = walkSpeedMult; + } + else + { + _animator.Play("stand_" + _walkDirection); + } + + _enterDungeonMessage = EnterDungeonMessage; + EnterDungeonMessage = false; + } + + private void StartSinging() + { + _isSinging = true; + _noteCount = 0; + _noteEndTime = 0; + _body.VelocityTarget = Vector2.Zero; + _animator.Play("sing"); + + // set the position for the dogs listening + Game1.GameManager.SaveManager.SetString("marin_sing_position", (int)EntityPosition.X + "," + (int)EntityPosition.Y); + } + + private void StopSinging() + { + Game1.GameManager.SetMusic(-1, 2); + _isSinging = false; + _isSingingWithSound = false; + _lastDirection = -1; + _noteEndTime = (int)(_noteCount / (_cycleTime * 0.5f) + 2) * (_cycleTime * 0.5f); + + Game1.GameManager.SaveManager.RemoveString("marin_sing_position"); + } + + private void KeyChanged() + { + if (!IsActive) + return; + + // start fading away? + var fadeValue = Game1.GameManager.SaveManager.GetString("maria_fade"); + if (!string.IsNullOrEmpty(fadeValue)) + { + _fadeTime = int.Parse(fadeValue); + _fadeCounter = _fadeTime; + Game1.GameManager.SaveManager.RemoveString("maria_fade"); + } + + // start moving? + var moveValue = Game1.GameManager.SaveManager.GetString("maria_walk"); + if (!string.IsNullOrEmpty(moveValue)) + { + var split = moveValue.Split(','); + + if (split.Length == 3) + { + var offsetX = int.Parse(split[0]); + var offsetY = int.Parse(split[1]); + _moveSpeed = float.Parse(split[2], CultureInfo.InvariantCulture); + _nextMoveStep.Enqueue(new MoveStep() { MoveSpeed = _moveSpeed, Offset = new Vector2(offsetX, offsetY), OffsetMode = true }); + } + if (split.Length == 4) + { + var positionX = int.Parse(split[0]); + var positionY = int.Parse(split[1]); + _moveSpeed = float.Parse(split[2], CultureInfo.InvariantCulture); + _nextMoveStep.Enqueue(new MoveStep() { MoveSpeed = _moveSpeed, Position = new Vector2(positionX, positionY) }); + } + + if (!_isMoving) + { + _isMoving = true; + DequeueMove(); + SetMovingString(true); + _body.CollisionTypes = Values.CollisionTypes.None; + } + + _isMoving = true; + _currentState = States.Idle; + Game1.GameManager.SaveManager.RemoveString("maria_walk"); + } + + // start singing? + var value = Game1.GameManager.SaveManager.GetString("maria_sing"); + if (value != null && value == "1") + { + StartSinging(); + Game1.GameManager.SetMusic(46, 2); + _currentState = States.Singing; + Game1.GameManager.SaveManager.RemoveString("maria_sing"); + } + + // start singing for the final scene? + var singFinal = Game1.GameManager.SaveManager.GetString("maria_sing_final", "0"); + if (singFinal == "1") + { + StartSinging(); + _currentState = States.SingingFinal; + Game1.GameManager.SaveManager.RemoveString("maria_sing_final"); + } + + var animalKey = Game1.GameManager.SaveManager.GetString("maria_sing_animals"); + if (animalKey != null && animalKey == "1") + { + StartSinging(); + Game1.GameManager.SetMusic(46, 2); + _currentState = States.AnimalSinging; + Game1.GameManager.SaveManager.RemoveString("maria_sing_animals"); + } + + var walrusKey = Game1.GameManager.SaveManager.GetString("maria_stop_singing"); + if (walrusKey != null && walrusKey == "1") + { + StopSinging(); + _currentState = States.Sequence; + Game1.GameManager.SaveManager.RemoveString("maria_stop_singing"); + } + + var animationKey = Game1.GameManager.SaveManager.GetString("maria_play_animation"); + if (!string.IsNullOrEmpty(animationKey)) + { + _animator.Play(animationKey); + _currentState = States.Sequence; + Game1.GameManager.SaveManager.RemoveString("maria_play_animation"); + } + + var stopSingingKey = Game1.GameManager.SaveManager.GetString("maria_sing_walrus"); + if (stopSingingKey != null && stopSingingKey == "1") + { + StartSinging(); + Game1.GameManager.SetMusic(46, 2); + _currentState = States.SingingWalrus; + Game1.GameManager.SaveManager.RemoveString("maria_sing_walrus"); + } + + var duoKey = Game1.GameManager.SaveManager.GetString("maria_start_duo"); + if (duoKey != null && duoKey == "1") + { + _duoIndex = 0; + _duoCounter = 0; + StartSinging(); + Game1.GameManager.SetMusic(73, 2); + _currentState = States.SingingDuo; + MapManager.ObjLink.FreezePlayer(); + Game1.GameManager.SaveManager.RemoveString("maria_start_duo"); + } + } + + private bool Interact() + { + if (_currentState != States.Idle && + _currentState != States.AnimalSinging && + _currentState != States.PostDuo) + return false; + + // stop singing + if (_currentState == States.AnimalSinging) + { + _isSinging = false; + _animator.Play("idle"); + Game1.GameManager.SetMusic(-1, 2); + } + + Game1.GameManager.StartDialogPath("maria"); + return true; + } + + private void Draw(SpriteBatch spriteBatch) + { + // draw maria + _bodyDrawComponent.Draw(spriteBatch); + + // draw the notes if maria is singing + var leftNotePosition = new Vector2(EntityPosition.X - 8 - _spriteNote.SourceRectangle.Width / 2f, EntityPosition.Y - 16 - _spriteNote.SourceRectangle.Height / 2f); + var leftNoteDirection = new Vector2(-0.4f, -1.0f); + DrawNote(spriteBatch, leftNotePosition, leftNoteDirection, 0); + + var rightNotePosition = new Vector2(EntityPosition.X + 8 - _spriteNote.SourceRectangle.Width / 2f, EntityPosition.Y - 16 - _spriteNote.SourceRectangle.Height / 2f); + var rightNoteDirection = new Vector2(0.4f, -1.0f); + DrawNote(spriteBatch, rightNotePosition, rightNoteDirection, _cycleTime / 2); + } + + private void DrawNote(SpriteBatch spriteBatch, Vector2 position, Vector2 direction, int timeOffset) + { + if (_noteCount < timeOffset || + !_isSinging && (int)((_noteCount - timeOffset) / _cycleTime + 1) * _cycleTime + timeOffset > _noteEndTime) + return; + + var time = (_noteCount + timeOffset) % _cycleTime; + position += direction * time * 0.02f + new Vector2(-direction.X, direction.Y) * (float)Math.Sin(time * 0.015) * 1.25f; + + var transparency = 1.0f; + if (time > _cycleTime - 100) + transparency = (_cycleTime - time) / 100f; + else if (time < 100) + transparency = time / 100; + + DrawHelper.DrawNormalized(spriteBatch, _spriteNote, position, Color.White * transparency); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjMermaid.cs b/InGame/GameObjects/NPCs/ObjMermaid.cs new file mode 100644 index 0000000..315040b --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjMermaid.cs @@ -0,0 +1,298 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjMermaid : GameObject + { + private readonly Animator _animator; + private readonly AiComponent _aiComponent; + private readonly BodyComponent _body; + private readonly CSprite _sprite; + private readonly BodyDrawComponent _drawComponent; + private readonly AnimationComponent _animationComponent; + private readonly BoxCollisionComponent _collisionComponent; + + private Vector2 _sitPosition; + private int _sitDirection; + + private Vector2 _spawnPosition; + + private int _jumpCounter = 4; + private bool _leave; + + public ObjMermaid() : base("mermaid") { } + + public ObjMermaid(Map.Map map, int posX, int posY, string spawnCondition) : base(map) + { + if (!string.IsNullOrEmpty(spawnCondition) && !SaveCondition.CheckCondition(spawnCondition)) + { + IsDead = true; + return; + } + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _spawnPosition = EntityPosition.Position; + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/npc_mermaid"); + _animator.Play("idle"); + + _sprite = new CSprite(EntityPosition); + _animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -7, -10, 14, 10, 8) + { + Gravity = -0.075f, + }; + + _aiComponent = new AiComponent(); + + var stateIdle = new AiState(UpdateIdle); + var stateDive = new AiState(UpdateLeave) { Init = InitLeave }; + var stateHidden = new AiState(); + stateHidden.Trigger.Add(new AiTriggerCountdown(1000, null, EndHidden)); + var stateJump = new AiState(UpdateJump) { Init = InitJump }; + var stateJumpHidden = new AiState(); + stateJumpHidden.Trigger.Add(new AiTriggerCountdown(1000, null, EndJumpHidden)); + + var stateSitHidden = new AiState(UpdateSitHidden) { Init = InitSitHidden }; + var stateSitJump = new AiState(UpdateSitJump) { Init = InitSitJump }; + var stateSit = new AiState(UpdateSit); + + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("dive", stateDive); + _aiComponent.States.Add("hidden", stateHidden); + _aiComponent.States.Add("jump", stateJump); + _aiComponent.States.Add("jumpHidden", stateJumpHidden); + + _aiComponent.States.Add("sitHidden", stateSitHidden); + _aiComponent.States.Add("sitJump", stateSitJump); + _aiComponent.States.Add("sit", stateSit); + + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + AddComponent(BodyComponent.Index, _body); + AddComponent(CollisionComponent.Index, _collisionComponent = new BoxCollisionComponent(_body.BodyBox, Values.CollisionTypes.Enemy)); + AddComponent(InteractComponent.Index, new InteractComponent(_body.BodyBox, Interact)); + AddComponent(BaseAnimationComponent.Index, _animationComponent); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(DrawComponent.Index, _drawComponent = new BodyDrawComponent(_body, _sprite, Values.LayerPlayer)); + //AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _sprite)); + + if (Game1.GameManager.SaveManager.GetString("mermaid_state", "0") == "0") + _aiComponent.ChangeState("idle"); + else + _aiComponent.ChangeState("sitHidden"); + } + + private void InitSitHidden() + { + _drawComponent.IsActive = false; + } + + private void UpdateSitHidden() + { + var playerDistance = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDistance.Length() < 64) + _aiComponent.ChangeState("sitJump"); + } + + private void InitSitJump() + { + _sitPosition = new Vector2(EntityPosition.X, EntityPosition.Y - 16); + _drawComponent.IsActive = true; + _body.Velocity.Z = 1.5f; + _body.Gravity = -0.05f; + + Game1.GameManager.PlaySoundEffect("D360-14-0E"); + + Splash(); + _animator.Play("stone_spawn"); + } + + private void UpdateSitJump() + { + // move upwards to the sitting position + var newPosition = Vector2.Lerp(EntityPosition.Position, _sitPosition, 0.075f * Game1.TimeMultiplier); + EntityPosition.Set(newPosition); + + if (_body.IsGrounded) + { + _sitDirection = MapManager.ObjLink.EntityPosition.X < EntityPosition.X ? -1 : 1; + _animator.Play("sit_" + _sitDirection); + + _aiComponent.ChangeState("sit"); + } + } + + private void UpdateSit() + { + var playerDistance = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (playerDistance.Length() < 64) + { + if (MapManager.ObjLink.EntityPosition.X < EntityPosition.X - _sitDirection * 4) + { + _sitDirection = -1; + _animator.Play("sit_" + _sitDirection); + } + if (MapManager.ObjLink.EntityPosition.X > EntityPosition.X - _sitDirection * 4) + { + _sitDirection = 1; + _animator.Play("sit_" + _sitDirection); + } + } + } + + private void InitJump() + { + _leave = true; + Splash(); + _drawComponent.IsActive = true; + _collisionComponent.IsActive = true; + + _body.IsGrounded = false; + _body.Velocity.Z = 1.25f; + + // find a target spot where there is water + var tries = 10; + var velocity = Vector2.Zero; + var dirRadiant = Game1.RandomNumber.Next(0, 100) / 100f * MathF.PI * 2; + + // we first try a random direction and then go clockwise around until we find a spot where there is deep water + while (tries > 0) + { + tries--; + velocity = new Vector2(MathF.Sin(dirRadiant), MathF.Cos(dirRadiant)); + + // is there water at the target position? + if ((Map.GetFieldState(EntityPosition.Position + new Vector2(-3, -6) + velocity * 14) & MapStates.FieldStates.DeepWater) != 0 && + (Map.GetFieldState(EntityPosition.Position + new Vector2(3, -6) + velocity * 14) & MapStates.FieldStates.DeepWater) != 0 && + (Map.GetFieldState(EntityPosition.Position + new Vector2(-3, 0) + velocity * 14) & MapStates.FieldStates.DeepWater) != 0 && + (Map.GetFieldState(EntityPosition.Position + new Vector2(3, 0) + velocity * 14) & MapStates.FieldStates.DeepWater) != 0) + break; + + dirRadiant += MathF.PI / 5; + } + _body.VelocityTarget = velocity * 0.45f; + + _animationComponent.MirroredH = velocity.X < 0; + _animator.Play("jump"); + _jumpCounter--; + + Game1.GameManager.PlaySoundEffect("D360-36-24"); + } + + private void UpdateJump() + { + if (_body.IsGrounded) + { + _body.VelocityTarget = Vector2.Zero; + _aiComponent.ChangeState("dive"); + } + } + + private void EndJumpHidden() + { + _aiComponent.ChangeState("jump"); + } + + private void UpdateIdle() + { + var playerDistance = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + var distance = playerDistance.Length(); + if (distance < 128) + { + if (MathF.Abs(playerDistance.X) > 8) + _animationComponent.MirroredH = playerDistance.X > 0; + } + if (distance < 18) + { + if (MapManager.ObjLink.IsDiving() && !Game1.GameManager.DialogIsRunning()) + { + Game1.GameManager.StartDialogPath("npc_mermaid_dive"); + } + } + } + + private void InitLeave() + { + _animator.Play("leave"); + + if (MapManager.ObjLink.IsDiving()) + MapManager.ObjLink.ShortenDive(); + } + + private void UpdateLeave() + { + if (!_animator.IsPlaying) + { + Splash(); + _drawComponent.IsActive = false; + _collisionComponent.IsActive = false; + + if (!_leave) + { + _aiComponent.ChangeState("hidden"); + + var posX = (_spawnPosition.X - EntityPosition.X) / 48; + var offsetX = ((posX + Game1.RandomNumber.Next(1, 3)) % 3) * 48; + EntityPosition.Set(new Vector2(_spawnPosition.X - offsetX, _spawnPosition.Y)); + } + else + { + if (0 < _jumpCounter) + _aiComponent.ChangeState("jumpHidden"); + else + Map.Objects.DeleteObjects.Add(this); + } + } + } + + private void EndHidden() + { + Splash(); + _animator.Play("idle"); + _drawComponent.IsActive = true; + _collisionComponent.IsActive = true; + _aiComponent.ChangeState("idle"); + } + + private void OnKeyChange() + { + var diveKey = Game1.GameManager.SaveManager.GetString("npc_mermaid_dive"); + if (!string.IsNullOrEmpty(diveKey) && diveKey == "1") + { + Game1.GameManager.SaveManager.RemoveString("npc_mermaid_dive"); + _aiComponent.ChangeState("dive"); + } + + var jumpKey = Game1.GameManager.SaveManager.GetString("npc_mermaid_leave"); + if (!string.IsNullOrEmpty(jumpKey) && jumpKey == "1") + { + Game1.GameManager.SaveManager.RemoveString("npc_mermaid_leave"); + _aiComponent.ChangeState("jump"); + } + } + + private bool Interact() + { + Game1.GameManager.StartDialogPath("npc_mermaid"); + return true; + } + + private void Splash() + { + var objSplash = new ObjAnimator(Map, (int)EntityPosition.X, (int)EntityPosition.Y, 0, 0, Values.LayerBottom, "Particles/fishingSplash", "idle", true); + Map.Objects.SpawnObject(objSplash); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjMonkey.cs b/InGame/GameObjects/NPCs/ObjMonkey.cs new file mode 100644 index 0000000..5ff6e71 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjMonkey.cs @@ -0,0 +1,431 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjMonkey : GameObject + { + private readonly Animator _animator; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiTriggerSwitch _hitCooldown; + private readonly CSprite _sprite; + private readonly AiTriggerSwitch _waitTimer; + private readonly BodyDrawComponent _drawComponent; + + private ObjBowWow _bowWow; + + private readonly Vector2 _resetPosition; + private readonly Vector2 _endPosition; + + // lives are used to fight with the bowwow + private const int MaxLives = 5; + private int _currentLives = MaxLives; + + private int _direction; + + private bool _initBusiness; + private const int FadeTime = 150; + + private int _directionChangeCounter = 0; + private float _damageCounter; + private const int DamageTime = 400; + + public ObjMonkey() : base("monkey") { } + + public ObjMonkey(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + // already build the bridge? + var value = Game1.GameManager.SaveManager.GetString("monkeyBusiness"); + if (value == "3") + { + IsDead = true; + return; + } + + _resetPosition = EntityPosition.Position; + + _body = new BodyComponent(EntityPosition, -6, -10, 12, 10, 8) + { + MoveCollision = OnCollision, + CollisionTypes = Values.CollisionTypes.Normal | + Values.CollisionTypes.NPCWall, + FieldRectangle = map.GetField(posX, posY), + MaxJumpHeight = 4f, + DragAir = 0.99f, + Drag = 0.85f, + Gravity = -0.15f + }; + + var randomDir = (Game1.RandomNumber.Next(0, 50) / 50.0f) * MathF.PI * 2; + _endPosition = new Vector2(EntityPosition.X + 8, EntityPosition.Y - 24) + + new Vector2(MathF.Sin(randomDir), MathF.Cos(randomDir)) * 150; + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/monkey"); + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-8, -16)); + + _hitCooldown = new AiTriggerSwitch(250); + _waitTimer = new AiTriggerSwitch(150); + + var stateWaiting = new AiState(UpdateWaiting); + var stateSitInit = new AiState(); + stateSitInit.Trigger.Add(new AiTriggerRandomTime(ToJump, 125, 1000)); + stateSitInit.Trigger.Add(_hitCooldown); + var stateSit = new AiState(UpdateSit); + stateSit.Trigger.Add(_hitCooldown); + stateSit.Trigger.Add(new AiTriggerRandomTime(ToJump, 750, 1500)); + var stateJump = new AiState(UpdateJump); + stateJump.Trigger.Add(_hitCooldown); + var stateFlee = new AiState(UpdateFlee) { Init = ToFlee }; + var stateFleeSit = new AiState(UpdateFleeSit); + stateFleeSit.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("flee"), 500, 1000)); + var stateReset = new AiState(UpdateReset); + var stateBanana = new AiState(UpdateBusiness); + stateBanana.Trigger.Add(new AiTriggerCountdown(1500, null, ToBusiness)); + var stateBusiness = new AiState(UpdateBusiness); + stateBusiness.Trigger.Add(new AiTriggerCountdown(250, null, ChangeDirection)); + var stateLeave = new AiState(UpdateLeave); + stateLeave.Trigger.Add(_waitTimer); + var stateFade = new AiState(); + stateFade.Trigger.Add(new AiTriggerCountdown(FadeTime, TickFade, () => TickFade(0))); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("waiting", stateWaiting); + _aiComponent.States.Add("sitInit", stateSitInit); + _aiComponent.States.Add("sit", stateSit); + _aiComponent.States.Add("jump", stateJump); + _aiComponent.States.Add("flee", stateFlee); + _aiComponent.States.Add("fleeSit", stateFleeSit); + _aiComponent.States.Add("reset", stateReset); + _aiComponent.States.Add("banana", stateBanana); + _aiComponent.States.Add("business", stateBusiness); + _aiComponent.States.Add("leave", stateLeave); + _aiComponent.States.Add("fade", stateFade); + + // start by locking into a random direction + _direction = Game1.RandomNumber.Next(0, 2); + _animator.Play("idle_" + _direction); + _aiComponent.ChangeState("waiting"); + + _drawComponent = new BodyDrawComponent(_body, _sprite, Values.LayerPlayer); + + AddComponent(InteractComponent.Index, new InteractComponent(_body.BodyBox, OnInteract)); + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, OnHit)); + AddComponent(CollisionComponent.Index, new BodyCollisionComponent(_body, Values.CollisionTypes.Normal | Values.CollisionTypes.PushIgnore)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _sprite)); + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + } + + private void KeyChanged() + { + var value = Game1.GameManager.SaveManager.GetString("monkeyBusiness"); + + if (!_initBusiness && value == "1") + { + _initBusiness = true; + ToBanana(); + } + else if (_aiComponent.CurrentStateId != "leave" && _aiComponent.CurrentStateId != "fade" && value == "3") + { + ToLeave(); + } + } + + private bool OnInteract() + { + Game1.GameManager.StartDialogPath("castle_monkey"); + + return true; + } + + private void UpdateWaiting() + { + var distance = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + + if (distance.Length() < 24) + { + // start fighting with the bowwow + var bowWowState = Game1.GameManager.SaveManager.GetString("bowWow"); + if (bowWowState == "2" || bowWowState == "3") + { + _aiComponent.ChangeState("sit"); + Game1.GameManager.StartDialogPath("castle_monkey"); + Tags = Values.GameObjectTag.Enemy; + + // search the bowwow + _bowWow = (ObjBowWow)Map.Objects.GetObjectOfType( + (int)EntityPosition.X - 80, (int)EntityPosition.Y - 40, 160, 160, typeof(ObjBowWow)); + } + } + } + + private void ToSit() + { + _aiComponent.ChangeState("sit"); + + // stop and wait + _body.Velocity = Vector3.Zero; + + _animator.Play("idle_" + _direction); + } + + private void UpdateSit() + { + DamageTick(); + } + + private void ToJump() + { + _aiComponent.ChangeState("jump"); + + Vector2 direction; + + // _bowWow should actually never be null... + if (_bowWow != null) + { + if (!_body.FieldRectangle.Contains(_bowWow.EntityPosition.Position)) + { + _aiComponent.ChangeState("sit"); + return; + } + + // jump towards the bowwow + direction = _bowWow.EntityPosition.Position - EntityPosition.Position; + if (direction != Vector2.Zero) + direction.Normalize(); + } + else + { + // change the direction + var rotation = Game1.RandomNumber.Next(0, 628) / 100f; + direction = new Vector2( + (float)Math.Sin(rotation), + (float)Math.Cos(rotation)) * Game1.RandomNumber.Next(25, 40) / 50f; + } + + _body.Velocity = new Vector3(direction.X * 1.5f, direction.Y * 1.5f, 1.75f); + + _direction = direction.X < 0 ? 0 : 1; + _animator.Play("jump_" + _direction); + } + + private void UpdateJump() + { + DamageTick(); + + // finished jumping + if (_body.IsGrounded) + ToSit(); + } + + private void ToFlee() + { + if (EntityPosition.Y < _resetPosition.Y - 90) + { + _aiComponent.ChangeState("reset"); + _animator.Play("idle_" + _direction); + Tags = Values.GameObjectTag.None; + return; + } + + _direction = EntityPosition.X < _resetPosition.X ? 1 : 0; + // jump up + _body.Velocity = new Vector3(_direction == 0 ? -0.5f : 0.5f, -1, 2.0f); + _animator.Play("jump_" + _direction); + + _body.CollisionTypes = Values.CollisionTypes.None; + } + + private void UpdateFlee() + { + DamageTick(); + } + + private void UpdateFleeSit() + { + _animator.Play("idle_u_" + _direction); + } + + private void UpdateReset() + { + var distance = MapManager.ObjLink.EntityPosition.Position - _resetPosition; + + // come back to the start position? + if (distance.Length() > 128) + { + _currentLives = MaxLives; + EntityPosition.Set(_resetPosition); + _aiComponent.ChangeState("waiting"); + + _damageCounter = 0; + _body.CollisionTypes = Values.CollisionTypes.Normal | + Values.CollisionTypes.NPCWall; + } + } + + private void ToBanana() + { + _animator.Play("jump_1"); + _aiComponent.ChangeState("banana"); + + Game1.GameManager.PlaySoundEffect("D360-01-01"); + } + + private void ToBusiness() + { + Game1.GameManager.StartDialogPath("castle_monkey_business"); + _aiComponent.ChangeState("business"); + _animator.Play("idle_1"); + _direction = 1; + } + + private void UpdateBusiness() + { + // freeze the player while the big business is happening + MapManager.ObjLink.FreezePlayer(); + + Game1.GameManager.InGameOverlay.DisableInventoryToggle = true; + } + + private void ChangeDirection() + { + if (_directionChangeCounter < 3) + { + _directionChangeCounter++; + _direction = (_direction + 1) % 2; + _animator.Play("idle_" + _direction); + } + + // done to reset the direction change trigger + _aiComponent.ChangeState("business"); + } + + private void ToLeave() + { + _body.CollisionTypes = Values.CollisionTypes.None; + _aiComponent.ChangeState("leave"); + } + + private void UpdateLeave() + { + if (!_body.IsGrounded || !_waitTimer.State) + return; + + var direction = _endPosition - EntityPosition.Position; + var distance = direction.Length(); + + direction.Normalize(); + var strength = Game1.RandomNumber.Next(150, 200) / 100.0f; + _body.Velocity = new Vector3(direction.X * strength, direction.Y * strength, 1.75f); + + _direction = direction.X < 0 ? 0 : 1; + _animator.Play("jump_" + _direction); + + // start fading away + if (distance < 48) + _aiComponent.ChangeState("fade"); + } + + private void TickFade(double time) + { + _sprite.Color = Color.White * (float)(time / FadeTime); + + // delete the monkey after it is faded away + if (time <= 0) + Map.Objects.DeleteObjects.Add(this); + } + + private void DamageTick() + { + if (_damageCounter > 0) + _damageCounter -= Game1.DeltaTime; + _sprite.SpriteShader = _damageCounter % 133 > 66 ? Resources.DamageSpriteShader0 : null; + } + + private void Draw(SpriteBatch spriteBatch) + { + _drawComponent.Draw(spriteBatch); + + if (_aiComponent.CurrentStateId != "banana") + return; + + // draw the banana + var sourceRectangle = Game1.GameManager.ItemManager["trade3"].SourceRectangle; + spriteBatch.Draw(Resources.SprItem, new Vector2(EntityPosition.X - 8, EntityPosition.Y - 30), sourceRectangle, Color.White); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (!_hitCooldown.State || damageType != HitType.BowWow) + return Values.HitCollision.None; + + Game1.GameManager.PlaySoundEffect("D360-03-03"); + + // fighting with the great bowwow? + _damageCounter = DamageTime; + + _currentLives--; + if (_currentLives <= 0) + _aiComponent.ChangeState("flee"); + + _hitCooldown.Reset(); + + _body.Velocity.X += direction.X * 4.0f; + _body.Velocity.Y += direction.Y * 4.0f; + + return Values.HitCollision.Blocking; + } + + private void OnCollision(Values.BodyCollision moveCollision) + { + // finished jumping? + if (_aiComponent.CurrentStateId == "leave" && moveCollision.HasFlag(Values.BodyCollision.Floor)) + { + _waitTimer.Reset(); + + if (_body.Velocity.Y > 0) + _animator.Play("idle_" + _direction); + else + _animator.Play("idle_u_" + _direction); + + _body.Velocity = Vector3.Zero; + } + + if (_aiComponent.CurrentStateId == "flee" && moveCollision.HasFlag(Values.BodyCollision.Floor)) + _aiComponent.ChangeState("fleeSit"); + + if (_aiComponent.CurrentStateId != "jump") + return; + + // repel after wall collision + if (moveCollision.HasFlag(Values.BodyCollision.Horizontal)) + _body.Velocity.X *= -0.25f; + else if (moveCollision.HasFlag(Values.BodyCollision.Vertical)) + _body.Velocity.Y *= -0.25f; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + _body.Velocity = new Vector3(direction * 1.25f, _body.Velocity.Z); + + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjMonkeyWorker.cs b/InGame/GameObjects/NPCs/ObjMonkeyWorker.cs new file mode 100644 index 0000000..7e87e54 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjMonkeyWorker.cs @@ -0,0 +1,178 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjMonkeyWorker : GameObject + { + private readonly Animator _animator; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly CSprite _sprite; + + private readonly CPosition _monkeyPosition; + + private readonly AiTriggerSwitch _waitTimer; + + private readonly Vector2 _workPosition; + private readonly Vector2 _endPosition; + + private const int FadeTime = 150; + + private int _direction; + + public ObjMonkeyWorker(Map.Map map, Vector2 startPosition, Vector2 workPosition, Vector2 endPosition) : base(map) + { + _monkeyPosition = new CPosition(startPosition.X + 8, startPosition.Y + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _workPosition = workPosition; + _endPosition = endPosition; + + _body = new BodyComponent(_monkeyPosition, -6, -8, 12, 8, 8) + { + MaxJumpHeight = 4f, + DragAir = 0.99f, + CollisionTypes = Values.CollisionTypes.None, + Drag = 0.85f, + Gravity = -0.15f, + MoveCollision = OnCollision + }; + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/monkey"); + _sprite = new CSprite(_monkeyPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-8, -16)); + + _waitTimer = new AiTriggerSwitch(150); + + var stateInit = new AiState(); + stateInit.Trigger.Add(new AiTriggerCountdown( + Game1.RandomNumber.Next(0, 1000), null, () => _aiComponent.ChangeState("come"))); + var stateCome = new AiState(UpdateCome); + stateCome.Trigger.Add(_waitTimer); + var stateWork = new AiState(UpdateWork); + stateWork.Trigger.Add(_waitTimer); + var stateLeave = new AiState(UpdateLeave); + stateLeave.Trigger.Add(_waitTimer); + var stateFade = new AiState(); + stateFade.Trigger.Add(new AiTriggerCountdown(FadeTime, TickFade, () => TickFade(0))); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("init", stateInit); + _aiComponent.States.Add("come", stateCome); + _aiComponent.States.Add("work", stateWork); + _aiComponent.States.Add("leave", stateLeave); + _aiComponent.States.Add("fade", stateFade); + + _aiComponent.ChangeState("init"); + + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _sprite)); + } + + private void OnCollision(Values.BodyCollision moveCollision) + { + // finished jumping? + if (moveCollision.HasFlag(Values.BodyCollision.Floor)) + { + _waitTimer.Reset(); + + if (_body.Velocity.Y > 0) + _animator.Play("idle_" + _direction); + else + _animator.Play("idle_u_" + _direction); + + _body.Velocity = Vector3.Zero; + } + } + + private void UpdateCome() + { + if (!_body.IsGrounded || !_waitTimer.State) + return; + + var direction = _workPosition - _monkeyPosition.Position; + var distance = direction.Length(); + + if (distance > 16) + { + direction.Normalize(); + var strength = Game1.RandomNumber.Next(150, 200) / 100.0f; + + if (distance < 64) + strength -= 0.5f; + + _body.Velocity = new Vector3(direction.X * strength, direction.Y * strength, 1.75f); + + _direction = direction.X < 0 ? 0 : 1; + _animator.Play("jump_" + _direction); + + Game1.GameManager.PlaySoundEffect("D360-36-24", false); + } + else + { + _aiComponent.ChangeState("work"); + } + } + + private void UpdateWork() + { + if (!_body.IsGrounded || !_waitTimer.State) + return; + + var direction = _workPosition - _monkeyPosition.Position; + + direction.Normalize(); + var strength = Game1.RandomNumber.Next(20, 40) / 100.0f; + _body.Velocity = new Vector3(direction.X * strength, direction.Y * strength, 1.25f); + + _direction = direction.X < 0 ? 0 : 1; + + _animator.Play("jump_" + _direction); + } + + public void ToLeave() + { + _aiComponent.ChangeState("leave"); + } + + private void UpdateLeave() + { + if (!_body.IsGrounded || !_waitTimer.State) + return; + + var direction = _endPosition - _monkeyPosition.Position; + var distance = direction.Length(); + + direction.Normalize(); + var strength = Game1.RandomNumber.Next(150, 200) / 100.0f; + _body.Velocity = new Vector3(direction.X * strength, direction.Y * strength, 1.75f); + + _direction = direction.X < 0 ? 0 : 1; + _animator.Play("jump_" + _direction); + + Game1.GameManager.PlaySoundEffect("D360-36-24", false); + + // start fading away + if (distance < 48) + _aiComponent.ChangeState("fade"); + } + + private void TickFade(double time) + { + _sprite.Color = Color.White * (float)(time / FadeTime); + + // delete the monkey after it is faded away + if (time <= 0) + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjMouse.cs b/InGame/GameObjects/NPCs/ObjMouse.cs new file mode 100644 index 0000000..644a603 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjMouse.cs @@ -0,0 +1,165 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjMouse : GameObject + { + private readonly Animator _animator; + private readonly BodyComponent _body; + private readonly AiComponent _aiComponent; + private readonly AiTriggerSwitch _changeDirectionSwitch; + private readonly AiTriggerSwitch _hitCooldown; + + private int _direction; + + public ObjMouse(Map.Map map, int posX, int posY) : base(map) + { + SprEditorImage = Resources.SprNpCs; + EditorIconSource = new Rectangle(63, 280, 15, 14); + + EntityPosition = new CPosition(posX + 8, posY + 8 + 4, 0); + EntitySize = new Rectangle(-9, -16, 18, 16); + + _body = new BodyComponent(EntityPosition, -5, -8, 10, 8, 8) + { + MoveCollision = OnCollision, + CollisionTypes = Values.CollisionTypes.Normal | + Values.CollisionTypes.Player | + Values.CollisionTypes.NPCWall, + FieldRectangle = map.GetField(posX, posY), + DragAir = 0.85f, + Drag = 0.85f, + Gravity = -0.15f + }; + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/mouse"); + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-9, -_animator.FrameHeight)); + + var stateIdle = new AiState(StateIdle); + stateIdle.Trigger.Add(_hitCooldown = new AiTriggerSwitch(250)); + var stateWalking = new AiState(StateWalking) { Init = InitWalk }; + stateWalking.Trigger.Add(new AiTriggerRandomTime(ToIdle, 750, 1500)); + stateWalking.Trigger.Add(_changeDirectionSwitch = new AiTriggerSwitch(250)); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("walking", stateWalking); + _aiComponent.ChangeState(Game1.RandomNumber.Next(0, 2) == 0 ? "idle" : "walking"); + + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(AnimationComponent.Index, animationComponent); + AddComponent(CollisionComponent.Index, new BodyCollisionComponent(_body, Values.CollisionTypes.Normal)); + AddComponent(PushableComponent.Index, new PushableComponent(_body.BodyBox, OnPush)); + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, OnHit)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + } + + private void ToIdle() + { + _aiComponent.ChangeState("idle"); + + // stop and wait + _body.VelocityTarget.X = 0; + _body.VelocityTarget.Y = 0; + + _animator.Play("stand_" + _direction); + } + + private void InitWalk() + { + // change the direction + var rotation = Game1.RandomNumber.Next(0, 628) / 100f; + _body.VelocityTarget = new Vector2( + (float)Math.Sin(rotation), + (float)Math.Cos(rotation)) * Game1.RandomNumber.Next(25, 40) / 50f; + _direction = _body.VelocityTarget.X < 0 ? 0 : 1; + + _animator.Play("walk_" + _direction); + } + + private void StateIdle() + { + if (!_animator.IsPlaying) + _aiComponent.ChangeState("walking"); + } + + private void StateWalking() + { + // jump while walking + if (_body.IsGrounded) + _body.Velocity.Z = 1f; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_aiComponent.CurrentStateId != "idle") + ToIdle(); + + if (!_hitCooldown.State) + return Values.HitCollision.None; + + _hitCooldown.Reset(); + + _body.Velocity.X += direction.X * 4.0f; + _body.Velocity.Y += direction.Y * 4.0f; + + return Values.HitCollision.Blocking; + } + + private void OnCollision(Values.BodyCollision moveCollision) + { + if (_aiComponent.CurrentStateId != "walking") + return; + + // rotate after wall collision + // top collision + if (moveCollision.HasFlag(Values.BodyCollision.Horizontal)) + { + if (!_changeDirectionSwitch.State) + return; + _changeDirectionSwitch.Reset(); + + _body.VelocityTarget.X *= -0.5f; + _direction = (_direction + 1) % 2; + _animator.Play("walk_" + _direction); + } + // vertical collision + else if (moveCollision.HasFlag(Values.BodyCollision.Vertical)) + { + _body.VelocityTarget.Y *= -0.5f; + } + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + // push the bird away + _body.Velocity = new Vector3(direction.X, direction.Y, 0) * 1.0f; + + if (_aiComponent.CurrentStateId == "walking") + return true; + + _aiComponent.ChangeState("walking"); + + var offsetAngle = MathHelper.ToRadians(Game1.RandomNumber.Next(45, 85) * (_direction * 2 - 1)); + var newDirection = new Vector2( + direction.X * (float)Math.Cos(offsetAngle) - direction.Y * (float)Math.Sin(offsetAngle), + direction.X * (float)Math.Sin(offsetAngle) + direction.Y * (float)Math.Cos(offsetAngle)) * 0.5f; + _body.VelocityTarget = newDirection; + + _direction = _body.VelocityTarget.X < 0 ? 0 : 1; + _animator.Play("walk_" + _direction); + + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjOwl.cs b/InGame/GameObjects/NPCs/ObjOwl.cs new file mode 100644 index 0000000..bb4c8f9 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjOwl.cs @@ -0,0 +1,360 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjOwl : GameObject + { + private readonly CSprite _sprite; + private readonly BodyDrawComponent _drawComponent; + private readonly BodyDrawShadowComponent _drawShadowComponent; + private readonly AiComponent _aiComponent; + + private Animator _animator; + private float _landingSpeed = 0.125f; + + private CPosition _owlPosition; + + // https://cubic-bezier.com/#.17,.67,.83,.67 + private readonly CubicBezier _landingCurve = new CubicBezier(100, new Vector2(0.35f, 1f), new Vector2(0.8f, 1)); + private readonly CubicBezier _leavingCurve = new CubicBezier(100, new Vector2(0.25f, 0.04f), new Vector2(0.35f, 0.11f)); + + private Vector3 _startPosition; + private Vector3 _landPosition; + private Vector3 _leavePosition; + + private readonly string _strKey; + private readonly string _keyCondition; + + private float _airCount; + private float _flySoundCount; + private int _enterTime = 2000; + + private int originX; + private int originY; + + private bool _isAlive; + private bool _wasTriggered; + private bool _triggerCollided; + + private bool _hoverMode; + private double _hoverCounter; + + private bool _sitMode; + private int _mode; // 0: leave after talking; 1: stay after talking; 2: spawn from the top + + public ObjOwl() : base("owl") { } + + public ObjOwl(Map.Map map, int posX, int posY, string keyCondition, Rectangle triggerRectangle, bool hoveMode, string strKey, int mode) : base(map) + { + _strKey = strKey; + _keyCondition = keyCondition; + _hoverMode = hoveMode; + _mode = mode; + + // always gets updated + //EntityPosition = new CPosition(posX, posY, 0); + //EntitySize = new Rectangle(-16, -32, 48, 64); + + originX = posX + 8; + originY = posY + 16; + + _owlPosition = new CPosition(_startPosition.X, _startPosition.Y, _startPosition.Z); + + var body = new BodyComponent(_owlPosition, -6, -8, 12, 8, 8) + { + IgnoresZ = true + }; + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/owl"); + _sprite = new CSprite(_owlPosition); + + var animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + //var stateDebug = new AiState(); + var stateWait = new AiState(UpdateWait); + var stateEnter = new AiState(UpdateEnter) { Init = InitEnter }; + var stateTalk = new AiState(UpdateTalk) { Init = InitTalking }; + var stateTalked = new AiState() { Init = InitTalked }; + var stateLeave = new AiState(UpdateLeave) { Init = InitLeave }; + var stateSit = new AiState(UpdateSit) { }; + + _aiComponent = new AiComponent(); + //_aiComponent.States.Add("debug", stateDebug); + _aiComponent.States.Add("wait", stateWait); + _aiComponent.States.Add("enter", stateEnter); + _aiComponent.States.Add("talk", stateTalk); + _aiComponent.States.Add("talked", stateTalked); + _aiComponent.States.Add("leave", stateLeave); + _aiComponent.States.Add("sit", stateSit); + _aiComponent.ChangeState("wait"); + + AddComponent(BodyComponent.Index, body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, _drawComponent = new BodyDrawComponent(body, _sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, _drawShadowComponent = new BodyDrawShadowComponent(body, _sprite) { OffsetY = 0 }); + var enterRectangle = new Rectangle(posX + 8 + triggerRectangle.X, posY + 8 + triggerRectangle.Y, triggerRectangle.Width, triggerRectangle.Height); + AddComponent(ObjectCollisionComponent.Index, new ObjectCollisionComponent(enterRectangle, OnCollision)); + + _sprite.Color = Color.Transparent; + _drawComponent.IsActive = false; + _drawShadowComponent.IsActive = false; + + // sitting infront of the egg + if (mode == 2) + { + if (Game1.GameManager.SaveManager.GetString(_keyCondition, "0") == "1") + { + IsDead = true; + return; + } + + _isAlive = true; + _sitMode = true; + } + else + { + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + + // add key change listener to activate/deactivate the owl + if (!string.IsNullOrEmpty(_keyCondition)) + KeyChanged(); + } + } + + private void KeyChanged() + { + var value = Game1.GameManager.SaveManager.GetString(_strKey, "0"); + _isAlive = value == _keyCondition; + } + + private void OnCollision(GameObject gameObject) + { + if (!_wasTriggered && _isAlive) + _triggerCollided = true; + } + + private void UpdateSit() + { + var playerDirection = MapManager.ObjLink.EntityPosition.Position - _owlPosition.Position; + if (playerDirection.Length() < 64 && MapManager.ObjLink.IsGrounded()) + { + // start playing owl music + Game1.GameManager.SetMusic(33, 2); + + _leavePosition = new Vector3(originX, originY - 90, 90); + _aiComponent.ChangeState("talk"); + } + } + + private void UpdateWait() + { + if (_triggerCollided && !MapManager.ObjLink.IsRailJumping() && !MapManager.ObjLink.IsTransitioning) + _aiComponent.ChangeState("enter"); + } + + private void InitEnter() + { + if (_wasTriggered) + return; + + if (_hoverMode) + { + _animator.Play("hover"); + + _startPosition = new Vector3(originX, originY - 64, 64); + _landPosition = new Vector3(originX, originY, 0); + _leavePosition = new Vector3(originX, originY - 64, 64); + } + else if (_mode == 2) + { + _animator.Play("fly"); + + _startPosition = new Vector3(originX, originY - 64, 64); + _landPosition = new Vector3(originX, originY, 0); + _leavePosition = new Vector3(originX, originY - 64, 64); + } + else + { + _animator.Play("fly"); + + _startPosition = new Vector3(originX - 64, originY - 64, 64); + _landPosition = new Vector3(originX, originY, 0); + _leavePosition = new Vector3(originX + 64, originY - 64, 64); + } + + _airCount = 0; + _flySoundCount = 0; + + // start playing owl music; not in the final scene + if (Game1.GameManager.GetCurrentMusic() != 88) + Game1.GameManager.SetMusic(33, 2); + + MapManager.ObjLink.FreezePlayer(); + _wasTriggered = true; + + _drawComponent.IsActive = true; + + if (!_hoverMode) + _drawShadowComponent.IsActive = true; + } + + private void UpdateEnter() + { + MapManager.ObjLink.FreezePlayer(); + + _airCount += Game1.DeltaTime; + + _flySoundCount -= Game1.DeltaTime; + if (_flySoundCount < 0) + { + _flySoundCount = 500; + Game1.GameManager.PlaySoundEffect("D378-45-2D", false); + } + + if (_airCount > _enterTime) + _airCount = _enterTime; + + var time = _airCount / _enterTime; + if (_airCount < _enterTime) + { + var currentPosition = Vector3.Lerp(_startPosition, _landPosition, _landingCurve.EvaluateX(time)); + _owlPosition.Set(currentPosition); + + if (!_hoverMode && time > 0.9) + _animator.Play("idle"); + } + else + { + if (!_hoverMode) + _animator.Play("idle"); + + _owlPosition.Set(_landPosition); + + _aiComponent.ChangeState("talk"); + } + + // player looks at the owl + if (_airCount > _enterTime - 1000) + { + var playerDir = _owlPosition.Position - MapManager.ObjLink.EntityPosition.Position; + MapManager.ObjLink.Direction = AnimationHelper.GetDirection(playerDir); + } + + // fade in + if (time <= 0.1f) + _sprite.Color = Color.White * (time / 0.1f); + else + _sprite.Color = Color.White; + } + + private void InitTalking() + { + _hoverCounter = 0; + + if (_sitMode) + Game1.GameManager.StartDialogPath(_keyCondition); + else + Game1.GameManager.StartDialogPath(_strKey); + + Game1.GameManager.InGameOverlay.TextboxOverlay.OwlMode = true; + } + + private void UpdateTalk() + { + MapManager.ObjLink.FreezePlayer(); + + // hover up/down + if (_hoverMode) + { + _hoverCounter += Game1.DeltaTime; + + var hoverPosition = _landPosition; + hoverPosition.Y -= MathF.Sin((GetHoverState((float)_hoverCounter / 1000f, 0.0f) - 0.0f) * MathF.PI * 2 - MathF.PI / 2) * 3 + 3; + _owlPosition.Set(hoverPosition); + } + + // leave of just sit there + if (!Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen) + _aiComponent.ChangeState((_mode == 0 || _mode == 2) ? "leave" : "talked"); + } + + private float GetHoverState(float _hoverCounter, float startPercentage) + { + // gradient up to 0.5f + var gradient = 0.9f; + // time needed to reach 0.5f + var timeX = 0.5f * gradient; + + _hoverCounter += startPercentage * gradient; + _hoverCounter %= 1; + + if (_hoverCounter < timeX) + return _hoverCounter / gradient; + else + return timeX / gradient + (1 - timeX / gradient) * (_hoverCounter - timeX) / (1 - timeX); + } + + private void InitLeave() + { + _airCount = 0; + _landPosition.X = _owlPosition.X; + _landPosition.Y = _owlPosition.Y; + + if (!_hoverMode) + { + _animator.Play("fly"); + _animator.SpeedMultiplier = 1.5f; + } + + // stop playing music + Game1.GameManager.SetMusic(-1, 2); + } + + private void UpdateLeave() + { + _flySoundCount -= Game1.DeltaTime; + if (_flySoundCount < 0) + { + _flySoundCount = 175; + Game1.GameManager.PlaySoundEffect("D378-05-05"); + } + + _airCount += Game1.DeltaTime; + + if (_airCount > _enterTime) + _airCount = _enterTime; + + var time = _airCount / (float)_enterTime; + if (_airCount < _enterTime) + { + var currentPosition = Vector3.Lerp(_landPosition, _leavePosition, _leavingCurve.EvaluateX(time)); + _owlPosition.Set(currentPosition); + } + else + { + Map.Objects.DeleteObjects.Add(this); + } + + // fade out + if (time >= 0.9f) + _sprite.Color = Color.White * ((1 - time) / 0.1f); + else + _sprite.Color = Color.White; + } + + private void InitTalked() + { + // stop playing music + Game1.GameManager.SetMusic(-1, 2); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjPainter.cs b/InGame/GameObjects/NPCs/ObjPainter.cs new file mode 100644 index 0000000..e0dd202 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjPainter.cs @@ -0,0 +1,56 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + class ObjPainter : GameObject + { + private readonly Animator _animator; + + public ObjPainter() : base("painter") { } + + public ObjPainter(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-12, -24, 24, 24); + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/npc_painter"); + _animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, Vector2.Zero); + + var body = new BodyComponent(EntityPosition, -9, -13, 18, 12, 8); + + AddComponent(BodyComponent.Index, body); + AddComponent(CollisionComponent.Index, new BodyCollisionComponent(body, Values.CollisionTypes.Normal)); + AddComponent(InteractComponent.Index, new InteractComponent(new CBox(EntityPosition, -9, -5, 18, 5, 8), Interact)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(body, sprite)); + } + + private void Update() + { + if (!Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen) + _animator.Play("idle"); + } + + private bool Interact() + { + if (EntityPosition.X < MapManager.ObjLink.EntityPosition.X) + _animator.Play("talk_1"); + else + _animator.Play("talk_-1"); + + Game1.GameManager.StartDialogPath("npc_painter"); + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjPerson.cs b/InGame/GameObjects/NPCs/ObjPerson.cs new file mode 100644 index 0000000..f90637f --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjPerson.cs @@ -0,0 +1,168 @@ +using System.Globalization; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + // @TODO: should probably be replaced with ObjPersonNew in most places + internal class ObjPerson : GameObject + { + public BodyComponent Body; + public readonly Animator Animator; + + private readonly string _personId; + private string _currentAnimation; + private int _lastDirection = -1; + private bool _directionMode = true; + + private bool _isMoving; + private float _movementSpeed; + private float _movementCounter; + private Vector2 _startPosition; + private Vector2 _endPosition; + + public ObjPerson() : base("person") { } + + public ObjPerson(Map.Map map, int posX, int posY, string personId, Rectangle bodyRectangle, Vector2 offset, string animationName) : base(map) + { + if (string.IsNullOrEmpty(personId)) + { + IsDead = true; + return; + } + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-bodyRectangle.Width / 2, -bodyRectangle.Height, bodyRectangle.Width, bodyRectangle.Height); + + _personId = personId; + Animator = AnimatorSaveLoad.LoadAnimator("NPCs/" + _personId); + + if (Animator == null) + { + IsDead = true; + return; + } + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(Animator, sprite, new Vector2( + -Animator.CurrentAnimation.AnimationWidth / 2f + offset.X, + -Animator.CurrentAnimation.AnimationHeight + offset.Y)); + + Body = new BodyComponent(EntityPosition, + -bodyRectangle.Width / 2, -bodyRectangle.Height, bodyRectangle.Width, bodyRectangle.Height, bodyRectangle.Height) + { + Gravity = -0.15f + }; + + if (!string.IsNullOrEmpty(animationName)) + { + _directionMode = false; + Animator.Play(animationName); + } + + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + AddComponent(BodyComponent.Index, Body); + AddComponent(CollisionComponent.Index, new BodyCollisionComponent(Body, Values.CollisionTypes.Normal | Values.CollisionTypes.PushIgnore)); + AddComponent(InteractComponent.Index, new InteractComponent(Body.BodyBox, Interact)); + AddComponent(AnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(Body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + } + + private void Update() + { + if (_isMoving) + { + _movementCounter += Game1.DeltaTime * _movementSpeed; + + // finished moving? + if (_movementCounter >= 1000) + { + EntityPosition.Set(_endPosition); + _isMoving = false; + } + else + { + var newPosition = Vector2.Lerp(_startPosition, _endPosition, _movementCounter / 1000); + EntityPosition.Set(newPosition); + } + } + + if (_directionMode) + { + var playerDistance = new Vector2( + MapManager.ObjLink.EntityPosition.X - (EntityPosition.X), + MapManager.ObjLink.EntityPosition.Y - (EntityPosition.Y - 4)); + + var dir = 3; + + // rotate in the direction of the player + if (playerDistance.Length() < 32) + dir = AnimationHelper.GetDirection(playerDistance); + + if (_lastDirection != dir) + { + // look at the player + Animator.Play("stand_" + dir); + _lastDirection = dir; + } + } + + // finished playing + if (_currentAnimation != null && !Animator.IsPlaying) + { + _currentAnimation = null; + Game1.GameManager.SaveManager.SetString(_personId + "Finished", "1"); + } + } + + private bool Interact() + { + Game1.GameManager.StartDialogPath(_personId); + return true; + } + + private void KeyChanged() + { + // start new animation? + var animationString = _personId + "Animation"; + var animationValues = Game1.GameManager.SaveManager.GetString(animationString); + if (animationValues != null) + { + _currentAnimation = animationValues.ToLower(); + Animator.Play(_currentAnimation); + Game1.GameManager.SaveManager.RemoveString(animationString); + } + + // start moving? + var moveString = _personId + "Move"; + var moveValue = Game1.GameManager.SaveManager.GetString(moveString); + if (moveValue != null) + { + // offsetX, offsetY, movementSpeed + var split = moveValue.Split(','); + if (split.Length == 3) + { + var offsetX = int.Parse(split[0]); + var offsetY = int.Parse(split[1]); + var speed = float.Parse(split[2], CultureInfo.InvariantCulture); + + _startPosition = EntityPosition.Position; + _endPosition = _startPosition + new Vector2(offsetX, offsetY); + _movementSpeed = speed; + + _isMoving = true; + _movementCounter = 0; + } + + Game1.GameManager.SaveManager.RemoveString(moveString); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjPersonNew.cs b/InGame/GameObjects/NPCs/ObjPersonNew.cs new file mode 100644 index 0000000..124ab76 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjPersonNew.cs @@ -0,0 +1,380 @@ +using System.Collections.Generic; +using System.Globalization; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjPersonNew : GameObject + { + struct MoveStep + { + public float MoveSpeed; + public Vector2 Offset; + } + private Queue _nextMoveStep = new Queue(); + + public BodyComponent Body; + public readonly Animator Animator; + private readonly CSprite _sprite; + private readonly BodyDrawComponent _drawComponent; + private readonly BodyDrawShadowComponent _shadowComponent; + private readonly BodyCollisionComponent _collisionComponent; + private readonly InteractComponent _interactionComponent; + + private readonly string _dialogId; + private string _currentAnimation; + private string _spawnCondition; + private float _lookCounter; + private int _lookRange = 32; + private bool _directionMode = true; + + private bool _isMoving; + private Vector2 _targetPosition; + private float _moveSpeed; + + private float _fadeTime; + private float _fadeCounter; + + private float _jumpTime; + private float _jumpCounter; + + public ObjPersonNew() : base("person") { } + + public ObjPersonNew(Map.Map map, int posX, int posY, string spawnCondition, string animationId, string dialogId, string animationName, Rectangle bodyRectangle) : base(map) + { + if (string.IsNullOrEmpty(animationId)) + { + IsDead = true; + return; + } + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(bodyRectangle.X - bodyRectangle.Width / 2, bodyRectangle.Y - bodyRectangle.Height, bodyRectangle.Width, bodyRectangle.Height); + + _spawnCondition = spawnCondition; + _dialogId = dialogId; + Animator = AnimatorSaveLoad.LoadAnimator("NPCs/" + animationId); + + if (Animator == null) + { + IsDead = true; + return; + } + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(Animator, _sprite, Vector2.Zero); + + Body = new BodyComponent(EntityPosition, + bodyRectangle.X - bodyRectangle.Width / 2, bodyRectangle.Y - bodyRectangle.Height, bodyRectangle.Width, bodyRectangle.Height, bodyRectangle.Height) + { + Gravity = -0.15f, + }; + + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + AddComponent(BodyComponent.Index, Body); + // only the player should collide with the npc + AddComponent(CollisionComponent.Index, _collisionComponent = new BodyCollisionComponent(Body, Values.CollisionTypes.Enemy | Values.CollisionTypes.PushIgnore)); + if (!string.IsNullOrEmpty(_dialogId)) + AddComponent(InteractComponent.Index, _interactionComponent = new InteractComponent(Body.BodyBox, Interact)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, _drawComponent = new BodyDrawComponent(Body, _sprite, Values.LayerPlayer) { WaterOutline = false }); + AddComponent(DrawShadowComponent.Index, _shadowComponent = new BodyDrawShadowComponent(Body, _sprite)); + + if (animationName == "pHidden") + { + SetVisibility(false); + } + else if (!string.IsNullOrEmpty(animationName)) + { + _directionMode = false; + Animator.Play(animationName); + } + else + { + Animator.Play("stand_3"); + } + + if (!string.IsNullOrEmpty(_spawnCondition)) + { + var spawnValue = Game1.GameManager.SaveManager.GetString(_spawnCondition); + if (spawnValue != "1") + SetActive(false); + } + } + + private void SetActive(bool isActive) + { + _collisionComponent.IsActive = isActive; + _interactionComponent.IsActive = isActive; + _drawComponent.IsActive = isActive; + _shadowComponent.IsActive = isActive; + } + + private void Update() + { + UpdateMoving(); + + UpdateFade(); + + JumpMode(); + + _lookCounter -= Game1.DeltaTime; + if (!_isMoving && _directionMode && _lookCounter < 0) + { + _lookCounter += 750; + UpdateLookAnimation(); + } + + // finished playing + if (_currentAnimation != null && !Animator.IsPlaying) + { + _currentAnimation = null; + Game1.GameManager.SaveManager.SetString(_dialogId + "Finished", "1"); + } + } + + private void UpdateLookAnimation() + { + var playerDistance = new Vector2( + MapManager.ObjLink.EntityPosition.X - (EntityPosition.X), + MapManager.ObjLink.EntityPosition.Y - (EntityPosition.Y - 4)); + + var dir = 3; + + // rotate in the direction of the player + if (playerDistance.Length() < _lookRange) + dir = AnimationHelper.GetDirection(playerDistance); + + // look at the player + if (_currentAnimation == null) + { + var animationIndex = Animator.GetAnimationIndex("stand_" + dir); + if (animationIndex >= 0) + Animator.Play(animationIndex); + else + Animator.Play("stand_" + (playerDistance.Y < 0 ? "1" : "3")); + } + } + + private void UpdateMoving() + { + if (!_isMoving) + return; + + // move towards the target position + var targetDistance = _targetPosition - EntityPosition.Position; + if (targetDistance.Length() > _moveSpeed * Game1.TimeMultiplier) + { + targetDistance.Normalize(); + Body.VelocityTarget = targetDistance * _moveSpeed; + + if (_currentAnimation == null) + { + var dir = AnimationHelper.GetDirection(targetDistance); + Animator.Play("walk_" + dir); + } + } + // finished walking + else + { + _lookCounter = 0; + Body.VelocityTarget = Vector2.Zero; + EntityPosition.Set(_targetPosition); + + if (_nextMoveStep.Count > 0) + DequeueMove(); + else + { + _isMoving = false; + SetMovingString(false); + } + } + } + + private void DequeueMove() + { + var move = _nextMoveStep.Dequeue(); + _moveSpeed = move.MoveSpeed; + _targetPosition = EntityPosition.Position + move.Offset; + } + + private void UpdateFade() + { + if (_fadeTime < 0) + { + _fadeCounter += Game1.DeltaTime; + if (_fadeCounter >= -_fadeTime) + _fadeCounter = -_fadeTime; + + var percentage = _fadeCounter / -_fadeTime; + _sprite.Color = Color.White * percentage; + _shadowComponent.Transparency = percentage; + + if (_fadeCounter >= -_fadeTime) + _fadeTime = 0; + } + else if (_fadeTime > 0) + { + _fadeCounter -= Game1.DeltaTime; + + if (_fadeCounter <= 0) + Map.Objects.DeleteObjects.Add(this); + else + { + var percentage = _fadeCounter / _fadeTime; + _sprite.Color = Color.White * percentage; + _shadowComponent.Transparency = percentage; + } + } + } + + private void JumpMode() + { + if (_jumpTime <= 0) + return; + + _jumpCounter -= Game1.DeltaTime; + if (_jumpCounter < 0) + { + _jumpCounter += _jumpTime; + Body.Velocity.Z = 1.125f; + } + } + + public void DisableRotating() + { + _directionMode = false; + } + + private bool Interact() + { + if (!_isMoving && _directionMode) + UpdateLookAnimation(); + + Game1.GameManager.StartDialogPath(_dialogId); + + return true; + } + + private void SetVisibility(bool visible) + { + _sprite.IsVisible = visible; + _shadowComponent.IsActive = visible; + } + + private void OnKeyChange() + { + if (!string.IsNullOrEmpty(_spawnCondition)) + { + var spawnValue = Game1.GameManager.SaveManager.GetString(_spawnCondition); + if (spawnValue == "1") + SetActive(true); + } + + // start new animation? + var animationString = _dialogId + "Animation"; + var animationValues = Game1.GameManager.SaveManager.GetString(animationString); + if (animationValues != null) + { + if (animationValues == "-") + { + _currentAnimation = null; + } + else if (animationValues != "") + { + SetVisibility(true); + _currentAnimation = animationValues; + Animator.Play(_currentAnimation); + } + else + { + SetVisibility(false); + _currentAnimation = null; + } + + Game1.GameManager.SaveManager.RemoveString(animationString); + } + + // start moving? + var moveString = _dialogId + "Move"; + var moveValue = Game1.GameManager.SaveManager.GetString(moveString); + if (moveValue != null) + { + // offsetX; offsetY; movementSpeed + var split = moveValue.Split(','); + if (split.Length == 3) + { + var offsetX = int.Parse(split[0]); + var offsetY = int.Parse(split[1]); + var moveSpeed = float.Parse(split[2], CultureInfo.InvariantCulture); + + _nextMoveStep.Enqueue(new MoveStep() { MoveSpeed = moveSpeed, Offset = new Vector2(offsetX, offsetY) }); + + if (!_isMoving) + { + _isMoving = true; + DequeueMove(); + SetMovingString(true); + Body.CollisionTypes = Values.CollisionTypes.None; + } + } + + Game1.GameManager.SaveManager.RemoveString(moveString); + } + + // start jumping? + var jumpString = _dialogId + "Jump"; + var jumpValue = Game1.GameManager.SaveManager.GetString(jumpString); + if (!string.IsNullOrEmpty(jumpValue)) + { + var split = jumpValue.Split(','); + if (split.Length == 1) + { + _jumpTime = int.Parse(jumpValue); + } + else + { + // jump one time + Body.Velocity.Z = float.Parse(split[0], CultureInfo.InvariantCulture); + Body.Gravity = float.Parse(split[1], CultureInfo.InvariantCulture); + } + Game1.GameManager.SaveManager.RemoveString(jumpString); + } + + // change look range? + var rangeString = _dialogId + "Range"; + var rangeValue = Game1.GameManager.SaveManager.GetString(rangeString); + if (!string.IsNullOrEmpty(rangeValue)) + { + _lookRange = int.Parse(rangeValue); + Game1.GameManager.SaveManager.RemoveString(rangeString); + } + + // start fading away? + var fadeString = _dialogId + "Fade"; + var fadeValue = Game1.GameManager.SaveManager.GetString(fadeString); + if (!string.IsNullOrEmpty(fadeValue)) + { + // negative value -> fade in + // positive value -> fade out + _fadeTime = int.Parse(fadeValue); + _fadeCounter = _fadeTime; + UpdateFade(); + + Game1.GameManager.SaveManager.RemoveString(fadeString); + } + } + + private void SetMovingString(bool state) + { + Game1.GameManager.SaveManager.SetString(_dialogId + "Moving", state ? "1" : "0"); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjPhotoMouse.cs b/InGame/GameObjects/NPCs/ObjPhotoMouse.cs new file mode 100644 index 0000000..01fc13e --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjPhotoMouse.cs @@ -0,0 +1,361 @@ +using System.Collections.Generic; +using System.Globalization; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjPhotoMouse : GameObject + { + struct MoveStep + { + public float MoveSpeed; + public Vector2 Offset; + } + private Queue _nextMoveStep = new Queue(); + + public readonly BodyComponent Body; + private readonly Animator _animator; + private readonly CSprite _sprite; + private readonly BodyDrawShadowComponent _shadowComponent; + private readonly InteractComponent _interactComponent; + private readonly BodyCollisionComponent _collisionComponent; + + private readonly string _spawnCondition; + private readonly string _dialogId; + private string _currentAnimation; + + private static int SwimTime = 2000; + private Vector2 _spawnPosition; + private double _swimCounter; + private int _swimDirection = -1; + private bool _swimMode; + private bool _isPulled; + + private bool _isMoving; + private Vector2 _targetPosition; + private float _moveSpeed; + + private float _fadeTime; + private float _fadeCounter; + + private bool _photoMode; + private bool _blockedExit; + private bool _movingToPlayer; + private bool _isActive = true; + + public ObjPhotoMouse() : base("photo_mouse") { } + + public ObjPhotoMouse(Map.Map map, int posX, int posY, string spawnCondition, string dialogId) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 15, 0); + EntitySize = new Rectangle(-8, -15, 16, 16); + + _spawnCondition = spawnCondition; + _dialogId = dialogId; + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/photo_mouse"); + _animator.Play("stand_0"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(0, 1)); + + Body = new BodyComponent(EntityPosition, -7, -12, 14, 12, 8); + + if (map.Is2dMap) + { + Body.IgnoresZ = true; + _spawnPosition = EntityPosition.Position; + _swimMode = true; + _animator.Play("swim_" + _swimDirection); + Body.OffsetX = -5; + Body.Width = 10; + Body.DragAir = 0.95f; + } + + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + AddComponent(BodyComponent.Index, Body); + // only the player should collide with the npc + AddComponent(CollisionComponent.Index, _collisionComponent = new BodyCollisionComponent(Body, Values.CollisionTypes.Enemy | Values.CollisionTypes.PushIgnore)); + AddComponent(InteractComponent.Index, _interactComponent = new InteractComponent(new CBox(EntityPosition, -7, -6 - 1, 2, 2, 8), Interact)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(Body, _sprite, Values.LayerPlayer) { WaterOutline = false }); + AddComponent(DrawShadowComponent.Index, _shadowComponent = new BodyDrawShadowComponent(Body, _sprite)); + + if (!string.IsNullOrEmpty(spawnCondition)) + SetActive(false); + } + + private void SetActive(bool active) + { + _isActive = active; + _collisionComponent.IsActive = active; + _sprite.IsVisible = active; + _shadowComponent.IsActive = active; + } + + private void Update() + { + UpdateMoving(); + + UpdateFade(); + + UpdateSwimming(); + + // finished playing + if (_currentAnimation != null && !_animator.IsPlaying) + { + _currentAnimation = null; + Game1.GameManager.SaveManager.SetString(_dialogId + "Finished", "1"); + } + + if (!_movingToPlayer && _photoMode && MapManager.ObjLink.Direction == 3) + { + // check if the player is standing on the correct position + var positioned = Game1.GameManager.SaveManager.GetString("photo_house_positioned"); + if (!string.IsNullOrEmpty(positioned) && positioned == "1") + { + _movingToPlayer = true; + + // move to the player + _nextMoveStep.Enqueue(new MoveStep() { MoveSpeed = 1, Offset = new Vector2(80 - EntityPosition.X, 0) }); + _nextMoveStep.Enqueue(new MoveStep() { MoveSpeed = 1, Offset = new Vector2(0, 54 - EntityPosition.Y) }); + + StartMoving(); + + Game1.GameManager.StartDialogPath("photo_mouse_photo_0"); + } + } + } + + private void UpdateSwimming() + { + if (!_swimMode || _isPulled) + return; + + _swimCounter -= Game1.DeltaTime; + if (_swimCounter < SwimTime - 450) + { + var catchMode = Game1.GameManager.SaveManager.GetString("mouse_catch", "0"); + if (EntityPosition.X < _spawnPosition.X - 8 && catchMode == "1") + { + Body.Velocity = Vector3.Zero; + _isPulled = true; + _animator.Play("pulled"); + Game1.GameManager.SaveManager.SetString("mouse_pulled", "1"); + } + } + + if (_swimCounter < 0) + { + _swimCounter += SwimTime; + // change direction + if ((_swimDirection > 0 && _spawnPosition.X + 8 < EntityPosition.X) || + (_swimDirection < 0 && EntityPosition.X < _spawnPosition.X - 8)) + { + _swimDirection = -_swimDirection; + _animator.Play("swim_" + _swimDirection); + } + + Body.Velocity.X = _swimDirection; + } + } + + private void UpdateMoving() + { + if (!_isMoving) + return; + + // move towards the target position + var targetDistance = _targetPosition - EntityPosition.Position; + if (targetDistance.Length() > _moveSpeed * Game1.TimeMultiplier) + { + targetDistance.Normalize(); + Body.VelocityTarget = targetDistance * _moveSpeed; + + if (_currentAnimation == null && !_isPulled) + { + var dir = AnimationHelper.GetDirection(targetDistance); + _animator.Play("walk_" + dir); + } + } + // finished walking + else + { + Body.VelocityTarget = Vector2.Zero; + EntityPosition.Set(_targetPosition); + _animator.Pause(); + + if (_nextMoveStep.Count > 0) + DequeueMove(); + else + { + _isMoving = false; + SetMovingString(false); + } + } + } + + private void DequeueMove() + { + var move = _nextMoveStep.Dequeue(); + _moveSpeed = move.MoveSpeed; + _targetPosition = EntityPosition.Position + move.Offset; + } + + private void UpdateFade() + { + if (_fadeTime < 0) + { + _fadeCounter += Game1.DeltaTime; + if (_fadeCounter >= -_fadeTime) + _fadeCounter = -_fadeTime; + + var percentage = _fadeCounter / -_fadeTime; + _sprite.Color = Color.White * percentage; + _shadowComponent.Transparency = percentage; + + if (_fadeCounter >= -_fadeTime) + _fadeTime = 0; + } + else if (_fadeTime > 0) + { + _fadeCounter -= Game1.DeltaTime; + + if (_fadeCounter <= 0) + Map.Objects.DeleteObjects.Add(this); + else + { + var percentage = _fadeCounter / _fadeTime; + _sprite.Color = Color.White * percentage; + _shadowComponent.Transparency = percentage; + } + } + } + + private bool Interact() + { + // only allow interaction from the left side to allow the pushing to work + if (!_isActive || (!_blockedExit && MapManager.ObjLink.Direction != 2)) + return false; + + Game1.GameManager.StartDialogPath(_dialogId); + return true; + } + + private void SetVisibility(bool visible) + { + _sprite.IsVisible = visible; + _shadowComponent.IsActive = visible; + } + + private void KeyChanged() + { + var photoMode = Game1.GameManager.SaveManager.GetString("photo_house_blocked"); + if (!string.IsNullOrEmpty(photoMode)) + { + _photoMode = photoMode == "1"; + _blockedExit = true; + _interactComponent.BoxInteractabel = Body.BodyBox; + } + + var photoFlash = Game1.GameManager.SaveManager.GetString("photo_flash"); + if (photoFlash != null) + { + Map.Objects.SpawnObject(new ObjPhotoFlash(Map)); + Game1.GameManager.SaveManager.RemoveString("photo_flash"); + } + + // start new animation? + var animationString = _dialogId + "Animation"; + var animationValues = Game1.GameManager.SaveManager.GetString(animationString); + if (animationValues != null) + { + if (animationValues == "-") + { + _currentAnimation = null; + } + else if (animationValues != "") + { + SetVisibility(true); + _currentAnimation = animationValues; + _animator.Play(_currentAnimation); + } + else + { + SetVisibility(false); + _currentAnimation = null; + } + + Game1.GameManager.SaveManager.RemoveString(animationString); + } + + // start moving? + var moveString = _dialogId + "Move"; + var moveValue = Game1.GameManager.SaveManager.GetString(moveString); + if (moveValue != null) + { + // offsetX; offsetY; movementSpeed + var split = moveValue.Split(','); + if (split.Length == 3) + { + var offsetX = int.Parse(split[0]); + var offsetY = int.Parse(split[1]); + var moveSpeed = float.Parse(split[2], CultureInfo.InvariantCulture); + + _nextMoveStep.Enqueue(new MoveStep() { MoveSpeed = moveSpeed, Offset = new Vector2(offsetX, offsetY) }); + + StartMoving(); + } + + Game1.GameManager.SaveManager.RemoveString(moveString); + } + + if (!string.IsNullOrEmpty(_spawnCondition)) + { + var spawnValue = Game1.GameManager.SaveManager.GetString(_spawnCondition); + if (!string.IsNullOrEmpty(spawnValue) && spawnValue == "1") + { + SetActive(true); + Game1.GameManager.SaveManager.RemoveString(spawnValue); + } + } + + // start fading away? + var fadeString = _dialogId + "Fade"; + var fadeValue = Game1.GameManager.SaveManager.GetString(fadeString); + if (!string.IsNullOrEmpty(fadeValue)) + { + // negative value -> fade in + // positive value -> fade out + _fadeTime = int.Parse(fadeValue); + _fadeCounter = _fadeTime; + UpdateFade(); + + Game1.GameManager.SaveManager.RemoveString(fadeString); + } + } + + private void StartMoving() + { + if (_isMoving) + return; + + _isMoving = true; + DequeueMove(); + SetMovingString(true); + Body.CollisionTypes = Values.CollisionTypes.None; + } + + private void SetMovingString(bool state) + { + Game1.GameManager.SaveManager.SetString(_dialogId + "Moving", state ? "1" : "0"); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjRaccoon.cs b/InGame/GameObjects/NPCs/ObjRaccoon.cs new file mode 100644 index 0000000..cea6372 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjRaccoon.cs @@ -0,0 +1,203 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjRaccoon : GameObject + { + private readonly CSprite _sprite; + private readonly BodyComponent _body; + private readonly BodyDrawComponent _bodyDrawComponent; + private readonly Animator _animator; + + private readonly RectangleF _laughRectangle; + + private float _rotationTimer = 0; + + private bool _isRotating; + private bool _exploded; + private bool _messageShown; + private bool _spawnedTarin; + + public ObjRaccoon() : base("raccoon") { } + + public ObjRaccoon(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + // raccoon was already transformed? + var value = Game1.GameManager.SaveManager.GetString("raccoon_transformed"); + if (value != null && value == "1") + { + IsDead = true; + return; + } + + _laughRectangle = new RectangleF(posX - 64, posY - 48, 64, 32); + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/raccoon"); + _animator.Play("idle"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-8, -16)); + + _body = new BodyComponent(EntityPosition, -7, -10, 14, 10, 8) + { + IgnoresZ = true, + MoveCollision = OnCollision, + CollisionTypes = Values.CollisionTypes.Normal | + Values.CollisionTypes.NPCWall + }; + _bodyDrawComponent = new BodyDrawComponent(_body, _sprite, Values.LayerPlayer); + + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + AddComponent(BodyComponent.Index, _body); + AddComponent(CollisionComponent.Index, new BodyCollisionComponent(_body, Values.CollisionTypes.Normal | Values.CollisionTypes.PushIgnore)); + AddComponent(InteractComponent.Index, new InteractComponent(_body.BodyBox, Interact)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(HittableComponent.Index, new HittableComponent(_body.BodyBox, OnHit)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, _bodyDrawComponent); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _sprite)); + } + + private void Update() + { + // show the warning message + if (!_messageShown && MapManager.ObjLink.EntityPosition.Y > EntityPosition.Y) + { + _messageShown = true; + Game1.GameManager.SaveManager.SetString("raccoon_warning", null); + } + + if (_isRotating) + UpdateRotation(); + else + { + if (MapManager.ObjLink.BodyRectangle.Intersects(_laughRectangle)) + _animator.Play("laugh"); + else + _animator.Play("idle"); + } + } + + private void UpdateRotation() + { + MapManager.ObjLink.FreezePlayer(); + Game1.GameManager.InGameOverlay.DisableInventoryToggle = true; + + // look at the raccoon + var playerDirection = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + var playerDir = AnimationHelper.GetDirection(playerDirection); + MapManager.ObjLink.SetWalkingDirection(playerDir); + + var direction = _body.VelocityTarget; + if (direction != Vector2.Zero) + { + direction.Normalize(); + + var speed = 3.5f; + if (_rotationTimer < 2000) + speed = 0.5f + (_rotationTimer / 2000) * 3.0f; + + _body.VelocityTarget = direction * speed; + _animator.SpeedMultiplier = speed * 2; + } + + _rotationTimer += Game1.DeltaTime; + + // move up + if (_rotationTimer > 4500) + { + var height = (_rotationTimer - 4500) / 500f; + EntityPosition.Set(new Vector3(EntityPosition.X, EntityPosition.Y, height * 13)); + } + + if (_rotationTimer > 5000 && !_exploded) + { + _exploded = true; + _sprite.IsVisible = false; + _body.VelocityTarget = Vector2.Zero; + + // spawn explosion with sound effect + Game1.GameManager.PlaySoundEffect("D378-12-0C"); + Map.Objects.SpawnObject(new ObjAnimator(Map, (int)EntityPosition.X, (int)EntityPosition.Y - 8 - 13, Values.LayerTop, "Particles/explosionRaccoon", "run", true)); + } + + // spawn tarin + if (_rotationTimer > 5250 && !_spawnedTarin) + { + _spawnedTarin = true; + + // the size cant be bigger than the size of the raccon; otherwise tarin could land on a wall + var npcTarin = new ObjPersonNew(Map, (int)EntityPosition.X, (int)EntityPosition.Y, null, "tarin", "tarin_healed", null, new Rectangle(0, 0, 10, 10)); + npcTarin.EntityPosition.Set(new Vector3(EntityPosition.X, EntityPosition.Y, EntityPosition.Z - 4)); + npcTarin.Body.Gravity = -0.175f; + Map.Objects.SpawnObject(npcTarin); + + Game1.GbsPlayer.Resume(); + } + + if (_rotationTimer > 6000) + { + Game1.GameManager.StartDialogPath("raccoon_transformed"); + Map.Objects.DeleteObjects.Add(this); + } + } + + private void OnCollision(Values.BodyCollision collision) + { + Game1.GameManager.PlaySoundEffect("D360-09-09", true); + + if ((collision & Values.BodyCollision.Horizontal) != 0) + _body.VelocityTarget.X = -_body.VelocityTarget.X; + else if ((collision & Values.BodyCollision.Vertical) != 0) + _body.VelocityTarget.Y = -_body.VelocityTarget.Y; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_isRotating) + return Values.HitCollision.None; + + // powder? + if (damageType == HitType.MagicPowder) + StartMoving(); + + return Values.HitCollision.Blocking; + } + + private void StartMoving() + { + Game1.GbsPlayer.Pause(); + + _isRotating = true; + _animator.Play("rotate"); + _body.VelocityTarget = new Vector2(0.5f, 0.5f); + + _body.OffsetX = -5; + _body.Width = 10; + } + + private void KeyChanged() + { + var value = Game1.GameManager.SaveManager.GetString("raccoon_warning"); + if (value != null) + _messageShown = false; + } + + private bool Interact() + { + Game1.GameManager.StartDialogPath("raccoon"); + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjShopKeeper.cs b/InGame/GameObjects/NPCs/ObjShopKeeper.cs new file mode 100644 index 0000000..26f8435 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjShopKeeper.cs @@ -0,0 +1,187 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjShopkeeper : GameObject + { + private readonly BodyComponent _body; + private readonly BodyDrawComponent _bodyDrawComponent; + private readonly Animator _animator; + + private readonly Rectangle _thunderTop = new Rectangle(444, 118, 14, 16); + private readonly Rectangle _thunderBottom = new Rectangle(476, 107, 32, 32); + + private float _directionChange; + private int _lastDirection = -1; + private bool _isHoldingItem; + + private float _punishCount; + private bool _punishMode; + private bool _punishDialog; + private bool _isPunishing = true; + private bool _showThunder; + private bool _soundEffect; + + public ObjShopkeeper() : base("shopkeeper") { } + + public ObjShopkeeper(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/shopkeeper"); + + // player stole from the shop the last time? + _punishMode = Game1.GameManager.SaveManager.GetString("stoleItem") == "1"; + if (_punishMode) + { + EntityPosition = new CPosition(posX + 8 - 39, posY + 16 - 32, 0); + _animator.Play("stand_3"); + } + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -16)); + + _body = new BodyComponent(EntityPosition, -7, -10, 14, 10, 8); + _bodyDrawComponent = new BodyDrawComponent(_body, sprite, 1); + var interactionBox = new CBox(EntityPosition, -7, -14, 14, 14, 8); + + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + AddComponent(BodyComponent.Index, _body); + AddComponent(CollisionComponent.Index, new BodyCollisionComponent(_body, Values.CollisionTypes.Normal)); + AddComponent(InteractComponent.Index, new InteractComponent(interactionBox, OnInteract)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + } + + public override void Init() + { + if (_punishMode) + MapManager.ObjLink.NextMapPositionEnd = + new Vector2(MapManager.ObjLink.NextMapPositionEnd.Value.X, MapManager.ObjLink.NextMapPositionEnd.Value.Y - 5); + } + + private void Update() + { + if (!_punishMode) + UpdateNormal(); + else + UpdatePunishMode(); + } + + private void UpdateNormal() + { + var playerDistance = new Vector2( + MapManager.ObjLink.EntityPosition.X - (EntityPosition.X), + MapManager.ObjLink.EntityPosition.Y - (EntityPosition.Y - 4)); + + // rotate in the direction of the player + var dir = AnimationHelper.GetDirection(playerDistance); + + if (_lastDirection != dir) + { + _directionChange -= Game1.DeltaTime; + + if (_directionChange <= 0) + { + // 50/50 chance of making the next direction change be fast or slow + _directionChange = Game1.RandomNumber.Next(0, 2) == 0 ? + Game1.RandomNumber.Next(0, 250) : Game1.RandomNumber.Next(1500, 2500); + // look at the player + _animator.Play("stand_" + dir); + _lastDirection = dir; + } + } + + var blockPath = _isHoldingItem && (_lastDirection == 0 || _lastDirection == 3); + Game1.GameManager.SaveManager.SetString("isWatched", blockPath ? "1" : "0"); + } + + private void UpdatePunishMode() + { + if (Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen) + return; + + if (_showThunder) + { + _punishCount += Game1.DeltaTime; + Game1.GameManager.UseShockEffect = _punishCount % 200 < 100; + + if (!_soundEffect) + { + _soundEffect = true; + Game1.GameManager.PlaySoundEffect("D378-38-26"); + } + } + + // show the dialog + if (!_punishDialog && !MapManager.ObjLink.IsTransitioning) + { + Game1.GameManager.StartDialogPath("itemShop_revenge"); + + _punishDialog = true; + _showThunder = true; + } + + if (_punishCount >= 3200 && _isPunishing) + { + _isPunishing = false; + _showThunder = false; + + Game1.GameManager.SaveManager.SetString("stoleItem", "0"); + + Game1.GameManager.UseShockEffect = false; + + // make sure the player actually dies + Game1.GameManager.InflictDamage(Game1.GameManager.MaxHearths * 4 * 2); + Game1.GameManager.RemoveItem("potion", 1); + } + + if (MapManager.ObjLink.IsTransitioning || _showThunder) + MapManager.ObjLink.UpdatePlayer = false; + } + + private void Draw(SpriteBatch spriteBatch) + { + // draw the shopkeeper + _bodyDrawComponent.Draw(spriteBatch); + + // draw the thunder effect + if (!_showThunder) + return; + + var offsetY = -5; + var animationOffset = _punishCount % 133 < 66; + if (_punishCount > 0) + spriteBatch.Draw(Resources.SprNpCs, new Vector2(EntityPosition.X - 8, EntityPosition.Y + offsetY), + new Rectangle(_thunderTop.X + (animationOffset ? _thunderTop.Width + 1 : 0), _thunderTop.Y, _thunderTop.Width, _thunderTop.Height), Color.White); + if (_punishCount > 66) + spriteBatch.Draw(Resources.SprNpCs, new Vector2(EntityPosition.X - 8, EntityPosition.Y + offsetY + 16), + new Rectangle(_thunderTop.X + (animationOffset ? _thunderTop.Width + 1 : 0), _thunderTop.Y, _thunderTop.Width, _thunderTop.Height), Color.White); + if (_punishCount > 133) + spriteBatch.Draw(Resources.SprNpCs, new Vector2(EntityPosition.X - 17, EntityPosition.Y + offsetY + 32), + new Rectangle(_thunderBottom.X + (animationOffset ? _thunderBottom.Width + 1 : 0), _thunderBottom.Y, _thunderBottom.Width, _thunderBottom.Height), Color.White); + } + + private void OnKeyChange() + { + var value = Game1.GameManager.SaveManager.GetString("holdItem"); + _isHoldingItem = value == "1"; + } + + private bool OnInteract() + { + Game1.GameManager.StartDialogPath("shopkeeper"); + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjTracy.cs b/InGame/GameObjects/NPCs/ObjTracy.cs new file mode 100644 index 0000000..27aa1ec --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjTracy.cs @@ -0,0 +1,79 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjTracy : GameObject + { + public BodyComponent Body; + public readonly Animator Animator; + + private float _lookUpdateCounter; + + public ObjTracy() : base("tracy") { } + + public ObjTracy(Map.Map map, int posX, int posY) : base(map) + { + Animator = AnimatorSaveLoad.LoadAnimator("NPCs/npc_tracy"); + Animator.Play("idle"); + + // 28, 42 or 7 + var price = Game1.GameManager.PieceOfPowerCount % 2 == 0 ? 0 : 1; + if (Game1.GameManager.SaveManager.GetInt("npc_tracy", 0) == 8) + price = 2; + + Game1.GameManager.SaveManager.SetString("npc_tracy_price", price.ToString()); + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(Animator, sprite, Vector2.Zero); + + Body = new BodyComponent(EntityPosition, -8, -11, 15, 11, 8); + + AddComponent(BodyComponent.Index, Body); + AddComponent(CollisionComponent.Index, new BodyCollisionComponent(Body, Values.CollisionTypes.Normal)); + AddComponent(InteractComponent.Index, new InteractComponent(Body.BodyBox, Interact)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(Body, sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + } + + private void Update() + { + _lookUpdateCounter += Game1.DeltaTime; + if (_lookUpdateCounter > 250) + { + _lookUpdateCounter = 0; + + // look at the player + var playerDirection = MapManager.ObjLink.EntityPosition.Position - EntityPosition.Position; + if (Math.Abs(playerDirection.X) > Math.Abs(playerDirection.Y)) + { + if (playerDirection.X < 0) + Animator.Play("left"); + else + Animator.Play("right"); + } + else + { + Animator.Play("idle"); + } + } + } + + private bool Interact() + { + Game1.GameManager.StartDialogPath("npc_tracy"); + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjTrendy.cs b/InGame/GameObjects/NPCs/ObjTrendy.cs new file mode 100644 index 0000000..c92a1c0 --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjTrendy.cs @@ -0,0 +1,91 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjTrendy : GameObject + { + private readonly BodyComponent _body; + private readonly Animator _animator; + private readonly CSprite _sprite; + + private bool _grabbed; + private bool _fallen; + private bool _endDialog; + + public ObjTrendy() : base("person") { } + + public ObjTrendy(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/npc_trendy"); + _animator.Play("stand_0"); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -4, -8, 8, 8, 8) + { + RestAdditionalMovement = false, + Gravity = -0.15f, + Bounciness = 0.5f, + MoveCollision = OnMoveCollision + }; + + var box = new CBox(EntityPosition, -7, -14, 14, 14, 8); + AddComponent(BodyComponent.Index, _body); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(box, Values.CollisionTypes.Enemy | Values.CollisionTypes.PushIgnore)); + AddComponent(InteractComponent.Index, new InteractComponent(box, Interact)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(_body, _sprite, Values.LayerPlayer) { WaterOutline = false }); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _sprite)); + } + + private void Update() + { + // go grabbed? + if (!_grabbed && _body.IgnoresZ) + { + _grabbed = true; + _animator.Play("grabbed"); + } + + // let go by the grabber + if (_grabbed && !_body.IgnoresZ) + { + _fallen = true; + _animator.Play("fall"); + } + + // ending dialog? + if (_fallen && !_endDialog && _body.AdditionalMovementVT == Vector2.Zero && EntityPosition.Z == 0 && _body.Velocity.Z == 0) + { + _endDialog = true; + Game1.GameManager.StartDialogPath("trendy_marin_end"); + } + + if (_grabbed) + MapManager.ObjLink.FreezePlayer(); + } + + private void OnMoveCollision(Values.BodyCollision collision) + { + if ((collision & Values.BodyCollision.Floor) != 0) + Game1.GameManager.PlaySoundEffect("D360-09-09"); + } + + private bool Interact() + { + Game1.GameManager.StartDialogPath("npc_trendy"); + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjWalrus.cs b/InGame/GameObjects/NPCs/ObjWalrus.cs new file mode 100644 index 0000000..80efa2c --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjWalrus.cs @@ -0,0 +1,238 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjWalrus : GameObject + { + private readonly Animator _animator; + private readonly AiComponent _aiComponent; + private readonly BodyComponent _body; + private readonly CSprite _sprite; + + private RectangleF _triggerRectangle; + private bool _intersecting; + + private int _jumpCount = 5; + + private Rectangle _spriteSourceRectangle; + + private float _danceCounter; + + private bool _isFalling; + private bool _splashed; + + public ObjWalrus() : base("walrus") { } + + public ObjWalrus(Map.Map map, int posX, int posY, string strDespawnKey) : base(map) + { + if (!string.IsNullOrEmpty(strDespawnKey) && Game1.GameManager.SaveManager.GetString(strDespawnKey) == "1") + { + IsDead = true; + return; + } + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/walrus"); + _animator.Play("sleep"); + + EntityPosition = new CPosition(posX + 16, posY + 29, 0); + EntitySize = new Rectangle(-16, -32, 32, 32); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _triggerRectangle = new RectangleF(posX - 8, posY, 32, 32); + + _body = new BodyComponent(EntityPosition, -16, -12, 32, 12, 8) + { + Gravity = -0.075f, + }; + + _aiComponent = new AiComponent(); + + var stateSleep = new AiState(UpdateSleep); + stateSleep.Trigger.Add(new AiTriggerCountdown(2200, null, SpawnParticle) { ResetAfterEnd = true }); + var stateAwaken = new AiState(UpdateAwaken) { Init = InitAwaken }; + var stateDance = new AiState(UpdateDance) { Init = InitDance }; + var stateJump = new AiState(UpdateJump) { Init = InitJump }; + var stateRoll = new AiState(UpdateRoll) { Init = InitRoll }; + var stateFall = new AiState(UpdateFall) { Init = InitFall }; + + _aiComponent.States.Add("sleep", stateSleep); + _aiComponent.States.Add("awaken", stateAwaken); + _aiComponent.States.Add("dance", stateDance); + _aiComponent.States.Add("jump", stateJump); + _aiComponent.States.Add("roll", stateRoll); + _aiComponent.States.Add("fall", stateFall); + + _aiComponent.ChangeState("sleep"); + + //AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + AddComponent(BodyComponent.Index, _body); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(new CBox(EntityPosition, -16, -24, 32, 24, 8), Values.CollisionTypes.Enemy)); + AddComponent(InteractComponent.Index, new InteractComponent(_body.BodyBox, Interact)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _sprite)); + } + + private void KeyChanged() + { + // start singing? + var value = Game1.GameManager.SaveManager.GetString("walrus_dance"); + if (value != null && value == "1") + { + Game1.GameManager.SaveManager.SetString("walrus_dance", "0"); + _aiComponent.ChangeState("awaken"); + } + } + + private bool Interact() + { + Game1.GameManager.StartDialogPath("walrus"); + return true; + } + + private void SpawnParticle() + { + var objBubble = new ObjBubble(Map, new Vector3(EntityPosition.X - 16, EntityPosition.Y, 19), new Vector3(-0.05f, 0, 0.1f)); + Map.Objects.SpawnObject(objBubble); + } + + private void UpdateSleep() + { + // trigger dialog on entering the trigger area while marin is following the player + if (MapManager.ObjLink._body.IsGrounded && + _triggerRectangle.Intersects(MapManager.ObjLink.BodyRectangle)) + { + if (!_intersecting) + { + var item = Game1.GameManager.GetItem("marin"); + if (item != null && item.Count >= 1) + Game1.GameManager.StartDialogPath("walrus"); + } + + _intersecting = true; + } + else + { + _intersecting = false; + } + } + + private void InitAwaken() + { + _animator.Play("awakening"); + } + + private void UpdateAwaken() + { + if (!_animator.IsPlaying) + _aiComponent.ChangeState("dance"); + } + + private void InitDance() + { + _animator.Play("wobble"); + _danceCounter = 0; + } + + private void UpdateDance() + { + _danceCounter += Game1.DeltaTime; + if (_danceCounter > 250) + { + _danceCounter -= 9999; + Game1.GameManager.PlaySoundEffect("D360-39-27"); + } + + if (!_animator.IsPlaying) + { + if (_jumpCount > 0) + _aiComponent.ChangeState("jump"); + else + _aiComponent.ChangeState("roll"); + } + } + + private void InitJump() + { + _animator.Play("up"); + _body.Velocity.Z = 1.25f; + _jumpCount--; + + Game1.GameManager.PlaySoundEffect("D360-36-24"); + } + + private void UpdateJump() + { + if (_body.Velocity.Z < 0) + _animator.Play("down"); + + if (_body.IsGrounded) + _aiComponent.ChangeState("dance"); + } + + private void InitRoll() + { + _animator.Play("jump"); + + Game1.GameManager.PlaySoundEffect("D360-39-27"); + Game1.GameManager.PlaySoundEffect("D378-17-11"); + } + + private void UpdateRoll() + { + if (!_animator.IsPlaying) + _aiComponent.ChangeState("fall"); + } + + private void InitFall() + { + _animator.Play("fall"); + EntityPosition.Z = 23 + 27; + EntityPosition.Offset(new Vector2(0, 32)); + _spriteSourceRectangle = _sprite.SourceRectangle; + _isFalling = true; + } + + private void UpdateFall() + { + if (!_splashed && EntityPosition.Z < _spriteSourceRectangle.Height) + { + Game1.GameManager.PlaySoundEffect("D378-36-24"); + + var splashAnimator0 = new ObjAnimator(Map, (int)EntityPosition.X - 6, (int)EntityPosition.Y + 1, 0, 0, Values.LayerPlayer, "Particles/fishingSplash", "idle", true); + var splashAnimator1 = new ObjAnimator(Map, (int)EntityPosition.X + 6, (int)EntityPosition.Y + 2, 0, 0, Values.LayerPlayer, "Particles/fishingSplash", "idle", true); + Map.Objects.SpawnObject(splashAnimator0); + Map.Objects.SpawnObject(splashAnimator1); + + _splashed = true; + ((BodyDrawShadowComponent)Components[BodyDrawShadowComponent.Index]).IsActive = false; + } + } + + private void Draw(SpriteBatch spriteBatch) + { + // disapear into the water + if (_isFalling) + { + _sprite.SourceRectangle.Y = _spriteSourceRectangle.Y + MathHelper.Clamp(_spriteSourceRectangle.Height - (int)EntityPosition.Z, 0, _spriteSourceRectangle.Height); + _sprite.SourceRectangle.Height = MathHelper.Clamp((int)EntityPosition.Z, 0, _spriteSourceRectangle.Height); + } + + _sprite.Draw(spriteBatch); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/NPCs/ObjWalrusSwim.cs b/InGame/GameObjects/NPCs/ObjWalrusSwim.cs new file mode 100644 index 0000000..1d6277a --- /dev/null +++ b/InGame/GameObjects/NPCs/ObjWalrusSwim.cs @@ -0,0 +1,128 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.GameObjects.NPCs +{ + internal class ObjWalrusSwim : GameObject + { + private readonly Animator _animator; + private readonly AiComponent _aiComponent; + private readonly BodyComponent _body; + private readonly CSprite _sprite; + + private readonly Vector2 _spawnPosition; + + private string _spawnKey; + private float _moveCounter; + private float _despawnTime; + private bool _dialog; + private bool _init; + + public ObjWalrusSwim() : base("walrus") { } + + public ObjWalrusSwim(Map.Map map, int posX, int posY, string strSpawnKey) : base(map) + { + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/walrus"); + _animator.Play("sleep"); + + EntityPosition = new CPosition(posX + 16, posY + 29, 0); + EntitySize = new Rectangle(-16, -32, 32, 32); + + _spawnPosition = EntityPosition.Position; + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, -16, -12, 32, 12, 8); + _spawnKey = strSpawnKey; + + _aiComponent = new AiComponent(); + + var stateHidden = new AiState() { Init = InitHidden }; + var stateSwim = new AiState(UpdateSwim) { Init = InitSwim }; + + _aiComponent.States.Add("hidden", stateHidden); + _aiComponent.States.Add("swim", stateSwim); + + _aiComponent.ChangeState("hidden"); + + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(OcarinaListenerComponent.Index, new OcarinaListenerComponent(OnSongPlayed)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _sprite)); + } + + private void OnSongPlayed(int songIndex) + { + if (Game1.GameManager.SaveManager.GetString(_spawnKey) != "1") + return; + + if (songIndex == 0 && _aiComponent.CurrentStateId == "hidden") + _aiComponent.ChangeState("swim"); + } + + private void SpawnSplash() + { + if (_init) + Game1.GameManager.PlaySoundEffect("D378-36-24"); + _init = true; + + var splashAnimator0 = new ObjAnimator(Map, (int)EntityPosition.X - 6, (int)EntityPosition.Y + 1, 0, 0, Values.LayerPlayer, "Particles/fishingSplash", "idle", true); + var splashAnimator1 = new ObjAnimator(Map, (int)EntityPosition.X + 6, (int)EntityPosition.Y + 2, 0, 0, Values.LayerPlayer, "Particles/fishingSplash", "idle", true); + Map.Objects.SpawnObject(splashAnimator0); + Map.Objects.SpawnObject(splashAnimator1); + } + + private void InitHidden() + { + _moveCounter = 0; + _sprite.IsVisible = false; + SpawnSplash(); + } + + private void InitSwim() + { + _despawnTime = 0; + _dialog = false; + _sprite.IsVisible = true; + EntityPosition.Set(_spawnPosition); + SpawnSplash(); + } + + private void UpdateSwim() + { + _moveCounter += Game1.DeltaTime; + if (!Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen) + { + _despawnTime += Game1.DeltaTime; + if (_despawnTime > 5000) + _aiComponent.ChangeState("hidden"); + } + + if (!_dialog && _moveCounter > 2000) + { + var playerDistance = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + if (playerDistance.Length() < 80) + { + _dialog = true; + Game1.GameManager.StartDialogPath("walrus_swim"); + } + } + + var offset = new Vector2(0, (int)MathF.Round(MathF.Cos(_moveCounter / 2000 * MathF.PI * 2))); + EntityPosition.Set(_spawnPosition + offset); + + _animator.Play("swim_" + (offset.Y > 0 ? "up" : "down")); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/ObjLink.cs b/InGame/GameObjects/ObjLink.cs new file mode 100644 index 0000000..eb93d94 --- /dev/null +++ b/InGame/GameObjects/ObjLink.cs @@ -0,0 +1,4870 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using ProjectZ.Base; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Systems; +using ProjectZ.InGame.GameObjects.Dungeon; +using ProjectZ.InGame.GameObjects.NPCs; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.GameSystems; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects +{ + public partial class ObjLink : GameObject + { + public enum State + { + Idle, Pushing, Grabbing, Pulling, Jumping, Attacking, Charging, Blocking, PreCarrying, Carrying, Throwing, CarryingItem, PickingUp, Falling, + Ocarina, OcarinaTelport, Rafting, Pushed, + FallRotateEntry, + Drowning, Drowned, Swimming, + Teleporting, MagicRod, Hookshot, Bombing, Powdering, Digging, BootKnockback, + TeleporterUpWait, TeleporterUp, TeleportFallWait, TeleportFall, + Dying, InitStunned, Stunned, Knockout, + SwordShow0, SwordShow1, SwordShowLv2, + ShowInstrumentPart0, ShowInstrumentPart1, ShowInstrumentPart2, ShowInstrumentPart3, + ShowToadstool, + CloakShow0, CloakShow1, + Intro, BedTransition, + Sequence, FinalInstruments, + Frozen + } + + public State CurrentState; + + private List _bombList = new List(); + private List _ocarinaList = new List(); + private List _destroyableWallList = new List(); + + // movement stuff + public float PosX => EntityPosition.X; + public float PosY => EntityPosition.Y; + public float PosZ => EntityPosition.Z; + + private const float WalkSpeed = 1.0f; + private const float WalkSpeedPoP = 20 / 16f; + private const float BootsRunningSpeed = 2.0f; + private const float SwimSpeed = 0.5f; + private const float SwimSpeedA = 1.0f; + + private float _currentWalkSpeed; + private float _waterSoundCounter; + + private readonly Vector2[] _walkDirection = { new Vector2(-1, 0), new Vector2(0, -1), new Vector2(1, 0), new Vector2(0, 1) }; + + public Vector2 ForwardVector + { + get => _walkDirection[Direction]; + } + + private Vector2 _moveVelocity; + private Vector2 _lastMoveVelocity; + private Vector2 _lastBaseMoveVelocity; + public Vector2 LastMoveVector; + + private Point _lastTilePosition; + + public int Direction; + private bool _isWalking; + + // player animations + public readonly Animator Animation; + private int _animationOffsetX = -7; + private int _animationOffsetY = -16; + + private CSprite _sprite; + private float _spriteTransparency; + + private bool _isVisible; + public bool IsVisible + { + get => _isVisible; + set + { + _isVisible = value; + _sprite.IsVisible = value; + } + } + + // weapon animations + private Animator AnimatorWeapons; + + private double _fallEntryCounter; + + // hole stuff + private Vector2 _holeResetPoint; + private Vector2 _alternativeHoleResetPosition; // map change on hole fall + public string HoleResetRoom; + public string HoleResetEntryId; + public int HoleTeleporterId; + public bool WasHoleReset; + private double _holeTeleportCounter; + // counter to start the level change + private float _holeFallCounter; + private bool _isFallingIntoHole; + + // body stuff + public BodyComponent _body; + public RectangleF BodyRectangle => _body.BodyBox.Box.Rectangle(); + public RectangleF PlayerRectangle => new RectangleF(PosX - 4, PosY - 12 - PosZ, 8, 12); + private BodyDrawComponent _drawBody; + private BodyDrawShadowComponent _shadowComponent; + private DrawComponent.DrawTemplate _bodyDrawFunction; + + // carried object + private GameObject _carriedGameObject; + private DrawComponent _carriedObjDrawComp; + private CarriableComponent _carriedComponent; + private Vector3 _carryStartPosition; + + // show item + public GameItem ShowItem; + private Vector2 _showItemOffset; + // used to only collect the item after it was shown + private GameItemCollected _collectedShowItem; + private string _pickupDialogOverride; + private string _additionalPickupDialog; + private double _itemShowCounter; + private bool _showItem; + + private bool _savedPreItemPickup; + public bool SavePreItemPickup + { + get { return _savedPreItemPickup; } + } + + private const int dist0 = 30; + private const int dist1 = 15; + private readonly Vector2[] _showInstrumentOffset = { + new Vector2(-dist1, -dist0), new Vector2(dist1, -dist0), new Vector2(dist0, dist1), new Vector2(dist0, -dist1), + new Vector2(dist1, dist0),new Vector2(-dist1, dist0),new Vector2(-dist0, -dist1),new Vector2(-dist0, dist1) }; + + private readonly int[] _instrumentMusicIndex = { 31, 39, 40, 41, 42, 43, 44, 45 }; + + // show sword lv2 + private float _showSwordLv2Counter; + private float _showSwordL2ParticleCounter; + private bool _shownSwordLv2Dialog; + + // transition stuff + public Vector2? MapTransitionStart; + public Vector2? MapTransitionEnd; + public Vector2? NextMapPositionStart; + public Vector2? NextMapPositionEnd; + public string NextMapPositionId; + public int DirectionEntry; + public bool IsTransitioning; + public bool NextMapFallStart; + public bool NextMapFallRotateStart; + public bool TransitionOutWalking; + public bool TransitionInWalking; + private bool _wasTransitioning; + private bool _startBedTransition; + + // rail jump + private Vector2 _railJumpStartPosition; + private Vector2 _railJumpTargetPosition; + private float _railJumpPositionZ; + private float _railJumpPercentage; + private float _railJumpHeight; + + // swim stuff + private Vector2 _swimVelocity; + private float _swimBoostCount; + private float _diveCounter; + + // store item picked up by the player + public GameItem StoreItem; + private int _storeItemWidth; + private int _storeItemHeight; + private Vector2 _storePickupPosition; + private bool _showStealMessage; + + // follower + private GameObjectFollower _objFollower; + private ObjCock _objRooster; + private ObjMarin _objMaria; + + private const string _spawnGhostKey = "spawn_ghost"; + private ObjGhost _objGhost; + private bool _spawnGhost; + + // boots + private bool _bootsHolding; + private bool _bootsRunning; + private bool _wasBootsRunning; + private bool _bootsStop; + private float _bootsCounter; + private float _bootsRunTime = 500; + private float _bootsParticleTime = 120; + + // trapped state + private int _trapInteractionCount; + private bool _isTrapped; + private bool _trappedDisableItems; + + // raft + private ObjRaft _objRaft; + private bool _isRafting; + + // stonelifter pull + private const float PullTime = 100; + private const float PullMaxTime = 400; + private const float PullResetTime = -133; + private float _pullCounter; + private bool _isPulling; + private bool _wasPulling; + // pick up time + private const float PreCarryTime = 200; + private float _preCarryCounter; + + // drown stuff + private Vector2 _drownResetPosition; + private float _drownCounter; + private float _drownResetCounter; + + // sword stuff + public Box SwordDamageBox; + private float _swordPokeTime = 100; + private float _swordPokeCounter; + + private Vector2[] _shootSwordOffset; + private bool _shotSword; + + public CBox DamageCollider; + private Vector2 _hitVelocity; + public const int BlinkTime = 66; + public const int CooldownTime = BlinkTime * 16; + + private double _hitCount; + private double _hitRepelTime; + private double _hitParticleTime; + + private const float SwordChargeTime = 500; + private float _swordChargeCounter; + private bool _swordPoked; + private bool _stopCharging; + + private Point[] _pokeAnimationOffset; + private bool _isHoldingSword; + private bool _isSwingingSword; + public bool CarrySword; + + // items + private ObjBoomerang _boomerang = new ObjBoomerang(); + private Vector2[] _boomerangOffset; + private Vector2[] _arrowOffset; + public bool HasFlippers; + + // arrow + private const float ArrowSpeed = 3; + private const float ArrowSpeedPoP = 4; + + // shield + public bool CarryShield; + private bool _wasBlocking; + + // hookshot + public ObjHookshot Hookshot = new ObjHookshot(); + private Vector2[] _hookshotOffset; + private bool _hookshotPull; + + // magic rod + private Vector2[] _magicRodOffset; + private const float MagicRodSpeed = 3; + private const float MagicRodSpeedPoP = 4; + + // shovel + private Vector2[] _shovelOffset; + private Point _digPosition; + private bool _hasDug; + private bool _canDig; + + private Vector2[] _powderOffset; + private Vector2[] _bombOffset; + + // ocarina + private float _ocarinaCounter; + private int _ocarinaNoteIndex; + private int _ocarinaSong; + + // jump stuff + private bool _canJump = true; + private const float JumpAcceleration = 2.35f; + private float _railJumpSpeed; + // should probably have been a different state because we do not want to be able to use certain items while railjumping compared to normally jumping + private bool _railJump; + private bool _startedJumping; + private bool _hasStartedJumping; + + // cloak transition + private int CloakTransitionTime = 2200; + private float _cloakTransitionCounter; + private float _cloakPercentage; + private int CloakTransitionOutTime = 2500; + private float _cloakTransitionOutCounter; + + // teleport stuff + private ObjDungeonTeleporter _teleporter; + private string _teleportMap; + private string _teleporterId; + private float _teleportCounter; + private float _teleportCounterFull; + private int _teleportState; + + // instrument stuff + // @TODO: replace + private Rectangle[] _noteSourceRectangles = { new Rectangle(145, 97, 10, 12), new Rectangle(156, 97, 6, 12) }; + private bool[] _noteInit = { false, false }; + private int[] _noteSpriteIndex = { 0, 0 }; + + private double _instrumentPickupTime; + private float _instrumentCounter; + private float _instrumentEndTime; + private int _instrumentIndex; + private int _instrumentCycleTime = 1000; + private bool _drawInstrumentEffect; + private bool _pickingUpInstrument; + private bool _pickingUpSword; + + // push stuff + private Vector2 _pushStart; + private Vector2 _pushEnd; + private float _pushCounter; + private int _pushTime; + + // used by the vaccuum + private float _rotationCounter; + + // stunned state + private float _stunnedCounter; + private bool _stunnedParticles; + + // final sequence + private int _finalIndex; + private double _finalSeqCounter; + + // save position + public string SaveMap; + public Vector2 SavePosition; + public int SaveDirection; + + // other stuff + public Point CollisionBoxSize; + private MapStates.FieldStates _lastFieldState; + + public bool CanWalk; + public bool DisableItems; + public bool UpdatePlayer; + public bool IsPoking; + private bool _pokeStart; + private bool _isLocked; + private bool _isGrabbed; + private bool _isFlying; + private bool _inDungeon; + +#if DEBUG + private bool _attackMode; +#endif + + private DictAtlasEntry _stunnedParticleSprite; + + public ObjLink() : base((Map.Map)null) + { + EntityPosition = new CPosition(0, 0, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + // load the player + sword animations + Animation = AnimatorSaveLoad.LoadAnimator("link0"); + AnimatorWeapons = AnimatorSaveLoad.LoadAnimator("Objects/sword"); + + _stunnedParticleSprite = Resources.GetSprite("stunned particle"); + + CollisionBoxSize = new Point(8, 8); + + _body = new BodyComponent(EntityPosition, -4, -10, 8, 10, 8) + { + IsPusher = true, + IsSlider = true, + MaxJumpHeight = 3, + Drag = 0.9f, + DragAir = 0.9f, + Gravity = -0.15f, + Gravity2D = 0.1f, + AbsorbPercentage = 1f, + HoleOnPull = OnHolePull, + HoleAbsorb = OnHoleAbsorb, + MoveCollision = OnMoveCollision, + CollisionTypes = Values.CollisionTypes.Normal | + Values.CollisionTypes.Enemy | + Values.CollisionTypes.PlayerItem | + Values.CollisionTypes.LadderTop, + }; + + DamageCollider = new CBox(EntityPosition, -5, -10, 10, 10, 8); + + _powderOffset = new[] + { + new Vector2(-12, 0), + new Vector2(-2, -CollisionBoxSize.Y -5), + new Vector2(12, 0), + new Vector2(2, 10) + }; + + _boomerangOffset = new[] + { + new Vector2(-10, -3), + new Vector2(-2, -CollisionBoxSize.Y -1), + new Vector2(10, -3), + new Vector2(2, 6) + }; + + _arrowOffset = new[] + { + new Vector2(-10, 0), + new Vector2(-2, -CollisionBoxSize.Y -1), + new Vector2(10, 0), + new Vector2(2, 6) + }; + + _magicRodOffset = new[] + { + new Vector2(-10, -4), + new Vector2(-4, -CollisionBoxSize.Y - 8), + new Vector2(10, -4), + new Vector2(3, 4) + }; + + _shootSwordOffset = new[] + { + new Vector2(-10, -4), + new Vector2(-5, -CollisionBoxSize.Y - 8), + new Vector2(10, -4), + new Vector2(4, 4) + }; + + _hookshotOffset = new[] + { + new Vector2(-5, -4), + new Vector2(-3, -CollisionBoxSize.Y - 2), + new Vector2(5, -4), + new Vector2(3, 0) + }; + + _shovelOffset = new[] + { + new Vector2(-9, -1), + new Vector2(0, -14), + new Vector2(9, -1), + new Vector2(0, 1) + }; + + _bombOffset = new[] + { + new Vector2(-10, 0), + new Vector2(0, -CollisionBoxSize.Y - 2), + new Vector2(10, 0), + new Vector2(0, 8) + }; + + _pokeAnimationOffset = new[] + { + new Point(-16, -4), + new Point(-4, -CollisionBoxSize.Y - 16), + new Point(16, -4), + new Point(5, 12) + }; + + _sprite = new CSprite(EntityPosition); + // cant just change the offset value without changing the blocking rectangle + var animatorComponent = new AnimationComponent(Animation, _sprite, new Vector2(_animationOffsetX, _animationOffsetY)); + + // custom draw function + _drawBody = new BodyDrawComponent(_body, DrawLink, Values.LayerPlayer); + _bodyDrawFunction = _drawBody.Draw; + _drawBody.Draw = Draw; + + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animatorComponent); + AddComponent(CollisionComponent.Index, new BodyCollisionComponent(_body, Values.CollisionTypes.Player)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, _drawBody); + AddComponent(DrawShadowComponent.Index, _shadowComponent = new BodyDrawShadowComponent(_body, _sprite)); + + EntityPosition.AddPositionListener(typeof(CarriableComponent), UpdatePositionCarriedObject); + } + + private void Update() + { +#if DEBUG + if (InputHandler.KeyPressed(Keys.Y)) + Game1.GameManager.InitPieceOfPower(); + if (InputHandler.KeyPressed(Keys.X)) + _attackMode = !_attackMode; + if (_attackMode) + { + var damageBox = new Box(EntityPosition.X - 160, EntityPosition.Y - 140, 0, 320, 280, 16); + var damageOrigin = damageBox.Center; + //Map.Objects.Hit(this, damageOrigin, damageBox, HitType.Sword1, Game1.GameManager.PieceOfPowerIsActive ? 2 : 1, Game1.GameManager.PieceOfPowerIsActive); + //Map.Objects.Hit(this, damageOrigin, damageBox, HitType.Bomb, 2, false); + Map.Objects.Hit(this, damageOrigin, damageBox, HitType.Bow, 2, false); + //Map.Objects.Hit(this, damageOrigin, damageBox, HitType.Hookshot, 2, false); + //Map.Objects.Hit(this, damageOrigin, damageBox, HitType.MagicRod, 2, false); + //Map.Objects.Hit(this, damageOrigin, damageBox, HitType.MagicPowder, 2, false); + //Map.Objects.Hit(this, damageOrigin, damageBox, HitType.PegasusBootsSword, 2, false); + //Map.Objects.Hit(this, damageOrigin, damageBox, HitType.PegasusBootsPush, 2, false); + //Map.Objects.Hit(this, damageOrigin, damageBox, HitType.ThrownObject, 2, false); + //Map.Objects.Hit(this, damageOrigin, damageBox, HitType.SwordShot, 2, false); + //Map.Objects.Hit(this, damageOrigin, damageBox, HitType.SwordHold, 2, false); + //Map.Objects.Hit(this, damageOrigin, damageBox, HitType.SwordSpin, 2, false); + } +#endif + + if (CurrentState == State.FallRotateEntry) + { + _fallEntryCounter += Game1.DeltaTime; + Direction = (int)(DirectionEntry + (_fallEntryCounter + 96) / 48) % 4; + + if (_body.IsGrounded) + CurrentState = State.Idle; + + UpdateAnimation(); + } + + // @HACK + // this is only needed because the player should not be able to step into the door 1 frame after finishing the transition + // this would cause the door transition to not start + if (IsTransitioning || _wasTransitioning) + { + _wasTransitioning = IsTransitioning; + return; + } + + // first photo sequence + if (CurrentState == State.Pushed) + { + _pushCounter += Game1.DeltaTime; + + // push towards the target position + if (_pushCounter > _pushTime) + { + EntityPosition.Set(_pushEnd); + CurrentState = State.Idle; + } + else + { + var percentage = MathF.Sin((_pushCounter / _pushTime) * MathF.PI * 0.5f); + var newPosition = Vector2.Lerp(_pushStart, _pushEnd, percentage); + EntityPosition.Set(newPosition); + } + } + + // need to update the bomb to make sure it does not explode while the player is not getting updated + if (_carriedComponent != null && _carriedComponent.IsPickedUp) + { + // used to updated the position to match the animation + // gets called twice when moving + // not sure how this could be done better + UpdatePositionCarriedObject(EntityPosition); + } + + if (!UpdatePlayer) + { + UpdatePlayer = true; + + // only update the animation + if (!Is2DMode) + UpdateAnimation(); + else + Update2DFrozen(); + + UpdateOcarinaAnimation(); + UpdateDive(); + UpdateDrawComponents(); + + return; + } + + UpdateHeartWarningSound(); + + if (CurrentState == State.FinalInstruments) + { + _finalSeqCounter -= Game1.DeltaTime; + if (_finalIndex == 0) + { + if (_finalSeqCounter <= 0) + { + _finalIndex = 1; + _finalSeqCounter += 2250; + Animation.Play("show1"); + Game1.GameManager.PlaySoundEffect("D360-52-34"); + } + } + else if (_finalIndex == 1) + { + if (_finalSeqCounter <= 0) + ((MapShowSystem)Game1.GameManager.GameSystems[typeof(MapShowSystem)]).StartEnding(); + } + + return; + } + else if (CurrentState == State.CloakShow0) + { + _cloakTransitionCounter += Game1.DeltaTime; + _cloakPercentage = _cloakTransitionCounter / CloakTransitionTime; + + if (_cloakTransitionCounter > CloakTransitionTime) + { + _cloakPercentage = 1; + + if (ShowItem.Name == "cloakBlue") + Game1.GameManager.StartDialog("cloak_blue"); + if (ShowItem.Name == "cloakRed") + Game1.GameManager.StartDialog("cloak_red"); + + CurrentState = State.CloakShow1; + + // add the item to the inventory + if (_collectedShowItem != null) + { + Game1.GameManager.CollectItem(_collectedShowItem, 0); + _collectedShowItem = null; + } + + ShowItem = null; + } + } + else if (CurrentState == State.CloakShow1) + { + _cloakTransitionOutCounter += Game1.DeltaTime; + + var transitionSystem = (MapTransitionSystem)Game1.GameManager.GameSystems[typeof(MapTransitionSystem)]; + transitionSystem.SetColorMode(Color.White, MathHelper.Clamp(_cloakTransitionOutCounter / 1000f, 0, 1)); + + if (_cloakTransitionOutCounter > CloakTransitionOutTime) + { + Game1.GameManager.StartDialogPath("color_fairy_4"); + + Direction = 3; + MapTransitionStart = EntityPosition.Position; + MapTransitionEnd = MapTransitionStart; + TransitionOutWalking = false; + + // append a map change + ((MapTransitionSystem)Game1.GameManager.GameSystems[typeof(MapTransitionSystem)]).AppendMapChange( + "overworld.map", "cloakOut", false, true, Color.White, true); + } + } + else if (CurrentState == State.ShowToadstool) + { + CurrentState = State.Idle; + } + else if (CurrentState == State.SwordShowLv2) + { + _showSwordL2ParticleCounter += Game1.DeltaTime; + if (_showSwordL2ParticleCounter > 4800 && !_shownSwordLv2Dialog) + { + _shownSwordLv2Dialog = true; + _showSwordL2ParticleCounter = 0; + Game1.GameManager.SetMusic(-1, 2); + Game1.GameManager.StartDialogPath("sword2Collected"); + } + // make sure to show the sword while the dialog box is open + else if (_shownSwordLv2Dialog) + { + ShowItem = null; + CurrentState = State.Idle; + } + } + else if (CurrentState == State.PickingUp && !_pickingUpInstrument && !_pickingUpSword) + { + Game1.GameManager.FreezeWorldAroundPlayer = true; + } + else if (CurrentState == State.TeleporterUpWait) + { + _holeTeleportCounter += Game1.DeltaTime; + if (_holeTeleportCounter > 1000) + { + CurrentState = State.TeleporterUp; + + _holeTeleportCounter -= 1000; + _shadowComponent.Transparency = 0; + + Game1.GameManager.PlaySoundEffect("D360-37-25"); + } + } + else if (CurrentState == State.TeleporterUp) + { + _holeTeleportCounter += Game1.DeltaTime; + var time = 400; + + EntityPosition.Z = (float)(_holeTeleportCounter / time) * 128; + Direction = (int)(_holeTeleportCounter / 64) % 4; + + // fade in + var percentage = MathHelper.Clamp(1 - ((float)_holeTeleportCounter - (time - 100)) / 100, 0, 1); + _spriteTransparency = percentage; + _shadowComponent.Transparency = percentage; + + if (_holeTeleportCounter > time) + { + _holeTeleportCounter -= time; + + if (ObjOverworldTeleporter.TeleporterDictionary.TryGetValue(HoleTeleporterId, out var teleporter)) + teleporter.SetNextTeleporterPosition(); + else + CurrentState = State.Idle; // should not happen + } + } + else if (CurrentState == State.TeleportFallWait) + { + _holeTeleportCounter += Game1.DeltaTime; + var time = 350; + + if (_holeTeleportCounter > time) + { + _holeTeleportCounter -= time - 50; + _body.Velocity = new Vector3(0, 0, 0); + CurrentState = State.TeleportFall; + } + } + else if (CurrentState == State.TeleportFall) + { + _holeTeleportCounter += Game1.DeltaTime; + Direction = (int)(_holeTeleportCounter / 64) % 4; + + // fade in + var percentage = MathHelper.Clamp((float)_holeTeleportCounter / 100, 0, 1); + + if (_body.IsGrounded) + { + percentage = 1; + CurrentState = State.Idle; + + UpdateSaveLocation(); + + // save settings? + if (GameSettings.Autosave) + { + SaveGameSaveLoad.SaveGame(Game1.GameManager); + Game1.GameManager.InGameOverlay.InGameHud.ShowSaveIcon(); + } + } + + _spriteTransparency = percentage; + _shadowComponent.Transparency = percentage; + } + + if (CurrentState == State.Knockout) + return; + + // stunned player + if (CurrentState == State.InitStunned && _hitVelocity.Length() < 0.25f) + { + Animation.Play("stunned"); + CurrentState = State.Stunned; + } + if (CurrentState == State.Stunned && _stunnedCounter > 0) + { + _stunnedCounter -= Game1.DeltaTime; + + if (_stunnedCounter <= 0) + CurrentState = State.Idle; + } + + AnimatorWeapons.Update(); + + // update all the item stuff + // this need to be before the update method to correctly start jumping? + UpdateItem(); + + if (Is2DMode) + Update2D(); + else + Update3D(); + + UpdateOcarina(); + + UpdateDamageShader(); + _hitCount -= Game1.DeltaTime; + + if (_savedPreItemPickup && (CurrentState == State.Idle || CurrentState == State.Swimming)) + EndPickup(); + + // die? + if (Game1.GameManager.CurrentHealth <= 0 && !Game1.GameManager.UseShockEffect) + OnDeath(); + + UpdateDrawComponents(); + + DisableItems = false; + HoleResetRoom = null; + CanWalk = true; + _canJump = true; + _isLocked = false; + + _hasStartedJumping = _startedJumping; + _startedJumping = false; + + _currentWalkSpeed = Game1.GameManager.PieceOfPowerIsActive ? WalkSpeedPoP : WalkSpeed; + } + + #region Draw + + private void Draw(SpriteBatch spriteBatch) + { + Game1.DebugText += "Jump Timer: " + _railJumpPercentage + "\n"; + Game1.DebugText += "Player State: " + CurrentState; + + if (!IsVisible) + return; + + // draw the player sprite behind the sword + if (Direction != 1 && !_isTrapped) + _bodyDrawFunction(spriteBatch); + + // draw the sword/magic rod + if (CurrentState == State.Attacking || + CurrentState == State.Charging || + CurrentState == State.SwordShow0 || + CurrentState == State.MagicRod || + (_bootsRunning && CarrySword)) + { + var changeColor = _swordChargeCounter <= 0 && + Game1.TotalGameTime % (8 / 0.06) >= 4 / 0.06 && + ObjectManager.CurrentEffect != Resources.DamageSpriteShader0.Effect; + + // change the draw shader + if (changeColor) + { + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, Resources.DamageSpriteShader0); + } + + AnimatorWeapons.Draw(spriteBatch, new Vector2(EntityPosition.X - 7, EntityPosition.Y - 16 - EntityPosition.Z), Color.White); + + if (changeColor) + { + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, null); + } + } + + // draw the sword after the first pickup + if (CurrentState == State.SwordShow1) + { + var itemSword = Game1.GameManager.ItemManager["sword1"]; + var position = new Vector2( + BodyRectangle.X - itemSword.SourceRectangle.Value.Width / 2f, + (EntityPosition.Y - EntityPosition.Z - 15) - itemSword.SourceRectangle.Value.Height); + + ItemDrawHelper.DrawItem(spriteBatch, itemSword, position, Color.White, 1, true); + } + + // draw the toadstool + if (CurrentState == State.ShowToadstool) + { + var itemToadstool = Game1.GameManager.ItemManager["toadstool"]; + var position = new Vector2( + BodyRectangle.X - itemToadstool.SourceRectangle.Value.Width / 2f, + (EntityPosition.Y - EntityPosition.Z - 15) - itemToadstool.SourceRectangle.Value.Height); + + ItemDrawHelper.DrawItem(spriteBatch, itemToadstool, position, Color.White, 1); + } + + // draw the player sprite in front of the sword + if (Direction == 1 && !_isTrapped) + _bodyDrawFunction(spriteBatch); + + if (_drawInstrumentEffect) + DrawInstrumentEffect(spriteBatch); + + // draw the picked up store item + if (StoreItem != null) + ItemDrawHelper.DrawItem(spriteBatch, StoreItem, _storePickupPosition, Color.White, 1, true); + + // draw the shown item + if (ShowItem != null) + { + var itemPosition = EntityPosition.Position + _showItemOffset; + itemPosition.Y -= EntityPosition.Z; + + if (CurrentState == State.CloakShow0) + { + ItemDrawHelper.DrawItem(spriteBatch, ShowItem, itemPosition, Color.White * (1 - _cloakPercentage), 1, true); + } + else if (ShowItem.Name == "sword2") + { + var swordImage = Resources.GetSprite("sword2Show"); + DrawHelper.DrawNormalized(spriteBatch, swordImage.Texture, itemPosition, swordImage.ScaledRectangle, Color.White, swordImage.Scale); + } + else + ItemDrawHelper.DrawItem(spriteBatch, ShowItem, itemPosition, Color.White, 1, true); + } + + // draw the object the player is carrying + if (_carriedObjDrawComp != null) + { + _carriedObjDrawComp.IsActive = true; + _carriedObjDrawComp.Draw(spriteBatch); + _carriedObjDrawComp.IsActive = false; + } + + // draw the dots over the head in the stunned state + if (CurrentState == State.Stunned && _stunnedParticles) + { + var rotation = (float)(Game1.TotalGameTime / 1200) * MathF.PI * 2; + var offset0 = new Vector2(MathF.Cos(rotation) * 8 - 2, MathF.Sin(rotation) * 3 - 2); + DrawHelper.DrawNormalized(spriteBatch, _stunnedParticleSprite, + offset0 + new Vector2(EntityPosition.X, EntityPosition.Y - EntityPosition.Z - 18), Color.White); + + var offset1 = new Vector2(MathF.Cos(rotation + MathF.PI) * 8 - 2, MathF.Sin(rotation + MathF.PI) * 3 - 2); + DrawHelper.DrawNormalized(spriteBatch, _stunnedParticleSprite, + offset1 + new Vector2(EntityPosition.X, EntityPosition.Y - EntityPosition.Z - 18), Color.White); + } + + if (CurrentState == State.SwordShowLv2) + DrawSwordL2Particles(spriteBatch); + + // draw the notes while showing an instrument + { + var leftNotePosition = new Vector2(EntityPosition.X - 8, EntityPosition.Y - 24); + DrawNote(spriteBatch, leftNotePosition, new Vector2(-0.4f, -1.0f), 0); + + var rightNotePosition = new Vector2(EntityPosition.X + 8, EntityPosition.Y - 24); + DrawNote(spriteBatch, rightNotePosition, new Vector2(0.4f, -1.0f), 1); + } + + if (CurrentState == State.FinalInstruments) + DrawFinalInstruments(spriteBatch); + + if (Game1.DebugMode) + { + // draw the save hole position + spriteBatch.Draw(Resources.SprWhite, + new Vector2(_holeResetPoint.X - 5, _holeResetPoint.Y - 5), new Rectangle(0, 0, + 10, 10), Color.HotPink * 0.65f); + + // weapon damage rectangle + var swordRectangle = SwordDamageBox.Rectangle(); + spriteBatch.Draw(Resources.SprWhite, + new Vector2(swordRectangle.X, swordRectangle.Y), new Rectangle(0, 0, + (int)swordRectangle.Width, (int)swordRectangle.Height), Color.Blue * 0.75f); + } + } + + private void DrawSwordL2Particles(SpriteBatch spriteBatch) + { + DrawSwordParticle(spriteBatch, new Vector2(EntityPosition.X - 4, EntityPosition.Y - 22), new Vector2(-32, -16), -125, 300, 200, 0); + DrawSwordParticle(spriteBatch, new Vector2(EntityPosition.X - 4, EntityPosition.Y - 22), new Vector2(-32, -16), -125 - 250, 300, 200, 0); + + DrawSwordParticle(spriteBatch, new Vector2(EntityPosition.X - 4, EntityPosition.Y - 22), new Vector2(-32, -32), 0, 300, 200, 1); + DrawSwordParticle(spriteBatch, new Vector2(EntityPosition.X - 4, EntityPosition.Y - 22), new Vector2(-32, -32), -250, 300, 200, 1); + + DrawSwordParticle(spriteBatch, new Vector2(EntityPosition.X - 4, EntityPosition.Y - 22), new Vector2(-24, -52), -50, 450, 50, 2); + DrawSwordParticle(spriteBatch, new Vector2(EntityPosition.X - 4, EntityPosition.Y - 22), new Vector2(-24, -52), -50 - 250, 450, 50, 2); + + DrawSwordParticle(spriteBatch, new Vector2(EntityPosition.X - 4, EntityPosition.Y - 22), new Vector2(0, -64), -75, 450, 50, 3); + DrawSwordParticle(spriteBatch, new Vector2(EntityPosition.X - 4, EntityPosition.Y - 22), new Vector2(0, -64), -75 - 250, 450, 50, 3); + + DrawSwordParticle(spriteBatch, new Vector2(EntityPosition.X - 4, EntityPosition.Y - 22), new Vector2(24, -52), -50, 450, 50, 4); + DrawSwordParticle(spriteBatch, new Vector2(EntityPosition.X - 4, EntityPosition.Y - 22), new Vector2(24, -52), -50 - 250, 450, 50, 4); + + DrawSwordParticle(spriteBatch, new Vector2(EntityPosition.X - 4, EntityPosition.Y - 22), new Vector2(32, -32), 0, 300, 200, 5); + DrawSwordParticle(spriteBatch, new Vector2(EntityPosition.X - 4, EntityPosition.Y - 22), new Vector2(32, -32), -250, 300, 200, 5); + + DrawSwordParticle(spriteBatch, new Vector2(EntityPosition.X - 4, EntityPosition.Y - 22), new Vector2(32, -16), -125, 300, 200, 6); + DrawSwordParticle(spriteBatch, new Vector2(EntityPosition.X - 4, EntityPosition.Y - 22), new Vector2(32, -16), -125 - 250, 300, 200, 6); + } + + private void DrawInstrumentEffect(SpriteBatch spriteBatch) + { + var fadeTime = 100; + var speed = 500; + var center = new Vector2(EntityPosition.X, EntityPosition.Y - 20); + + { + var time = (float)(Game1.TotalGameTime % speed); + var state = MathF.Sin((time / speed) * MathF.PI * 0.475f); + var distance = 32 - 20 * state; + var transparency = MathHelper.Clamp(time / fadeTime, 0, 1) * + MathHelper.Clamp((speed - time) / fadeTime, 0, 1); + var sourceRectangle = time < (speed / 1.65f) ? new Rectangle(194, 114, 12, 12) : new Rectangle(194, 98, 12, 12); + + for (var y = 0; y < 2; y++) + for (var x = 0; x < 2; x++) + { + var position = new Vector2( + center.X - 6 + (x * 2 - 1) * distance, + center.Y - 6 + (y * 2 - 1) * distance); + spriteBatch.Draw(Resources.SprItem, position, sourceRectangle, + Color.White * transparency, 0, Vector2.Zero, Vector2.One, + (x == 0 ? SpriteEffects.FlipHorizontally : SpriteEffects.None) | + (y == 0 ? SpriteEffects.FlipVertically : SpriteEffects.None), 0); + } + } + + { + var time = (float)((Game1.TotalGameTime + speed / 2) % speed); + var state = MathF.Sin((time / speed) * MathF.PI * 0.475f); + var distance = 40 - 34 * state; + var transparency = MathHelper.Clamp(time / fadeTime, 0, 1) * + MathHelper.Clamp((speed - time) / fadeTime, 0, 1); + var sourceRectangle = time < (speed / 1.65f) ? new Rectangle(176, 116, 16, 8) : new Rectangle(176, 100, 16, 8); + + for (var y = 0; y < 2; y++) + for (var x = 0; x < 2; x++) + { + var rotation = (float)((x * 2 + y) * Math.PI / 2); + + var position = new Vector2( + center.X + (y == 0 ? (x * 2 - 1) * distance : 0), + center.Y + (y == 0 ? 0 : (x * 2 - 1) * distance)); + + spriteBatch.Draw(Resources.SprItem, position, sourceRectangle, + Color.White * transparency, rotation, new Vector2(16, 4), Vector2.One, SpriteEffects.None, 0); + } + } + } + + private void DrawFinalInstruments(SpriteBatch spriteBatch) + { + if (_finalIndex != 1) + return; + + var percentage = 0.25f + Math.Clamp((float)(2500 - _finalSeqCounter) / 2000, 0, 1) * 0.75f; + + // draw the instruments + for (var i = 0; i < 8; i++) + { + var itemInstrument = Game1.GameManager.ItemManager["instrument" + i]; + var position = new Vector2(EntityPosition.X - 8, EntityPosition.Y - 60) + _showInstrumentOffset[i] * percentage; + ItemDrawHelper.DrawItem(spriteBatch, itemInstrument, position, Color.White, 1, true); + } + } + + private void DrawLink(SpriteBatch spriteBatch) + { + _sprite.Draw(spriteBatch); + + // draw the colored cloak + var texture = _sprite.SprTexture; + + var cloakColor = Game1.GameManager.CloakColor; + if (CurrentState == State.CloakShow0 && ShowItem != null && ShowItem.Name == "cloakBlue") + cloakColor = Color.Lerp(cloakColor, ItemDrawHelper.CloakColors[1], _cloakPercentage); + else if (CurrentState == State.CloakShow0 && ShowItem != null && ShowItem.Name == "cloakRed") + cloakColor = Color.Lerp(cloakColor, ItemDrawHelper.CloakColors[2], _cloakPercentage); + + _sprite.Color = cloakColor * _spriteTransparency; + _sprite.SprTexture = Resources.SprLinkCloak; + _sprite.Draw(spriteBatch); + + _sprite.Color = Color.White * _spriteTransparency; + _sprite.SprTexture = texture; + } + + private void DrawNote(SpriteBatch spriteBatch, Vector2 position, Vector2 direction, int noteIndex) + { + var timeOffset = noteIndex * _instrumentCycleTime / 2; + + if (_instrumentCounter < timeOffset || + (CurrentState != State.ShowInstrumentPart1 || _drawInstrumentEffect) && + ((_instrumentCounter - timeOffset) / _instrumentCycleTime + 1) * _instrumentCycleTime + timeOffset > _instrumentEndTime) + return; + + var time = (_instrumentCounter + timeOffset) % _instrumentCycleTime; + + var transparency = 1.0f; + // fade out + if (time > _instrumentCycleTime - 100) + { + _noteInit[noteIndex] = false; + transparency = (_instrumentCycleTime - time) / 100f; + } + // fade in + else if (time < 100) + { + if (!_noteInit[noteIndex]) + { + _noteInit[noteIndex] = true; + _noteSpriteIndex[noteIndex] = Game1.RandomNumber.Next(0, 2); + + } + transparency = time / 100; + } + + position += direction * time * 0.02f + new Vector2(-direction.X, direction.Y) * (float)Math.Sin(time * 0.015) * 0.75f; + position += new Vector2( + -_noteSourceRectangles[_noteSpriteIndex[noteIndex]].Width / 2f, + -_noteSourceRectangles[_noteSpriteIndex[noteIndex]].Height); + + spriteBatch.Draw(Resources.SprItem, position, + _noteSourceRectangles[_noteSpriteIndex[noteIndex]], Color.White * transparency); + } + + private void DrawSwordParticle(SpriteBatch spriteBatch, Vector2 position, Vector2 direction, int timeOffset, int fullTime, int timeDelay, int index) + { + var fadeTime = 50; + var particleTime = (_showSwordL2ParticleCounter + timeOffset) % (fullTime + timeDelay); + var percentage = particleTime / fullTime; + var colorTransparency = Math.Min((fullTime - particleTime) / fadeTime, particleTime / fadeTime); + var particlePosition = position + percentage * direction; + var spriteParticle = Resources.GetSprite("sword_particle_" + index); + + if (0 < particleTime && particleTime < fullTime) + DrawHelper.DrawNormalized(spriteBatch, spriteParticle.Texture, + particlePosition - spriteParticle.Origin, spriteParticle.ScaledRectangle, Color.White * colorTransparency, spriteParticle.Scale); + } + + private void DrawLight(SpriteBatch spriteBatch) + { + DrawHelper.DrawLight(spriteBatch, new Rectangle((int)EntityPosition.X - 45, (int)EntityPosition.Y - 45, 90, 90), new Color(255, 255, 255) * 0.125f); + } + + public void DrawTransition(SpriteBatch spriteBatch) + { + if (!IsVisible) + return; + + _bodyDrawFunction(spriteBatch); + + if (_drawInstrumentEffect) + DrawInstrumentEffect(spriteBatch); + + // draw the shown item + if (ShowItem != null) + { + var itemPosition = EntityPosition.Position + _showItemOffset; + ItemDrawHelper.DrawItem(spriteBatch, ShowItem, itemPosition, Color.White, 1, true); + } + } + + #endregion + + private void OnKeyChange() + { + var strCloak = "cloak_transition"; + var cloakTransition = Game1.GameManager.SaveManager.GetString(strCloak); + if (cloakTransition == "1") + { + _cloakTransitionCounter = 0; + _cloakPercentage = 0; + _cloakTransitionOutCounter = 0; + + Game1.GameManager.SaveManager.RemoveString(strCloak); + Game1.GameManager.SaveManager.SetString(strCloak, "0"); + + CurrentState = State.CloakShow0; + } + + // play animation? + var strAnimation = "link_direction"; + var newDirection = Game1.GameManager.SaveManager.GetString(strAnimation); + if (!string.IsNullOrEmpty(newDirection)) + { + Direction = int.Parse(newDirection); + UpdateAnimation(); + Game1.GameManager.SaveManager.SetString(strAnimation, null); + } + + // start moving? [set:link_move,-16,32] + var moveValue = Game1.GameManager.SaveManager.GetString("link_move"); + if (!string.IsNullOrEmpty(moveValue)) + { + var split = moveValue.Split(','); + var directionX = float.Parse(split[0], CultureInfo.InvariantCulture); + var directionY = float.Parse(split[1], CultureInfo.InvariantCulture); + + var velocity = new Vector2(directionX, directionY); + _body.VelocityTarget = velocity; + Direction = AnimationHelper.GetDirection(velocity); + _isWalking = true; + + Game1.GameManager.SaveManager.SetString("link_move_collision", "0"); + Game1.GameManager.SaveManager.RemoveString("link_move"); + } + + var idleValue = Game1.GameManager.SaveManager.GetString("link_idle"); + if (!string.IsNullOrEmpty(idleValue)) + { + CurrentState = State.Idle; + Game1.GameManager.SaveManager.RemoveString("link_idle"); + } + + var hideHudValue = Game1.GameManager.SaveManager.GetString("hide_hud"); + if (!string.IsNullOrEmpty(hideHudValue)) + { + Game1.GameManager.InGameOverlay.HideHud(true); + Game1.GameManager.SaveManager.RemoveString("hide_hud"); + } + + // start moving? [set:link_push,-16,0,200] + var pushValue = Game1.GameManager.SaveManager.GetString("link_push"); + if (!string.IsNullOrEmpty(pushValue)) + { + var split = pushValue.Split(','); + + // init movement + if (split.Length == 1) + { + _pushStart = EntityPosition.Position; + _pushEnd = new Vector2(80, 94); + _pushTime = int.Parse(split[0]); + } + else + { + var offsetX = float.Parse(split[0], CultureInfo.InvariantCulture); + var offsetY = float.Parse(split[1], CultureInfo.InvariantCulture); + _pushStart = EntityPosition.Position; + _pushEnd = _pushStart + new Vector2(offsetX, offsetY); + _pushTime = int.Parse(split[2]); + } + + _pushCounter = 0; + CurrentState = State.Pushed; + + Game1.GameManager.SaveManager.RemoveString("link_push"); + } + + // link animation + var animationValue = Game1.GameManager.SaveManager.GetString("link_animation"); + if (!string.IsNullOrEmpty(animationValue)) + { + Animation.Play(animationValue); + CurrentState = State.Sequence; + Game1.GameManager.SaveManager.RemoveString("link_animation"); + } + + var linkFinal = Game1.GameManager.SaveManager.GetString("link_final"); + if (!string.IsNullOrEmpty(linkFinal)) + { + _finalIndex = 0; + _finalSeqCounter = 1500; + Animation.Play("final_stand_down"); + CurrentState = State.FinalInstruments; + Game1.GameManager.SetMusic(62, 2); + Game1.GameManager.SaveManager.RemoveString("link_final"); + } + + // start diving? + var diveValue = Game1.GameManager.SaveManager.GetString("link_dive"); + if (!string.IsNullOrEmpty(diveValue)) + { + _diveCounter = int.Parse(diveValue); + CurrentState = State.Swimming; + Game1.GameManager.SaveManager.RemoveString("link_dive"); + } + + // boomerang trading + // can be exchanged for: shovel, feather + var boomerangValue = Game1.GameManager.SaveManager.GetString("boomerang_trade"); + if (!string.IsNullOrEmpty(boomerangValue)) + { + Game1.GameManager.SaveManager.RemoveString("boomerang_trade"); + + if (Game1.GameManager.Equipment[1] != null && + (Game1.GameManager.Equipment[1].Name == "shovel" || + Game1.GameManager.Equipment[1].Name == "feather" || + Game1.GameManager.Equipment[1].Name == "magicRod" || + Game1.GameManager.Equipment[1].Name == "hookshot")) + { + Game1.GameManager.SaveManager.SetString("tradded_item", Game1.GameManager.Equipment[1].Name); + Game1.GameManager.Equipment[1] = null; + + Game1.GameManager.StartDialogPath("npc_hidden_boomerang"); + } + else + { + Game1.GameManager.StartDialogPath("npc_hidden_reject"); + } + } + + var boomerangReturnValue = Game1.GameManager.SaveManager.GetString("boomerang_trade_return"); + if (!string.IsNullOrEmpty(boomerangReturnValue)) + { + Game1.GameManager.SaveManager.RemoveString("boomerang_trade_return"); + + // remove the boomerang + Game1.GameManager.RemoveItem("boomerang", 1); + + // return the traded item + var tradedItem = Game1.GameManager.SaveManager.GetString("tradded_item"); + var item = new GameItemCollected(tradedItem); + MapManager.ObjLink.PickUpItem(item, true); + _pickupDialogOverride = "npc_hidden_4"; + } + + var spawnGhostValue = Game1.GameManager.SaveManager.GetString(_spawnGhostKey); + if (!string.IsNullOrEmpty(spawnGhostValue)) + { + _spawnGhost = true; + } + } + + private void OnMoveCollision(Values.BodyCollision collision) + { + // knockback + if (CurrentState == State.Idle && _wasBootsRunning) + { + var knockBack = false; + + if ((collision & Values.BodyCollision.Horizontal) != 0 && Direction % 2 == 0) + { + var dirX = (collision & Values.BodyCollision.Left) != 0 ? -1 : 1; + _body.Velocity.X = -dirX; + Game1.GameManager.ShakeScreen(750, 2, 1, 5.5f, 2.5f, dirX, 1); + knockBack = true; + } + if ((collision & Values.BodyCollision.Vertical) != 0 && Direction % 2 != 0) + { + var dirY = (collision & Values.BodyCollision.Top) != 0 ? -1 : 1; + _body.Velocity.Y = -dirY; + Game1.GameManager.ShakeScreen(750, 1, 2, 2.5f, 5.5f, 1, dirY); + knockBack = true; + } + + if (knockBack) + { + _bootsRunning = false; + _bootsCounter = 0; + + _body.Velocity.Z = 2.0f; + CurrentState = State.BootKnockback; + + var damageOrigin = BodyRectangle.Center; + var damageBox = _body.BodyBox.Box; + damageBox.X += AnimationHelper.DirectionOffset[Direction].X; + damageBox.Y += AnimationHelper.DirectionOffset[Direction].Y; + + Game1.GameManager.PlaySoundEffect("D360-11-0B"); + + Map.Objects.Hit(this, damageOrigin, damageBox, HitType.PegasusBootsPush, 0, false); + } + } + + // what is this? + if ((collision & Values.BodyCollision.Floor) != 0) + { + _moveVelocity = _lastMoveVelocity * 0.5f; + _lastBaseMoveVelocity = _moveVelocity; + } + + if (CurrentState == State.BootKnockback && + (collision & Values.BodyCollision.Floor) != 0) + { + CurrentState = State.Idle; + _body.Velocity.Z = 0; + } + + if (Is2DMode) + OnMoveCollision2D(collision); + else + { + // colliding horizontally or vertically? -> start pushing + if (CurrentState == State.Idle && _isWalking && ( + (collision & Values.BodyCollision.Horizontal) != 0 && (Direction == 0 || Direction == 2) || + (collision & Values.BodyCollision.Vertical) != 0 && (Direction == 1 || Direction == 3))) + { + var box = _body.BodyBox.Box; + // offset by one in the walk direction + box.X += AnimationHelper.DirectionOffset[Direction].X; + box.Y += AnimationHelper.DirectionOffset[Direction].Y; + var cBox = Box.Empty; + var outBox = Box.Empty; + // check if the object we are walking into is actually an object where the push animation should be played + if (Map.Objects.Collision(box, cBox, _body.CollisionTypes, Values.CollisionTypes.PushIgnore, Direction, _body.Level, ref outBox)) + CurrentState = State.Pushing; + } + + if (CurrentState == State.Swimming) + { + if ((collision & Values.BodyCollision.Horizontal) != 0) + _moveVelocity.X = 0; + if ((collision & Values.BodyCollision.Vertical) != 0) + _moveVelocity.Y = 0; + } + + // used for scripting (final stript stop at the top of the stairs) + Game1.GameManager.SaveManager.SetString("link_move_collision", "1"); + + // stop the hit velocity if the are colliding with a wall + // this was done because the player pushes into the hitVelocity direction + if ((collision & Values.BodyCollision.Horizontal) != 0 && _body.VelocityTarget.X == 0) + _hitVelocity.X = 0; + if ((collision & Values.BodyCollision.Vertical) != 0 && _body.VelocityTarget.Y == 0) + _hitVelocity.Y = 0; + + if (CurrentState == State.Charging && + ((collision & Values.BodyCollision.Left) != 0 && Direction == 0 || + (collision & Values.BodyCollision.Top) != 0 && Direction == 1 || + (collision & Values.BodyCollision.Right) != 0 && Direction == 2 || + (collision & Values.BodyCollision.Bottom) != 0 && Direction == 3)) + { + if (_swordPokeCounter <= 0) + { + IsPoking = true; + _pokeStart = true; + + Animation.Play("poke_" + Direction); + AnimatorWeapons.Play("poke_" + Direction); + CurrentState = State.Attacking; + _swordChargeCounter = SwordChargeTime; + } + + _swordPokeCounter -= Game1.DeltaTime; + } + } + } + + private void OnHolePull(Vector2 direction, float percentage) + { + // disable jumping if the player stands on top of a hole + // if the hole is 14x14 the player should not be able to stand between the holes and jump out of them + // player 8x10 + // hole area while standing between 4 14x14 holes: 2x10 + 2x8 = 36 + // 1 - 36/80 = 0.55 + if (percentage >= 0.55f) + _canJump = false; + } + + private void Update3D() + { + _isWalking = false; + WasHoleReset = false; + + if (CurrentState == State.Intro) + { + var walkVelocity = ControlHandler.GetMoveVector2(); + + if (Animation.CurrentAnimation.Id == "intro_sit" && + !Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen && walkVelocity.Length() > Values.ControllerDeadzone) + { + CurrentState = State.Idle; + Direction = 2; + StartRailJump(EntityPosition.Position + new Vector2(12, 4), 1, 1); + Animation.Play("intro_jump"); + + Game1.GameManager.SaveManager.SetString("played_intro", "1"); + } + + return; + } + + // finished jumping into the bed? + if (_startBedTransition && CurrentState == State.Idle) + { + CurrentState = State.BedTransition; + + _startBedTransition = false; + + Animation.Play("bed"); + } + + if (CurrentState == State.BedTransition) + return; + + if (CurrentState == State.SwordShow0) + { + if (!Animation.IsPlaying) + { + Animation.Play("show2"); + _showSwordLv2Counter = 500; + CurrentState = State.SwordShow1; + + Game1.GameManager.PlaySoundEffect("D360-07-07"); + + var animation = new ObjAnimator(Map, 0, 0, Values.LayerTop, "Particles/swordPoke", "run", true); + animation.EntityPosition.Set(new Vector2( + BodyRectangle.X, + EntityPosition.Y - EntityPosition.Z - 30)); + Map.Objects.SpawnObject(animation); + } + else + return; + } + else if (CurrentState == State.SwordShow1) + { + _showSwordLv2Counter -= Game1.DeltaTime; + if (_showSwordLv2Counter < 0) + CurrentState = State.Idle; + } + + if (_isRafting && (CurrentState == State.Rafting || CurrentState == State.Charging)) + { + var moveVelocity = ControlHandler.GetMoveVector2(); + + var moveVelocityLength = moveVelocity.Length(); + if (moveVelocityLength > 1) + moveVelocity.Normalize(); + + if (moveVelocityLength > Values.ControllerDeadzone) + { + _isWalking = true; + _objRaft.TargetVelocity(moveVelocity * 0.5f); + + if (CurrentState != State.Charging) + { + var vectorDirection = ToDirection(moveVelocity); + Direction = vectorDirection; + } + } + } + + if (_isFlying && CurrentState == State.Carrying) + { + var moveVelocity = ControlHandler.GetMoveVector2(); + + var moveVelocityLength = moveVelocity.Length(); + if (moveVelocityLength > 1) + moveVelocity.Normalize(); + + if (moveVelocityLength > Values.ControllerDeadzone) + { + _objRooster.TargetVelocity(moveVelocity, 0.5f, Direction); + + var vectorDirection = ToDirection(moveVelocity); + Direction = vectorDirection; + } + } + + // we need to prevent overlays from being opened because they do not stop the music and it would run out of sync + if ((ShowItem != null && ShowItem.Name.StartsWith("instrument")) || + CurrentState == State.ShowInstrumentPart0 || + CurrentState == State.ShowInstrumentPart1 || + CurrentState == State.ShowInstrumentPart2 || + CurrentState == State.ShowInstrumentPart3) + Game1.GameManager.InGameOverlay.DisableInventoryToggle = true; + + if (CurrentState == State.ShowInstrumentPart0) + { + // is the sound effect still playing? + if (_instrumentPickupTime + 7500 < Game1.TotalGameTime) + { + Game1.GameManager.SetMusic(_instrumentMusicIndex[_instrumentIndex], 2); + Game1.GbsPlayer.Play(); + Game1.GbsPlayer.SoundGenerator.SetStopTime(8); + CurrentState = State.ShowInstrumentPart1; + } + } + else if (CurrentState == State.ShowInstrumentPart1) + { + _instrumentCounter += Game1.DeltaTime; + + if (_instrumentCounter > 3500) + { + _drawInstrumentEffect = true; + Game1.GameManager.PlaySoundEffect("D360-43-2B", false); + } + + if (Game1.GbsPlayer.SoundGenerator.WasStopped && Game1.GbsPlayer.SoundGenerator.FinishedPlaying()) + { + Game1.GameManager.SetMusic(-1, 0); + Game1.GameManager.SetMusic(-1, 2); + Game1.GameManager.PlaySoundEffect("D378-44-2C"); + + _instrumentCounter = 0; + CurrentState = State.ShowInstrumentPart2; + } + } + else if (CurrentState == State.ShowInstrumentPart2) + { + _instrumentCounter += Game1.DeltaTime; + + var transitionSystem = (MapTransitionSystem)Game1.GameManager.GameSystems[typeof(MapTransitionSystem)]; + transitionSystem.SetColorMode(Color.White, MathHelper.Clamp(_instrumentCounter / 500f, 0, 1)); + + if (_instrumentCounter > 2500) + { + Direction = 3; + UpdateAnimation(); + + CurrentState = State.ShowInstrumentPart3; + ShowItem = null; + _drawInstrumentEffect = false; + + Game1.GameManager.StartDialogPath($"instrument{_instrumentIndex}Collected"); + } + } + else if (CurrentState == State.ShowInstrumentPart3) + { + MapTransitionStart = EntityPosition.Position; + MapTransitionEnd = MapTransitionStart; + TransitionOutWalking = false; + + EndPickup(); + + // append a map change + ((MapTransitionSystem)Game1.GameManager.GameSystems[typeof(MapTransitionSystem)]).AppendMapChange( + "overworld.map", $"d{_instrumentIndex + 1}Finished", false, true, Color.White, true); + } + + if (CurrentState == State.Teleporting) + { + if (_teleportCounterFull < 1250 || Direction <= 2) + _teleportCounter += Game1.DeltaTime; + + _teleportCounterFull += Game1.DeltaTime; + var rotationSpeed = 150 - (float)Math.Sin((_teleportCounterFull / 2000f) * Math.PI) * 50; + if (_teleportCounter > rotationSpeed) + { + _teleportCounter -= rotationSpeed; + Direction = (Direction + 1) % 4; + UpdateAnimation(); + } + + var transitionSystem = (MapTransitionSystem)Game1.GameManager.GameSystems[typeof(MapTransitionSystem)]; + + if (_teleportState == 0 && _teleportCounterFull >= 1250) + { + if (_teleporter != null) + { + _teleportState = 1; + + EntityPosition.Set(_teleporter.TeleportPosition); + _teleporter.Lock(); + + var goalPosition = Game1.GameManager.MapManager.GetCameraTarget(); + MapManager.Camera.SoftUpdate(goalPosition); + } + else if (Direction == 3 && _teleportCounterFull >= 1450) + { + MapTransitionStart = EntityPosition.Position; + MapTransitionEnd = EntityPosition.Position; + TransitionOutWalking = false; + + transitionSystem.AppendMapChange(_teleportMap, _teleporterId, false, true, Color.White, true); + } + + transitionSystem.SetColorMode(Color.White, 1); + } + + var fadeOutTime = 250.0f; + var fadeoutStart = 1750; + var fadeoutEnd = 1750 + fadeOutTime; + + // fading in + if (_teleportCounterFull >= 750 && _teleportCounterFull < 1250) + { + transitionSystem.SetColorMode(Color.White, (_teleportCounterFull - 750) / 500f); + } + // fading out + else if (_teleportState == 1 && _teleportCounterFull >= fadeoutStart && _teleportCounterFull < fadeoutEnd) + { + transitionSystem.SetColorMode(Color.White, 1 - (_teleportCounterFull - fadeoutStart) / fadeOutTime); + } + // finished? + else if (_teleportState == 1 && _teleportCounterFull >= fadeoutEnd) + { + _drawBody.Layer = Values.LayerPlayer; + transitionSystem.SetColorMode(Color.White, 0); + CurrentState = State.Idle; + } + } + + UpdateSwimming(); + + UpdateIgnoresZ(); + + // hinox should throw the player farther than normal + if (CurrentState == State.Stunned) + _body.DragAir = 0.95f; + else + _body.DragAir = 0.9f; + + // save the last position the player is grounded to use for the reset position if the player drowns + if (CurrentState != State.Jumping && CurrentState != State.Drowning && CurrentState != State.Drowned && _body.IsGrounded) + { + var bodyCenter = new Vector2(EntityPosition.X, EntityPosition.Y - _body.Height / 2f); + // center the position + // can lead to the position being inside something + bodyCenter.X = (int)(bodyCenter.X / 16) * 16 + 8; + bodyCenter.Y = (int)(bodyCenter.Y / 16) * 16 + 8 + _body.Height / 2f; + + // found new reset position? + if (!Map.GetFieldState(bodyCenter).HasFlag(MapStates.FieldStates.DeepWater)) + { + var bodyBox = new Box( + bodyCenter.X + _body.OffsetX, + bodyCenter.Y + _body.OffsetY, 0, _body.Width, _body.Height, _body.Depth); + var cBox = Box.Empty; + + // check it the player is not standing inside something + if (!Map.Objects.Collision(bodyBox, Box.Empty, _body.CollisionTypes | Values.CollisionTypes.DrownExclude, 0, 0, ref cBox)) + _drownResetPosition = bodyCenter; + } + } + + // walk + UpdateWalking(); + + if (CurrentState == State.Drowning) + { + if (_drownCounter < 300) + { + _body.Velocity = Vector3.Zero; + // align the player to the pixel grid + EntityPosition.Set(new Vector2( + MathF.Round(EntityPosition.X), MathF.Round(EntityPosition.Y))); + } + + _drownCounter -= Game1.DeltaTime; + if (_drownCounter <= 0) + { + IsVisible = false; + CurrentState = State.Drowned; + _drownResetCounter = 500; + } + } + + if (CurrentState == State.Drowned) + { + _drownResetCounter -= Game1.DeltaTime; + if (_drownResetCounter <= 0) + { + CurrentState = State.Idle; + CanWalk = true; + IsVisible = true; + + _hitCount = CooldownTime; + Game1.GameManager.CurrentHealth -= 2; + + _body.CurrentFieldState = MapStates.FieldStates.None; + EntityPosition.Set(_drownResetPosition); + } + } + + if (CurrentState == State.Swimming) + { + if (_diveCounter > -100) + { + _diveCounter -= Game1.DeltaTime; + + // stop diving + if (ControlHandler.ButtonPressed(CButtons.B)) + _diveCounter = 0; + } + // start diving + else if (ControlHandler.ButtonPressed(CButtons.B)) + { + StartDiving(1500); + } + + if (_swimBoostCount > -300) + _swimBoostCount -= Game1.DeltaTime; + else if (ControlHandler.ButtonPressed(CButtons.A)) + _swimBoostCount = 300; + + if (_swimBoostCount > 0) + _moveVelocity *= SwimSpeedA; + else + _moveVelocity *= SwimSpeed; + + var distance = _moveVelocity - _swimVelocity; + var length = distance.Length(); + if (distance != Vector2.Zero) + distance.Normalize(); + + if (length < 0.045f) + _swimVelocity = _moveVelocity; + else + _swimVelocity += distance * (_swimBoostCount > 0 ? 0.06f : 0.045f) * Game1.TimeMultiplier; + + _moveVelocity = _swimVelocity; + } + + // slows down the walk movement when the player is hit + var moveMultiplier = MathHelper.Clamp(1f - _hitVelocity.Length(), 0, 1); + + // move the player + if (CurrentState != State.Hookshot) + { + _body.VelocityTarget = _moveVelocity * moveMultiplier + _hitVelocity; + } + + LastMoveVector = _moveVelocity; + _moveVelocity = Vector2.Zero; + + if (_hitCount > 0 && _hitVelocity.Length() > 0.05f * Game1.TimeMultiplier) + { + var hitNormal = _hitVelocity; + hitNormal.Normalize(); + + var slowDownAmount = 0.05f + MathHelper.Clamp(_hitVelocity.Length() / 25f, 0, 0.05f); + + _hitVelocity -= hitNormal * slowDownAmount * Game1.TimeMultiplier; + } + else + _hitVelocity = Vector2.Zero; + + // update the jump logic + UpdateJump(); + + // hole falling logic + { + // update position used to reset the player if he falls into a hole + UpdateSavePosition(); + + // change the room? + if (_isFallingIntoHole) + { + _holeFallCounter -= Game1.DeltaTime; + + if (_holeFallCounter <= 0) + { + _isFallingIntoHole = false; + + if (HoleResetRoom != null) + { + // append a map change + ((MapTransitionSystem)Game1.GameManager.GameSystems[ + typeof(MapTransitionSystem)]).AppendMapChange(HoleResetRoom, HoleResetEntryId); + } + // teleport on hole fall? + else if (HoleTeleporterId >= 0) + { + _holeTeleportCounter = 0; + CurrentState = State.TeleporterUpWait; + } + } + } + + HoleTeleporterId = -1; + + // finished falling down the hole? + if (CurrentState == State.Falling && !Animation.IsPlaying) + OnHoleReset(); + } + + // update links animation + UpdateAnimation(); + + UpdateGhostSpawn(); + + // stop push animation + if (CurrentState == State.Pushing) + CurrentState = State.Idle; + + _lastFieldState = _body.CurrentFieldState; + } + + private void UpdateSwimming() + { + // we cant use the field state of the body because the raft updates the state while exiting + var fieldState = SystemBody.GetFieldState(_body); + + // start/stop swimming or drowning + if (!_isRafting && !_isFlying && fieldState.HasFlag(MapStates.FieldStates.DeepWater) && CurrentState != State.Dying) + { + if (CurrentState != State.Jumping && _body.IsGrounded && CurrentState != State.PickingUp) + { + ReleaseCarriedObject(); + var inLava = fieldState.HasFlag(MapStates.FieldStates.Lava); + + if ((HasFlippers && !inLava) && CurrentState != State.Swimming) + { + CurrentState = State.Swimming; + + // only push the player if he walks into the water and does not jump + if (!_lastFieldState.HasFlag(fieldState)) + _body.Velocity = new Vector3(_body.VelocityTarget.X, _body.VelocityTarget.Y, 0) * 0.75f; + + // splash effect + var splashAnimator = new ObjAnimator(Map, 0, 0, 0, 3, Values.LayerPlayer, "Particles/splash", "idle", true); + splashAnimator.EntityPosition.Set(new Vector2( + _body.Position.X + _body.OffsetX + _body.Width / 2f, + _body.Position.Y + _body.OffsetY + _body.Height - _body.Position.Z - 6)); + Map.Objects.SpawnObject(splashAnimator); + + Game1.GameManager.PlaySoundEffect("D360-14-0E"); + + _diveCounter = 0; + _swimBoostCount = 0; + _swimVelocity = Vector2.Zero; + } + else if (!HasFlippers || inLava) + { + if (CurrentState != State.Drowning && CurrentState != State.Drowned) + { + // only push the player if he walks into the water and does not jump + if (!_lastFieldState.HasFlag(fieldState)) + _body.Velocity = new Vector3(_body.VelocityTarget.X, _body.VelocityTarget.Y, 0) * 0.5f; + + // splash effect + var splashAnimator = new ObjAnimator(Map, 0, 0, 0, 3, Values.LayerPlayer, "Particles/splash", "idle", true); + splashAnimator.EntityPosition.Set(new Vector2( + _body.Position.X + _body.OffsetX + _body.Width / 2f, + _body.Position.Y + _body.OffsetY + _body.Height - _body.Position.Z - 6)); + Map.Objects.SpawnObject(splashAnimator); + + Game1.GameManager.PlaySoundEffect("D370-03-03"); + + CurrentState = State.Drowning; + _drownCounter = 650; + + // blink in lava + _hitCount = inLava ? CooldownTime : 0; + } + } + } + } + else if (CurrentState == State.Swimming && (!IsTransitioning || !Map.Is2dMap)) + CurrentState = State.Idle; + + if (CurrentState == State.Swimming) + { + EntityPosition.Z = 0; + _body.IsGrounded = true; + } + } + + private void UpdateIgnoresZ() + { + if (CurrentState == State.Swimming || + CurrentState == State.Hookshot || + CurrentState == State.TeleporterUp || + CurrentState == State.TeleportFallWait || _isFlying || _isGrabbed || _isClimbing) + _body.IgnoresZ = true; + else + _body.IgnoresZ = false; + } + + private void UpdateWalking() + { + if (CurrentState != State.Idle && (CurrentState != State.Carrying || _isFlying) && CurrentState != State.Charging && CurrentState != State.Swimming && + CurrentState != State.CarryingItem && (CurrentState != State.MagicRod || _body.IsGrounded) && (CurrentState != State.Jumping || _railJump) && + CurrentState != State.Pushing && CurrentState != State.Blocking && CurrentState != State.Attacking || + !CanWalk || _isRafting) return; + + var walkVelocity = Vector2.Zero; + if (!_isLocked && (CurrentState != State.Attacking || !_body.IsGrounded)) + walkVelocity = ControlHandler.GetMoveVector2(); + + var walkVelLength = walkVelocity.Length(); + if (walkVelLength > 1) + walkVelocity.Normalize(); + + var vectorDirection = ToDirection(walkVelocity); + + if (_bootsRunning && (walkVelLength < Values.ControllerDeadzone || vectorDirection != (Direction + 2) % 4)) + { + if (!_bootsStop) + { + _moveVelocity = AnimationHelper.DirectionOffset[Direction] * BootsRunningSpeed; + + // can move up or down while running + if (Direction % 2 != 0) + _moveVelocity.X += walkVelocity.X; + else if (Direction % 2 == 0) + _moveVelocity.Y += walkVelocity.Y; + } + } + else if (walkVelLength > Values.ControllerDeadzone) + { + _bootsCounter %= _bootsParticleTime; + _bootsRunning = false; + +#if DEBUG + if (InputHandler.KeyDown(Keys.LeftShift)) + walkVelocity *= 0.25f; +#endif + + // slow down in the grass + if (_body.CurrentFieldState.HasFlag(MapStates.FieldStates.Grass) && _body.IsGrounded) + _currentWalkSpeed *= 0.8f; + + // slow down in the water + if (_body.CurrentFieldState.HasFlag(MapStates.FieldStates.Water) && _body.IsGrounded) + { + _currentWalkSpeed *= 0.8f; + + _waterSoundCounter += Game1.DeltaTime; + if (_waterSoundCounter > 250) + { + _waterSoundCounter -= 250; + Game1.GameManager.PlaySoundEffect("D360-14-0E", false); + } + } + + // do not walk when trapped + if (!_isTrapped) + { + _isWalking = true; + + if (_body.IsGrounded) + { + // after hitting the ground we still have _lastMoveVelocity + if (!_body.WasGrounded) + _moveVelocity = Vector2.Zero; + + _moveVelocity += walkVelocity * _currentWalkSpeed; + } + } + + // update the direction the player is facing + if (CurrentState != State.Attacking && CurrentState != State.Charging) + Direction = vectorDirection; + } + + _lastBaseMoveVelocity = _moveVelocity; + + // when we walk of a cliff set the air move vector + // we need to make sure that the player did not started jumping + if (!_startedJumping && !_hasStartedJumping && _body.WasGrounded && !_body.IsGrounded) + _lastMoveVelocity = _moveVelocity; + + // the player has momentum when he is in the air and can not be controlled directly like on the ground + if (!_body.IsGrounded || _body.Velocity.Z > 0) + { + var distance = (_lastMoveVelocity - walkVelocity * _currentWalkSpeed).Length(); + + // trying to move in the air? => slowly change the direction in the air + if (distance > 0 && walkVelocity != Vector2.Zero) + { + var amount = Math.Clamp((0.05f / distance) * Game1.TimeMultiplier, 0, 1); + _lastMoveVelocity = Vector2.Lerp(_lastMoveVelocity, walkVelocity * _currentWalkSpeed, amount); + } + + _moveVelocity = _lastMoveVelocity; + } + } + + private void UpdateAnimation() + { + if (Game1.GameManager.UseShockEffect) + return; + + var shieldString = Game1.GameManager.ShieldLevel == 2 ? "ms_" : "s_"; + if (!CarryShield) + shieldString = "_"; + + if (_bootsHolding || _bootsRunning) + { + if (!_bootsRunning) + Animation.Play("walk" + shieldString + Direction); + else + { + // run while blocking with the shield + Animation.Play((CarryShield ? "walkb" : "walk") + shieldString + Direction); + } + + Animation.SpeedMultiplier = 2.0f; + return; + } + + Animation.SpeedMultiplier = 1.0f; + + if (CurrentState == State.Idle && !_isWalking || + CurrentState == State.Charging && !_isWalking || + CurrentState == State.Rafting && !_isWalking || + CurrentState == State.Teleporting || + CurrentState == State.ShowInstrumentPart3 || + CurrentState == State.TeleportFall || + CurrentState == State.TeleporterUp || + CurrentState == State.FallRotateEntry) + Animation.Play("stand" + shieldString + Direction); + else if (( + CurrentState == State.Idle || + CurrentState == State.Charging || + CurrentState == State.Rafting) && _isWalking) + Animation.Play("walk" + shieldString + Direction); + else if (CurrentState == State.Blocking) + Animation.Play((!_isWalking ? "standb" : "walkb") + shieldString + Direction); + else if ((CurrentState == State.Carrying || CurrentState == State.CarryingItem) && !_isFlying) + Animation.Play((!_isWalking ? "standc_" : "walkc_") + Direction); + else if (CurrentState == State.Carrying && _isFlying) + Animation.Play("flying_" + Direction); + else if (CurrentState == State.Pushing) + Animation.Play("push_" + Direction); + else if (CurrentState == State.Grabbing) + Animation.Play("grab_" + Direction); + else if (CurrentState == State.Pulling) + Animation.Play("pull_" + Direction); + else if (CurrentState == State.Swimming) + { + Animation.Play(_diveCounter > 0 ? "dive" : "swim_" + Direction); + + if (_swimVelocity.Length() < 0.1 && !IsTransitioning) + Animation.IsPlaying = false; + } + else if (CurrentState == State.Drowning) + Animation.Play(_drownCounter > 300 ? "swim_" + Direction : "dive"); + } + + private void UpdateHeartWarningSound() + { + if (Game1.GameManager.CurrentHealth <= 4) + { + + } + + } + + private void UpdateDive() + { + _diveCounter -= Game1.DeltaTime; + } + + private void UpdateDamageShader() + { + if (_hitCount > 0) + _sprite.SpriteShader = (CooldownTime - _hitCount) % (BlinkTime * 2) < BlinkTime ? Resources.DamageSpriteShader0 : null; + else + _sprite.SpriteShader = null; + } + + private void UpdateSavePosition() + { + var bodyCenter = _body.BodyBox.Box.Center; + var currentTilePosition = new Point(((int)bodyCenter.X - Map.MapOffsetX * 16) / 160, ((int)bodyCenter.Y - Map.MapOffsetY * 16) / 128); + var tileDiff = currentTilePosition - _lastTilePosition; + var newResetPosition = _holeResetPoint; + _lastTilePosition = currentTilePosition; + + // update position? + if (tileDiff != Point.Zero) + { + var tileSize = 16; + _alternativeHoleResetPosition = Vector2.Zero; + + if (tileDiff.X == 0) + newResetPosition.X = EntityPosition.X; + else + { + if (tileDiff.X > 0) + newResetPosition.X = (int)(bodyCenter.X / tileSize) * tileSize; + else + newResetPosition.X = (int)(bodyCenter.X / tileSize + 1) * tileSize; + } + + if (tileDiff.Y == 0) + newResetPosition.Y = EntityPosition.Y; + else + { + if (tileDiff.Y > 0) + newResetPosition.Y = (int)(bodyCenter.Y / tileSize) * tileSize; + else + newResetPosition.Y = (int)(bodyCenter.Y / tileSize + 1) * tileSize; + } + + // check if there is no hole at the new position + var bodyBox = new Box(newResetPosition.X + _body.BodyBox.OffsetX, newResetPosition.Y + _body.BodyBox.OffsetY, 0, _body.Width, _body.Height, 8); + var outBox = Box.Empty; + if (!Map.Objects.Collision(bodyBox, Box.Empty, Values.CollisionTypes.Hole, 0, 0, ref outBox)) + _holeResetPoint = newResetPosition; + } + } + + public void UpdateSaveLocation() + { + MapManager.ObjLink.SaveMap = Map.MapName; + MapManager.ObjLink.SavePosition = EntityPosition.Position; + MapManager.ObjLink.SaveDirection = Direction; + } + + private void SetHoleResetPosition(Vector2 newResetPosition) + { + _holeResetPoint = newResetPosition; + + var offset = Map != null ? new Point(Map.MapOffsetX, Map.MapOffsetY) : Point.Zero; + _lastTilePosition = new Point(((int)newResetPosition.X - offset.X * 16) / 160, ((int)newResetPosition.Y - offset.Y * 16) / 128); + } + + private void UpdateDrawComponents() + { + if (_drawInstrumentEffect) + _drawBody.Layer = Values.LayerTop; + else + _drawBody.Layer = (CurrentState == State.Swimming && _diveCounter > 0) ? Values.LayerBottom : Values.LayerPlayer; + + if (CurrentState == State.Swimming && _diveCounter > 0 || + CurrentState == State.Drowning || + CurrentState == State.Drowned || + CurrentState == State.BedTransition || + _isTrapped) + _shadowComponent.IsActive = false; + else + _shadowComponent.IsActive = true; + } + + private void StartDiving(int diveTime) + { + // splash effect + var splashAnimator = new ObjAnimator(Map, 0, 0, 0, 0, Values.LayerTop, "Particles/splash", "idle", true); + splashAnimator.EntityPosition.Set(new Vector2( + _body.Position.X + _body.OffsetX + _body.Width / 2f, + _body.Position.Y + _body.OffsetY + _body.Height - _body.Position.Z - 3)); + Map.Objects.SpawnObject(splashAnimator); + + Game1.GameManager.PlaySoundEffect("D360-14-0E"); + + _diveCounter = diveTime; + } + + private void OnHoleReset() + { + // change the room? + if (HoleResetRoom != null) + return; + + _isFallingIntoHole = false; + + CurrentState = State.Idle; + CanWalk = true; + + _hitCount = CooldownTime; + Game1.GameManager.InflictDamage(2); + + MoveToHoleResetPosition(); + } + + private void MoveToHoleResetPosition() + { + WasHoleReset = true; + EntityPosition.Set(_holeResetPoint); + + // alternative reset point + var cBox = Box.Empty; + if (_alternativeHoleResetPosition != Vector2.Zero && + Map.Objects.Collision(_body.BodyBox.Box, Box.Empty, _body.CollisionTypes, 0, 0, ref cBox)) + { + EntityPosition.Set(_alternativeHoleResetPosition); + } + } + + private bool InteractWithObject() + { + var boxSize = 6; + var interactionBox = new Box( + EntityPosition.X + _walkDirection[Direction].X * (BodyRectangle.Width / 2 + boxSize / 2) - boxSize / 2, + BodyRectangle.Center.Y + _walkDirection[Direction].Y * (BodyRectangle.Height / 2 + boxSize / 2) - boxSize / 2, 0, + boxSize, boxSize, 16); + + return Map.Objects.InteractWithObject(interactionBox); + } + + private void ReturnToIdle() + { + // Return to idle or to rafting if that was the player was rafting before + if (_isRafting) + CurrentState = State.Rafting; + else + CurrentState = State.Idle; + } + + private void UpdateGhostSpawn() + { + if (!_spawnGhost || !Map.IsOverworld) + return; + + var dungeonEntryPosition = new Vector2(1840, 272); + var distance = MapManager.ObjLink.EntityPosition.Position - dungeonEntryPosition; + if (MathF.Abs(distance.X) > 512 || MathF.Abs(distance.Y) > 256) + { + _spawnGhost = false; + Game1.GameManager.SaveManager.RemoveString(_spawnGhostKey); + Game1.GameManager.CollectItem(new GameItemCollected("ghost") { Count = 1 }, 0); + UpdateFollower(false); + _objGhost.StartFollowing(); + } + } + + #region item stuff + + private void UpdateItem() + { + if (CurrentState == State.Blocking) + CurrentState = State.Idle; + else + _wasBlocking = false; + + if (CurrentState == State.Grabbing || CurrentState == State.Pulling) + CurrentState = State.Idle; + + _isPulling = false; + _isHoldingSword = false; + _bootsHolding = false; + + if (!_isLocked) + { + // interact with object + if ((CurrentState == State.Idle || CurrentState == State.Pushing || CurrentState == State.Swimming || CurrentState == State.CarryingItem) && + ControlHandler.ButtonPressed(CButtons.A) && InteractWithObject()) + InputHandler.ResetInputState(); + + if (_isTrapped && !_trappedDisableItems && + (ControlHandler.ButtonPressed(CButtons.A) || + ControlHandler.ButtonPressed(CButtons.B) || + ControlHandler.ButtonPressed(CButtons.X) || + ControlHandler.ButtonPressed(CButtons.Y))) + { + _trapInteractionCount--; + if (_trapInteractionCount <= 0) + FreeTrappedPlayer(); + } + + // use/hold item + if (!DisableItems && (!_isTrapped || !_trappedDisableItems)) + { + for (var i = 0; i < Values.HandItemSlots; i++) + { + if (Game1.GameManager.Equipment[i] != null && + ControlHandler.ButtonPressed((CButtons)((int)CButtons.A * Math.Pow(2, i)))) + UseItem(Game1.GameManager.Equipment[i]); + + if (Game1.GameManager.Equipment[i] != null && + ControlHandler.ButtonDown((CButtons)((int)CButtons.A * Math.Pow(2, i)))) + HoldItem(Game1.GameManager.Equipment[i], + ControlHandler.LastButtonDown((CButtons)((int)CButtons.A * Math.Pow(2, i)))); + } + } + } + + UpdatePegasusBoots(); + + // shield pushing + if (CurrentState == State.Blocking || _bootsRunning && CarryShield) + UpdateShieldPush(); + + // pick up animation + if (CurrentState == State.PreCarrying) + { + _preCarryCounter += Game1.DeltaTime; + + // change the animation of the player depending on where the picked up object is + if (_preCarryCounter > 100) + Animation.Play("standc_" + Direction); + + UpdatePositionCarriedObject(EntityPosition); + } + + // stop attacking + if (CurrentState == State.Attacking && !Animation.IsPlaying) + { + _isSwingingSword = false; + + if (!_isHoldingSword || _swordPoked || _stopCharging) + ReturnToIdle(); + else + { + // start charging sword + CurrentState = State.Charging; + AnimatorWeapons.Play("stand_" + Direction); + _swordPokeCounter = _swordPokeTime; + } + } + + if (CurrentState == State.Charging) + UpdateCharging(); + + // hit stuff with the sword + if (CurrentState == State.Attacking || _bootsRunning && CarrySword) + UpdateAttacking(); + + if (CurrentState == State.PickingUp) + UpdatePickup(); + + if (!Animation.IsPlaying && + (CurrentState == State.Powdering || CurrentState == State.Bombing || CurrentState == State.MagicRod || CurrentState == State.Throwing)) + ReturnToIdle(); + + if (CurrentState == State.Hookshot) + UpdateHookshot(); + + if (CurrentState == State.Digging) + UpdateDigging(); + + _wasPulling = _isPulling; + } + + private void UseItem(GameItemCollected item) + { + switch (item.Name) + { + case "sword1": + case "sword2": + UseSword(); + break; + case "feather": + UseFeather(); + break; + case "toadstool": + UseToadstool(); + break; + case "powder": + UsePowder(); + break; + case "bomb": + UseBomb(); + break; + case "bow": + UseArrow(); + break; + case "shovel": + UseShovel(); + break; + case "stonelifter": + case "stonelifter2": + UseStoneLifter(); + break; + case "hookshot": + UseHookshot(); + break; + case "boomerang": + UseBoomerang(); + break; + case "magicRod": + UseMagicRod(); + break; + case "ocarina": + UseOcarina(); + break; + } + } + + private void HoldItem(GameItemCollected item, bool lastKeyDown) + { + switch (item.Name) + { + case "sword1": + HoldSword(); + break; + case "sword2": + HoldSword(); + break; + case "shield": + case "mirrorShield": + HoldShield(lastKeyDown); + break; + case "stonelifter": + case "stonelifter2": + HoldStoneLifter(); + break; + case "pegasusBoots": + HoldPegasusBoots(); + break; + } + } + + private void UseSword() + { + if (CurrentState != State.Idle && CurrentState != State.Pushing && CurrentState != State.Rafting && + (CurrentState != State.Jumping || _railJump) && (CurrentState != State.Swimming || !Map.Is2dMap)) + return; + + var slashSounds = new[] { "D378-02-02", "D378-20-14", "D378-21-15", "D378-24-18" }; + Game1.GameManager.PlaySoundEffect(slashSounds[Game1.RandomNumber.Next(0, 4)]); + + Animation.Play("attack_" + Direction); + AnimatorWeapons.Play("attack_" + Direction); + _swordChargeCounter = SwordChargeTime; + IsPoking = false; + _pokeStart = false; + _stopCharging = false; + _swordPoked = false; + _shotSword = false; + StopRaft(); + + CurrentState = State.Attacking; + } + + private void HoldSword() + { + _isHoldingSword = true; + } + + private void UseFeather() + { + if (Is2DMode) + Jump2D(); + else + Jump(); + } + + private void UseToadstool() + { + CurrentState = State.ShowToadstool; + Animation.Play("show2"); + Game1.GameManager.StartDialogPath("toadstool_hole"); + } + + private void UsePowder() + { + if (CurrentState != State.Idle && + CurrentState != State.Jumping && + CurrentState != State.Rafting && + (CurrentState != State.Swimming || !Map.Is2dMap)) + return; + + // remove one powder from the inventory + if (!Game1.GameManager.RemoveItem("powder", 1)) + return; + + var spawnPosition = new Vector2(EntityPosition.X, EntityPosition.Y) + _powderOffset[Direction]; + Map.Objects.SpawnObject(new ObjPowder(Map, spawnPosition.X, spawnPosition.Y, EntityPosition.Z, true)); + + if (CurrentState != State.Jumping) + { + StopRaft(); + + CurrentState = State.Powdering; + Animation.Play("powder_" + Direction); + } + } + + private void UseBomb() + { + // throw the object the player is currently carrying + if (_carriedGameObject != null) + { + ThrowCarriedObject(); + return; + } + + if (CurrentState != State.Idle && + CurrentState != State.Rafting && + (CurrentState != State.Swimming || !Map.Is2dMap)) + return; + + // pick up the bomb if there is one infront of the player + var recInteraction = new RectangleF( + EntityPosition.X + _walkDirection[Direction].X * (_body.Width / 2) - 4, + EntityPosition.Y - _body.Height / 2 + _walkDirection[Direction].Y * (_body.Height / 2) - 4, 8, 8); + + // find a bomb to carry + _bombList.Clear(); + Map.Objects.GetObjectsOfType(_bombList, typeof(ObjBomb), + (int)recInteraction.X, (int)recInteraction.Y, (int)recInteraction.Width, (int)recInteraction.Height); + + // pick up the first bomb + foreach (var objBomb in _bombList) + { + var carriableComponent = objBomb.Components[CarriableComponent.Index] as CarriableComponent; + if (!carriableComponent.IsActive || + !carriableComponent.Rectangle.Rectangle.Intersects(recInteraction)) + continue; + + carriableComponent?.StartGrabbing?.Invoke(); + StartPickup(carriableComponent); + + Animation.Play("pull_" + Direction); + + return; + } + + // remove one bomb from the inventory + if (!Game1.GameManager.RemoveItem("bomb", 1)) + return; + + var spawnPosition = new Vector2(EntityPosition.X, EntityPosition.Y) + _bombOffset[Direction]; + Map.Objects.SpawnObject(new ObjBomb(Map, spawnPosition.X, spawnPosition.Y, true, false, 2000)); + + CurrentState = State.Bombing; + + // play animation + Animation.Play("powder_" + Direction); + } + + private void UseArrow() + { + if (CurrentState != State.Idle && + CurrentState != State.Jumping && + CurrentState != State.Rafting && + CurrentState != State.Bombing && + (CurrentState != State.Swimming || !Map.Is2dMap)) + return; + + // remove one powder from the inventory + if (!Game1.GameManager.RemoveItem("bow", 1)) + return; + + var spawnPosition = new Vector3( + EntityPosition.X + _arrowOffset[Direction].X, EntityPosition.Y + _arrowOffset[Direction].Y + (Map.Is2dMap ? -4 : 0), EntityPosition.Z + (Map.Is2dMap ? 0 : 4)); + Map.Objects.SpawnObject(new ObjArrow( + Map, spawnPosition, Direction, Game1.GameManager.PieceOfPowerIsActive ? ArrowSpeedPoP : ArrowSpeed)); + + if (CurrentState != State.Jumping) + { + StopRaft(); + + CurrentState = State.Powdering; + Animation.Play("powder_" + Direction); + } + + Game1.GameManager.PlaySoundEffect("D378-10-0A"); + } + + private void UseShovel() + { + if (CurrentState != State.Idle || _isClimbing) + return; + + CurrentState = State.Digging; + _hasDug = false; + + // play animation + Animation.Play("dig_" + Direction); + + _digPosition = new Point( + (int)((EntityPosition.X + _shovelOffset[Direction].X) / Values.TileSize), + (int)((EntityPosition.Y + _shovelOffset[Direction].Y) / Values.TileSize)); + + _canDig = Map.CanDig(_digPosition); + + if (_canDig) + Game1.GameManager.PlaySoundEffect("D378-14-0E"); + else + Game1.GameManager.PlaySoundEffect("D360-07-07"); + } + + private void UseStoneLifter() + { + if (_carriedComponent == null || CurrentState != State.Carrying) + return; + + if (Map.Is2dMap && _isClimbing) + return; + + ThrowCarriedObject(); + } + + private void HoldStoneLifter() + { + if (CurrentState != State.Idle) + return; + + GameObject grabbedObject = null; + + if (_carriedComponent == null) + { + var recInteraction = new RectangleF( + EntityPosition.X + _walkDirection[Direction].X * (_body.Width / 2) - 1, + EntityPosition.Y - _body.Height / 2 + _walkDirection[Direction].Y * (_body.Height / 2) - 1, 2, 2); + + // find an object to carry + grabbedObject = Map.Objects.GetCarryableObjects(recInteraction); + if (grabbedObject != null) + { + var carriableComponent = grabbedObject.Components[CarriableComponent.Index] as CarriableComponent; + if (carriableComponent.IsActive) + { + CurrentState = State.Grabbing; + + if (!carriableComponent.IsHeavy || Game1.GameManager.StoneGrabberLevel > 1) + carriableComponent?.StartGrabbing?.Invoke(); + } + } + } + + if (_wasPulling) + _pullCounter += Game1.DeltaTime; + else + _pullCounter = 0; + + if (CurrentState == State.Grabbing) + { + var carriableComponent = grabbedObject.Components[CarriableComponent.Index] as CarriableComponent; + + // is the player pulling in the opposite direction? + var moveVec = ControlHandler.GetMoveVector2(); + + if (carriableComponent?.Pull != null) + { + // do not continuously play the pull animation + if (!carriableComponent.Pull(_pullCounter > 0 ? moveVec : Vector2.Zero) && _pullCounter < 0) + _pullCounter = PullResetTime; + } + + if (moveVec.Length() > 0.5) + { + // pulling into the oposite direction + var moveDir = AnimationHelper.GetDirection(moveVec); + if ((moveDir + 2) % 4 == Direction) + { + // do not show the pull animation while resetting + if (_pullCounter >= 0) + CurrentState = State.Pulling; + + _isPulling = true; + + if (!carriableComponent.IsHeavy || Game1.GameManager.StoneGrabberLevel > 1) + { + // start carrying the object + if (_pullCounter >= PullTime && grabbedObject != null) + StartPickup(carriableComponent); + + if (_pullCounter > PullMaxTime) + _pullCounter = PullResetTime; + } + } + } + } + } + + private void UseHookshot() + { + if (CurrentState != State.Idle && CurrentState != State.Rafting && (!Map.Is2dMap || CurrentState != State.Swimming)) + return; + + var hookshotDirection = CurrentState == State.Swimming ? _swimDirection : Direction; + + var spawnPosition = new Vector3( + EntityPosition.X + _hookshotOffset[hookshotDirection].X, + EntityPosition.Y + _hookshotOffset[hookshotDirection].Y, EntityPosition.Z); + Hookshot.Start(Map, spawnPosition, AnimationHelper.DirectionOffset[hookshotDirection]); + Map.Objects.SpawnObject(Hookshot); + + CurrentState = State.Hookshot; + _body.VelocityTarget = Vector2.Zero; + _body.HoleAbsorption = Vector2.Zero; + _body.IgnoreHoles = true; + StopRaft(); + + // play animation + Animation.Play("powder_" + hookshotDirection); + } + + private void UseBoomerang() + { + if ((CurrentState != State.Idle && + CurrentState != State.Jumping && + (CurrentState != State.Swimming || !Map.Is2dMap)) || !_boomerang.IsReady) + return; + + var spawnPosition = new Vector3(EntityPosition.X + _boomerangOffset[Direction].X, EntityPosition.Y + _boomerangOffset[Direction].Y, EntityPosition.Z); + + // can throw into multiple directions + var boomerangVector = _lastBaseMoveVelocity; + if (boomerangVector != Vector2.Zero) + boomerangVector.Normalize(); + else + boomerangVector = _walkDirection[Direction]; + + _boomerang.Start(Map, spawnPosition, boomerangVector); + Map.Objects.SpawnObject(_boomerang); + + if (CurrentState != State.Jumping) + { + CurrentState = State.Powdering; + Animation.Play("powder_" + Direction); + } + } + + private void UseMagicRod() + { + if (CurrentState != State.Idle && + CurrentState != State.Rafting && + (CurrentState != State.Swimming || !Map.Is2dMap) && + (CurrentState != State.Jumping || _railJump)) + return; + + var spawnPosition = new Vector3(EntityPosition.X + _magicRodOffset[Direction].X, EntityPosition.Y + _magicRodOffset[Direction].Y, EntityPosition.Z); + Map.Objects.SpawnObject(new ObjMagicRodShot(Map, spawnPosition, AnimationHelper.DirectionOffset[Direction] * + (Game1.GameManager.PieceOfPowerIsActive ? MagicRodSpeedPoP : MagicRodSpeed), Direction)); + + CurrentState = State.MagicRod; + _swordChargeCounter = SwordChargeTime; + + Game1.GameManager.PlaySoundEffect("D378-13-0D"); + StopRaft(); + + // play animation + Animation.Play("rod_" + Direction); + AnimatorWeapons.Play("rod_" + Direction); + } + + private void UseOcarina() + { + if (CurrentState != State.Idle || _isClimbing) + return; + + _ocarinaNoteIndex = 0; + _ocarinaCounter = 0; + + Game1.GbsPlayer.Pause(); + + if (Game1.GameManager.SelectedOcarinaSong == 0) + Game1.GameManager.PlaySoundEffect("D370-09-09"); + else if (Game1.GameManager.SelectedOcarinaSong == 1) + Game1.GameManager.PlaySoundEffect("D370-11-0B"); + else if (Game1.GameManager.SelectedOcarinaSong == 2) + Game1.GameManager.PlaySoundEffect("D370-10-0A"); + else + Game1.GameManager.PlaySoundEffect("D370-21-15"); + + _ocarinaSong = Game1.GameManager.SelectedOcarinaSong; + CurrentState = State.Ocarina; + Direction = 3; + Animation.Play("ocarina"); + } + + private void UpdateOcarina() + { + if (CurrentState == State.Ocarina) + { + // finished playing the ocarina song? + if (!Animation.IsPlaying) + { + FinishedOcarinaSong(); + return; + } + + UpdateOcarinaAnimation(); + } + else if (CurrentState == State.OcarinaTelport) + { + // show the animation while teleporting + CurrentState = State.Idle; + } + } + + private void UpdateOcarinaAnimation() + { + if (CurrentState != State.Ocarina) + return; + + _ocarinaCounter += Game1.DeltaTime; + if (_ocarinaCounter > 100 + _ocarinaNoteIndex * 910) + { + _ocarinaNoteIndex++; + + var dir = _ocarinaNoteIndex % 2 == 1 ? -1 : 1; + var objNote = new ObjNote(Map, new Vector2(EntityPosition.X + dir * 7, EntityPosition.Y), dir); + Map.Objects.SpawnObject(objNote); + } + } + + private void FinishedOcarinaSong() + { + // continue playing music + if (_ocarinaSong != 1) + Game1.GbsPlayer.Play(); + + if (_ocarinaSong == -1) + { + CurrentState = State.Idle; + Game1.GameManager.StartDialogPath("ocarina_bad"); + return; + } + + if (_ocarinaSong == 1) + { + CurrentState = State.OcarinaTelport; + + MapTransitionStart = EntityPosition.Position; + MapTransitionEnd = EntityPosition.Position; + TransitionOutWalking = false; + + Game1.GameManager.PlaySoundEffect("D360-44-2C"); + + // load the map + var transitionSystem = (MapTransitionSystem)Game1.GameManager.GameSystems[typeof(MapTransitionSystem)]; + + if (Map.DungeonMode) + { + // respawn at the dungeon entry + MapManager.ObjLink.SetNextMapPosition(MapManager.ObjLink.SavePosition); + transitionSystem.AppendMapChange(MapManager.ObjLink.SaveMap, null, false, false, Color.White, true); + } + else + { + // append a map change + transitionSystem.AppendMapChange("overworld.map", "ocarina_entry", false, false, Color.White, true); + } + + transitionSystem.StartTeleportTransition = true; + + return; + } + + CurrentState = State.Idle; + + var recInteraction = new RectangleF(EntityPosition.X - 64, EntityPosition.Y - 64 - 8, 128, 128); + + _ocarinaList.Clear(); + Map.Objects.GetComponentList(_ocarinaList, + (int)recInteraction.X, (int)recInteraction.Y, (int)recInteraction.Width, (int)recInteraction.Height, OcarinaListenerComponent.Mask); + + // notify ocarina listener components around the player + foreach (var objOcarinaListener in _ocarinaList) + { + if (recInteraction.Contains(objOcarinaListener.EntityPosition.Position)) + { + var ocarinaComponent = (OcarinaListenerComponent)objOcarinaListener.Components[OcarinaListenerComponent.Index]; + ocarinaComponent.OcarinaPlayedFunction(Game1.GameManager.SelectedOcarinaSong); + } + } + } + + private void HoldShield(bool lastKeyDown) + { + if (CurrentState != State.Idle && CurrentState != State.Pushing) + return; + + if (!_wasBlocking) + Game1.GameManager.PlaySoundEffect("D378-22-16"); + + _wasBlocking = true; + CurrentState = State.Blocking; + } + + private void HoldPegasusBoots() + { + if (CurrentState == State.BootKnockback || _isTrapped) + return; + + _bootsHolding = true; + } + + private void UpdateShieldPush() + { + if (Animation.CollisionRectangle.IsEmpty || _isTrapped) + return; + + // push with the shield + var shieldRectangle = new Box( + EntityPosition.X + Animation.CollisionRectangle.X - 7, + EntityPosition.Y + Animation.CollisionRectangle.Y - 16, 0, + Animation.CollisionRectangle.Width, + Animation.CollisionRectangle.Height, 12); + + var pushedRectangle = Map.Objects.PushObject(shieldRectangle, + _walkDirection[Direction] + _body.VelocityTarget * 0.5f, PushableComponent.PushType.Impact); + + // get repelled from the pushed object + if (pushedRectangle != null) + { + _bootsRunning = false; + _bootsCounter = 0; + + _body.Velocity += new Vector3( + -_walkDirection[Direction].X * pushedRectangle.RepelMultiplier, + -_walkDirection[Direction].Y * pushedRectangle.RepelMultiplier, 0); + + if (pushedRectangle.RepelParticle) + { + Game1.GameManager.PlaySoundEffect("D360-07-07"); + // poke particle + Map.Objects.SpawnObject(new ObjAnimator(Map, + (int)(pushedRectangle.PushableBox.Box.X + pushedRectangle.PushableBox.Box.Width / 2), + (int)(pushedRectangle.PushableBox.Box.Y + pushedRectangle.PushableBox.Box.Height / 2), + Values.LayerTop, "Particles/swordPoke", "run", true)); + } + else + { + Game1.GameManager.PlaySoundEffect("D360-09-09"); + } + } + } + + private void UpdateCharging() + { + // stop charging + if (_isHoldingSword) + { + // poke objects that walk into the sowrd + RectangleF collisionRectangle = AnimatorWeapons.CollisionRectangle; + var damageOrigin = BodyRectangle.Center; + SwordDamageBox = new Box( + collisionRectangle.X + EntityPosition.X + _animationOffsetX, + collisionRectangle.Y + EntityPosition.Y - EntityPosition.Z + _animationOffsetY, 0, + collisionRectangle.Width, + collisionRectangle.Height, 4); + + var hitType = Game1.GameManager.SwordLevel == 1 ? HitType.Sword1 : HitType.Sword2; + var damage = Game1.GameManager.SwordLevel == 1 ? 1 : 2; + + // red cloak doubles damage + if (Game1.GameManager.CloakType == GameManager.CloakRed) + damage *= 2; + // piece of power double the damage + if (Game1.GameManager.PieceOfPowerIsActive) + damage *= 2; + + var pieceOfPower = Game1.GameManager.PieceOfPowerIsActive || Game1.GameManager.CloakType == GameManager.CloakRed; + var hitCollision = Map.Objects.Hit(this, damageOrigin, SwordDamageBox, hitType | HitType.SwordHold, damage, pieceOfPower, out var direction, true); + // start poking? + if (hitCollision != Values.HitCollision.None && + hitCollision != Values.HitCollision.NoneBlocking) + { + _swordPoked = true; + Animation.Play("poke_" + Direction); + AnimatorWeapons.Play("poke_" + Direction); + CurrentState = State.Attacking; + + // get repelled + RepelPlayer(hitCollision, direction); + } + else if (_swordChargeCounter > 0) + { + _swordChargeCounter -= Game1.DeltaTime; + + // finished charging? + if (_swordChargeCounter <= 0) + Game1.GameManager.PlaySoundEffect("D360-04-04"); + } + } + else + { + // start charge attack + if (_swordChargeCounter <= 0) + StartSwordSpin(); + else + ReturnToIdle(); + } + } + + private void StartSwordSpin() + { + CurrentState = State.Attacking; + + Animation.Play("swing_" + Direction); + AnimatorWeapons.Play("swing_" + Direction); + + Game1.GameManager.PlaySoundEffect("D378-03-03"); + + _swordChargeCounter = SwordChargeTime; + _isSwingingSword = true; + } + + private void UpdateAttacking() + { + if (_bootsRunning && CarrySword) + AnimatorWeapons.Play("stand_" + Direction); + + if (AnimatorWeapons.CollisionRectangle.IsEmpty) + return; + + var damageOrigin = BodyRectangle.Center; + if (Map.Is2dMap) + damageOrigin.Y -= 4; + + RectangleF collisionRectangle = AnimatorWeapons.CollisionRectangle; + + // this lerps the collision box between frames + // a rotation collision box would probably be a better option + if (AnimatorWeapons.CurrentAnimation.Frames.Length > AnimatorWeapons.CurrentFrameIndex + 1) + { + var frameState = (float)(AnimatorWeapons.FrameCounter / AnimatorWeapons.CurrentFrame.FrameTime); + var collisionRectangleNextFrame = AnimatorWeapons.GetCollisionBox( + AnimatorWeapons.CurrentAnimation.Frames[AnimatorWeapons.CurrentFrameIndex + 1]); + collisionRectangle = new RectangleF( + MathHelper.Lerp(collisionRectangle.X, collisionRectangleNextFrame.X, frameState), + MathHelper.Lerp(collisionRectangle.Y, collisionRectangleNextFrame.Y, frameState), + MathHelper.Lerp(collisionRectangle.Width, collisionRectangleNextFrame.Width, frameState), + MathHelper.Lerp(collisionRectangle.Height, collisionRectangleNextFrame.Height, frameState)); + } + + SwordDamageBox = new Box( + collisionRectangle.X + EntityPosition.X + _animationOffsetX, + collisionRectangle.Y + EntityPosition.Y - EntityPosition.Z + _animationOffsetY, 0, + collisionRectangle.Width, + collisionRectangle.Height, 4); + + var hitType = _bootsRunning ? HitType.PegasusBootsSword : + (Game1.GameManager.SwordLevel == 1 ? HitType.Sword1 : HitType.Sword2); + + var damage = Game1.GameManager.SwordLevel == 1 ? 1 : 2; + + if (_isSwingingSword) + { + damage *= 2; + hitType |= HitType.SwordSpin; + } + + if (_bootsRunning) + damage *= 2; + + // piece of power double the damage + if (Game1.GameManager.PieceOfPowerIsActive) + damage *= 2; + + // red cloak doubles the damage + if (Game1.GameManager.CloakType == GameManager.CloakRed) + damage *= 2; + + var pieceOfPower = Game1.GameManager.PieceOfPowerIsActive || Game1.GameManager.SwordLevel == 2; + var hitCollision = Map.Objects.Hit(this, damageOrigin, SwordDamageBox, hitType, damage, pieceOfPower, out var direction, true); + + if (_pokeStart) + { + _pokeStart = false; + + if (hitCollision != Values.HitCollision.NoneBlocking) + { + var swordRectangle = AnimatorWeapons.CollisionRectangle; + var swordBox = new Box( + swordRectangle.X + EntityPosition.X + _animationOffsetX, + swordRectangle.Y + EntityPosition.Y - EntityPosition.Z + _animationOffsetY, 0, + swordRectangle.Width, swordRectangle.Height, 4); + var destroyableWall = DestroyableWall(swordBox); + + if (destroyableWall) + Game1.GameManager.PlaySoundEffect("D378-23-17"); + else + Game1.GameManager.PlaySoundEffect("D360-07-07"); + + var pokeParticle = new ObjAnimator(Map, 0, 0, Values.LayerTop, "Particles/swordPoke", "run", true); + pokeParticle.EntityPosition.X = EntityPosition.X + _pokeAnimationOffset[Direction].X; + pokeParticle.EntityPosition.Y = EntityPosition.Y + _pokeAnimationOffset[Direction].Y; + Map.Objects.SpawnObject(pokeParticle); + } + } + + if (hitCollision != Values.HitCollision.None && hitCollision != Values.HitCollision.NoneBlocking) + _stopCharging = true; + + // shoot the sword if the player has the l2 sword and full health + if (!_shotSword && Game1.GameManager.SwordLevel == 2 && Game1.GameManager.CurrentHealth >= Game1.GameManager.MaxHearths * 4 && AnimatorWeapons.CurrentFrameIndex == 2) + { + _shotSword = true; + + var spawnPosition = new Vector3(EntityPosition.X + _shootSwordOffset[Direction].X, EntityPosition.Y + _shootSwordOffset[Direction].Y - EntityPosition.Z, 0); + var objSwordShot = new ObjSwordShot(Map, spawnPosition, Direction); + Map.Objects.SpawnObject(objSwordShot); + } + + // spawn hit particle? + if ((hitCollision & Values.HitCollision.Particle) != 0 && _hitParticleTime + 225 < Game1.TotalGameTime) + { + _hitParticleTime = Game1.TotalGameTime; + SwordPoke(collisionRectangle); + } + + RepelPlayer(hitCollision, direction); + } + + private void RepelPlayer(Values.HitCollision collisionType, Vector2 direction) + { + // repel the player + if ((collisionType & Values.HitCollision.Repelling) != 0 && + _hitRepelTime + 225 < Game1.TotalGameTime) + { + _hitRepelTime = Game1.TotalGameTime; + + var multiplier = Map.Is2dMap ? 1.5f : (_bootsRunning ? 1.5f : 1.0f); + + if ((collisionType & Values.HitCollision.Repelling0) != 0) + multiplier = 3.00f; + if ((collisionType & Values.HitCollision.Repelling1) != 0) + multiplier = 2.25f; + + if (_bootsRunning) + _bootsStop = true; + + _body.Velocity += new Vector3(-direction.X, -direction.Y, 0) * multiplier; + } + } + + private void SwordPoke(RectangleF collisionRectangle) + { + Game1.GameManager.PlaySoundEffect("D360-07-07"); + + // poke particle + Map.Objects.SpawnObject(new ObjAnimator(Map, + (int)(EntityPosition.X - 8 + collisionRectangle.X + collisionRectangle.Width / 2), + (int)(EntityPosition.Y - 15 + collisionRectangle.Y + collisionRectangle.Height / 2), + Values.LayerTop, "Particles/swordPoke", "run", true)); + } + + private void UpdatePickup() + { + if (ShowItem == null) + return; + + _itemShowCounter -= Game1.DeltaTime; + + if (_itemShowCounter <= 0) + { + // show pick up text + if (_showItem && CurrentState == State.PickingUp) + { + _showItem = false; + + // show pickup dialog + if (ShowItem.PickUpDialog != null) + { + if (string.IsNullOrEmpty(_pickupDialogOverride)) + Game1.GameManager.StartDialogPath(ShowItem.PickUpDialog); + else + { + Game1.GameManager.StartDialogPath(_pickupDialogOverride); + _pickupDialogOverride = null; + } + + if (!string.IsNullOrEmpty(_additionalPickupDialog)) + { + Game1.GameManager.StartDialogPath(_additionalPickupDialog); + _additionalPickupDialog = null; + } + } + + _itemShowCounter = 250; + + if (ShowItem.Name == "sword1") + _itemShowCounter = 5850; + else if (ShowItem.Name.StartsWith("instrument")) + _itemShowCounter = 1000; + } + else + { + Game1.GameManager.SaveManager.SetString("player_shows_item", "0"); + + // add the item to the inventory + if (_collectedShowItem != null) + { + Game1.GameManager.CollectItem(_collectedShowItem, 0); + _collectedShowItem = null; + } + + // spawn the follower if one was picked up + UpdateFollower(false); + + // sword spin + if (ShowItem.Name == "sword1") + { + Game1.GameManager.PlaySoundEffect("D378-03-03"); + Animation.Play("swing_3"); + AnimatorWeapons.Play("swing_3"); + CurrentState = State.SwordShow0; + _swordChargeCounter = 1; // don't blink + ShowItem = null; + } + else if (ShowItem.Name.StartsWith("instrument")) + { + // make sure that the music is not playing + Game1.GameManager.StopPieceOfPower(); + Game1.GameManager.StopGuardianAcorn(); + + _instrumentCounter = 0; + CurrentState = State.ShowInstrumentPart0; + } + else + { + ShowItem = null; + if (CurrentState == State.PickingUp) + CurrentState = State.Idle; + } + } + } + } + + private void EndPickup() + { + _savedPreItemPickup = false; + SaveGameSaveLoad.ClearSaveState(); + Game1.GameManager.SaveManager.DisableHistory(); + } + + private void UpdateHookshot() + { + if (Hookshot.IsMoving) + return; + + _body.IgnoreHoles = false; + ReturnToIdle(); + } + + private void UpdateDigging() + { + if (Animation.CurrentFrameIndex > 0 && !_hasDug) + { + _hasDug = true; + if (_canDig) + Map.Dig(_digPosition, EntityPosition.Position, Direction); + } + + if (!Animation.IsPlaying) + CurrentState = State.Idle; + } + + private void UpdatePegasusBoots() + { + _wasBootsRunning = _bootsRunning; + if (CurrentState != State.Idle || _isClimbing || Map.Is2dMap && Direction % 2 != 0) + { + _bootsHolding = false; + _bootsRunning = false; + _bootsCounter = 0; + + return; + } + + // stop running but start charging with a time boost + if (_bootsStop && _body.Velocity.Length() < 0.25f) + { + _bootsStop = false; + _bootsRunning = false; + _bootsCounter = _bootsRunTime - 300; + } + + if (_bootsHolding || _bootsRunning) + { + var lastCounter = _bootsCounter; + _bootsCounter += Game1.DeltaTime; + + // spawn particles + if (_bootsCounter % _bootsParticleTime < lastCounter % _bootsParticleTime) + { + // water splash effect while running water? + if (_body.CurrentFieldState.HasFlag(MapStates.FieldStates.Water)) + { + Game1.GameManager.PlaySoundEffect("D360-14-0E"); + + var splashAnimator = new ObjAnimator(_body.Owner.Map, 0, 0, 0, 3, 1, "Particles/splash", "idle", true); + splashAnimator.EntityPosition.Set(new Vector2( + _body.Position.X + _body.OffsetX + _body.Width / 2f, + _body.Position.Y + _body.OffsetY + _body.Height - _body.Position.Z - 3)); + Map.Objects.SpawnObject(splashAnimator); + } + else + { + Game1.GameManager.PlaySoundEffect("D378-07-07"); + + var animator = new ObjAnimator(Map, (int)EntityPosition.X, (int)(EntityPosition.Y + 1), + 0, -1 - (int)EntityPosition.Z, Values.LayerPlayer, "Particles/run", "spawn", true); + Map.Objects.SpawnObject(animator); + } + } + + // start running + if (!_bootsRunning && _bootsCounter > _bootsRunTime) + { + _bootsRunning = true; + _wasBootsRunning = true; + _bootsStop = false; + } + } + else + { + _bootsCounter = 0; + } + } + + private bool Jump(bool force = false, bool playSoundEffect = true) + { + if ((!force && ( + CurrentState != State.Idle && + CurrentState != State.Attacking && + CurrentState != State.Charging && + CurrentState != State.Pushing && + CurrentState != State.Blocking && + CurrentState != State.Rafting)) || + _isTrapped || !_canJump) + { + if (_isTrapped && playSoundEffect) + Game1.GameManager.PlaySoundEffect("D360-13-0D"); + + return false; + } + + if (!_body.IsGrounded) + return false; + + // release the carried object if the player is carrying something + ReleaseCarriedObject(); + + if (playSoundEffect) + Game1.GameManager.PlaySoundEffect("D360-13-0D"); + + if (_isRafting) + { + // do not move while jumping + _moveVelocity = Vector2.Zero; + _lastMoveVelocity = Vector2.Zero; + StopRaft(); + } + else + { + // base move velocity does not contain the velocity added in the air + // so when we hit the floor and directly jump afterwards we do not get the velocity of the previouse jump + _lastMoveVelocity = _lastBaseMoveVelocity; + } + + _startedJumping = true; + _body.Velocity.Z = JumpAcceleration; + + // while attacking the player can still jump but without the animation + if (CurrentState != State.Attacking && + CurrentState != State.Charging) + { + // start the jump animation + Animation.Play("jump_" + Direction); + + CurrentState = State.Jumping; + } + + return true; + } + + private void UpdateJump() + { + if (CurrentState != State.Jumping) + return; + + if (_railJump) + { + _railJumpPercentage += Game1.TimeMultiplier * _railJumpSpeed; + var amount = MathF.Sin(_railJumpPercentage * (MathF.PI * 0.3f)) / MathF.Sin(MathF.PI * 0.3f); + var newPosition = Vector2.Lerp(_railJumpStartPosition, _railJumpTargetPosition, amount); + EntityPosition.Set(newPosition); + + EntityPosition.Z = MathF.Sin(_railJumpPercentage * MathF.PI) * _railJumpHeight + _railJumpPercentage * _railJumpPositionZ; + + if (_railJumpPercentage >= 1) + { + _railJump = false; + _body.IgnoreHeight = false; + _body.IgnoresZ = false; + _body.Velocity.Z = -1f; + _body.JumpStartHeight = _railJumpPositionZ; + EntityPosition.Set(_railJumpTargetPosition); + EntityPosition.Z = _railJumpPositionZ; + _lastMoveVelocity = Vector2.Zero; + } + } + + // touched the ground + if (!_railJump && _body.IsGrounded && _body.Velocity.Z <= 0) + { + if ((_body.CurrentFieldState & (MapStates.FieldStates.Water | MapStates.FieldStates.DeepWater)) == 0) + Game1.GameManager.PlaySoundEffect("D378-07-07"); + if ((_body.CurrentFieldState & MapStates.FieldStates.DeepWater) == 0) + Game1.GameManager.PlaySoundEffect("D360-14-0E"); + + ReturnToIdle(); + } + } + + private void ThrowCarriedObject() + { + Game1.GameManager.PlaySoundEffect("D360-08-08"); + + // play a little throw animation + Animation.Play("throw_" + Direction); + CurrentState = State.Throwing; + + _carriedComponent.Throw(_walkDirection[Direction] * 3f); + RemoveCarriedObject(); + } + + private void StartPickup(CarriableComponent carriableComponent) + { + if (carriableComponent?.Init == null) + return; + + _carriedComponent = carriableComponent; + + Game1.GameManager.PlaySoundEffect("D370-02-02"); + + _carryStartPosition = _carriedComponent.Init(); + _carriedComponent.IsPickedUp = true; + CurrentState = State.PreCarrying; + _preCarryCounter = 0; + + _carriedGameObject = carriableComponent.Owner; + _carriedObjDrawComp = carriableComponent.Owner.Components[DrawComponent.Index] as DrawComponent; + if (_carriedObjDrawComp != null) + _carriedObjDrawComp.IsActive = false; + } + + private void UpdatePositionCarriedObject(CPosition newPosition) + { + if (_carriedComponent == null) + return; + + var targetPosition = new Vector3(EntityPosition.X, EntityPosition.Y, EntityPosition.Z + _carriedComponent.CarryHeight); + + if (CurrentState == State.PreCarrying) + { + // finished pickup animation? + if (_preCarryCounter >= PreCarryTime) + { + _preCarryCounter = PreCarryTime; + CurrentState = State.Carrying; + } + + var pickupTime = 1 - MathF.Cos((_preCarryCounter / PreCarryTime) * (MathF.PI / 2)); + + var carryPositionXY = Vector2.Lerp( + new Vector2(_carryStartPosition.X, _carryStartPosition.Y), + new Vector2(targetPosition.X, targetPosition.Y), + 1 - MathF.Cos(pickupTime * (MathF.PI / 2))); + var carryPositionZ = MathHelper.Lerp(_carryStartPosition.Z, targetPosition.Z, + MathF.Sin(pickupTime * (MathF.PI / 2))); + + if (!_carriedComponent.UpdatePosition(new Vector3(carryPositionXY.X, carryPositionXY.Y, carryPositionZ))) + { + CurrentState = State.Idle; + ReleaseCarriedObject(); + } + } + else if (!_isFlying) + { + // move the carried object up/down with the walk animation + if (Direction % 2 == 0) + targetPosition.Z += _isWalking ? Animation.CurrentFrameIndex : 1; + else if (Map.Is2dMap) + targetPosition.Z += 1; + + if (!_carriedComponent.UpdatePosition(targetPosition)) + { + CurrentState = State.Idle; + ReleaseCarriedObject(); + } + } + } + + #endregion + + private void StopRaft() + { + if (_isRafting) + { + _objRaft.Body.VelocityTarget = Vector2.Zero; + _objRaft.Body.AdditionalMovementVT = Vector2.Zero; + _objRaft.Body.LastAdditionalMovementVT = Vector2.Zero; + } + } + + private void StealItem() + { + StopHoldingItem(); + + // used in ObjStoreItem to not return the item to the shelf + Game1.GameManager.SaveManager.SetString("result", "0"); + + Game1.GameManager.SaveName = "Thief"; + + // add the item to the inventory + var strItem = Game1.GameManager.SaveManager.GetString("itemShopItem"); + var strCount = Game1.GameManager.SaveManager.GetString("itemShopCount"); + + var item = new GameItemCollected(strItem) + { + Count = int.Parse(strCount) + }; + + // gets picked up + PickUpItem(item, false, false); + + Game1.GameManager.SaveManager.SetString("stoleItem", "1"); + _showStealMessage = true; + } + + private void OnHoleAbsorb() + { + if (CurrentState == State.Falling || + CurrentState == State.TeleporterUpWait || + CurrentState == State.TeleporterUp || + CurrentState == State.PickingUp || + CurrentState == State.Dying) + return; + + CurrentState = State.Falling; + + FreeTrappedPlayer(); + ReleaseCarriedObject(); + + _railJump = false; + _isFallingIntoHole = true; + _holeFallCounter = 350; + + Animation.Play("fall"); + Game1.GameManager.PlaySoundEffect("D370-12-0C"); + } + + private void OnDeath() + { + if (CurrentState == State.Dying) + return; + + // has potion? + var potion = Game1.GameManager.GetItem("potion"); + if (potion != null && potion.Count >= 1) + { + Game1.GameManager.RemoveItem("potion", 1); + Game1.GameManager.HealPlayer(99); + ItemDrawHelper.EnableHeartAnimationSound(); + return; + } + + Game1.GameManager.StopMusic(true); + Game1.GameManager.PlaySoundEffect("D370-08-08"); + + CurrentState = State.Dying; + Animation.Play("dying"); + + // set the correct start frame depending on the direction the player is facing + int[] dirToFrame = { 0, 2, 1, 3 }; + Animation.SetFrame(dirToFrame[Direction]); + + ((GameOverSystem)Game1.GameManager.GameSystems[typeof(GameOverSystem)]).StartDeath(); + } + + private void ReleaseCarriedObject() + { + // let the carried item fall down + if (_carriedComponent == null) + return; + + _carriedComponent.Throw(new Vector2(0, 0)); + RemoveCarriedObject(); + } + + private void RemoveCarriedObject() + { + _carriedComponent.IsPickedUp = false; + _carriedComponent = null; + + _carriedGameObject = null; + + if (_carriedObjDrawComp != null) + { + _carriedObjDrawComp.IsActive = true; + _carriedObjDrawComp = null; + } + } + + private void UpdateFollower(bool mapInit) + { + var hasFollower = false; + + // check if marin is following the player + var itemMarin = Game1.GameManager.GetItem("marin"); + if (itemMarin != null && itemMarin.Count > 0) + { + _objFollower = _objMaria; + hasFollower = true; + } + + // check if the rooster is following the player + var itemRooster = Game1.GameManager.GetItem("rooster"); + if (itemRooster != null && itemRooster.Count > 0) + { + _objFollower = _objRooster; + hasFollower = true; + } + + // check if the ghost is following the player + var itemGhost = Game1.GameManager.GetItem("ghost"); + if (itemGhost != null && itemGhost.Count > 0) + { + _objFollower = _objGhost; + hasFollower = true; + } + + if (hasFollower) + { + // check if the follower is already spawned + if (_objFollower.Map != Map) + { + if (mapInit && NextMapPositionStart.HasValue) + _objFollower.EntityPosition.Set(NextMapPositionStart.Value); + else + _objFollower.EntityPosition.Set(EntityPosition.Position); + + _objFollower.Map = Map; + Map.Objects.SpawnObject(_objFollower); + } + } + // remove the current follower from the map + else if (_objFollower != null) + { + Map.Objects.DeleteObjects.Add(_objFollower); + _objFollower = null; + } + } + + private void UpdateStoreItemPosition(CPosition position) + { + _storePickupPosition.X = position.X - _storeItemWidth / 2f; + _storePickupPosition.Y = position.Y - EntityPosition.Z - 14 - _storeItemHeight; + } + + #region public + + public void InitGame() + { + Animation.Play((CarryShield ? "stands_" : "stand_") + Direction); + _spriteTransparency = 1; + + _inDungeon = false; + + NextMapFallStart = false; + NextMapFallRotateStart = false; + + Game1.GameManager.SwordLevel = 0; + Game1.GameManager.ShieldLevel = 0; + Game1.GameManager.StoneGrabberLevel = 0; + + Game1.GameManager.SelectedOcarinaSong = -1; + Game1.GameManager.OcarinaSongs[0] = 0; + Game1.GameManager.OcarinaSongs[1] = 0; + Game1.GameManager.OcarinaSongs[2] = 0; + + Game1.GameManager.HasMagnifyingLens = false; + + _spawnGhost = false; + HasFlippers = false; + StoreItem = null; + + _body.IsActive = true; + + _objMaria = new ObjMarin(Map, 0, 0); + _objRooster = new ObjCock(Map, 0, 0, null); + _objGhost = new ObjGhost(Map, 0, 0); + + MapInit(); + + CurrentState = State.Idle; + } + + public void MapInit() + { + if (CurrentState != State.Swimming && CurrentState != State.OcarinaTelport) + CurrentState = State.Idle; + + _boomerang.Reset(); + Hookshot.Reset(); + + _hookshotPull = false; + + _railJump = false; + IsVisible = true; + + _isRafting = false; + _isFlying = false; + + _isClimbing = false; + + _isTrapped = false; + _shadowComponent.IsActive = true; + + _isGrabbed = false; + + ShowItem = null; + _collectedShowItem = null; + _objFollower = null; + + _hitRepelTime = 0; + _hitParticleTime = 0; + + _hitCount = 0; + _sprite.SpriteShader = null; + + _moveVelocity = Vector2.Zero; + _lastMoveVelocity = Vector2.Zero; + _hitVelocity = Vector2.Zero; + _body.Velocity = Vector3.Zero; + + _body.IgnoreHeight = false; + _body.IgnoreHoles = false; + _body.DeepWaterOffset = -3; + _body.Level = 0; + _body.IsGrounded = true; + + _bootsHolding = false; + _bootsRunning = false; + _bootsCounter = 0; + + _carriedGameObject = null; + _carriedComponent = null; + _carriedObjDrawComp = null; + + _drawInstrumentEffect = false; + + _diveCounter = 0; + _swimVelocity = Vector2.Zero; + + if (NextMapFallStart) + { + EntityPosition.Z = 64; + + _body.Velocity.Z = -3.75f; + _body.IgnoresZ = false; + _body.JumpStartHeight = EntityPosition.Z; + + NextMapFallStart = false; + } + + if (NextMapFallRotateStart) + { + EntityPosition.Z = 160; + + _body.Velocity.Z = -3.75f; + _body.IgnoresZ = false; + _body.IsGrounded = false; + _body.JumpStartHeight = EntityPosition.Z; + + _fallEntryCounter = 0; + CurrentState = State.FallRotateEntry; + + NextMapFallRotateStart = false; + } + + if (NextMapPositionEnd.HasValue) + SetHoleResetPosition(NextMapPositionEnd.Value); + + if (Is2DMode) + MapInit2D(); + + // reset guardian acorn and piece of power except when in a dungeon + if (!_inDungeon || Map == null || !Map.DungeonMode) + { + Game1.GameManager.StopGuardianAcorn(); + Game1.GameManager.StopPieceOfPower(); + } + + if (Map != null && Map.DungeonMode) + _inDungeon = true; + else + _inDungeon = false; + + Game1.GameManager.UseShockEffect = false; + } + + public void InitEnding() + { + CurrentState = State.Sequence; + Animation.Play("stand_1"); + } + + public void FinishLoadingMap(Map.Map map) + { + Map = map; + Is2DMode = map.Is2dMap; + + if (NextMapPositionStart.HasValue) + SetPosition(NextMapPositionStart.Value); + + MapInit(); + + UpdateFollower(true); + + if (_objFollower != null) + _objFollower.EntityPosition.Set(NextMapPositionStart.Value); + } + + public void Respawn() + { + Animation.Play((CarryShield ? "stands_" : "stand_") + Direction); + + StoreItem = null; + _body.IsActive = true; + + var hearts = 3; + if (Game1.GameManager.MaxHearths >= 14) + hearts = 10; + else if (Game1.GameManager.MaxHearths >= 10) + hearts = 7; + else if (Game1.GameManager.MaxHearths >= 6) + hearts = 5; + + Game1.GameManager.CurrentHealth = hearts * 4; + + Game1.GameManager.DeathCount++; + + MapInit(); + } + + public void StartIntro() + { + // set the music + Game1.GameManager.SetMusic(27, 2); + + CurrentState = State.Intro; + + Animation.Play("intro"); + + NextMapPositionStart = null; + NextMapPositionEnd = null; + SetPosition(new Vector2(56, 51)); + MapManager.Camera.ForceUpdate(Game1.GameManager.MapManager.GetCameraTarget()); + + MapManager.ObjLink.SaveMap = Map.MapName; + MapManager.ObjLink.SavePosition = new Vector2(70, 70); + MapManager.ObjLink.SaveDirection = 3; + } + + public void SetPosition(Vector2 newPosition) + { + _body.VelocityTarget = Vector2.Zero; + EntityPosition.Set(new Vector2(newPosition.X, newPosition.Y)); + } + + public void FreezePlayer() + { + UpdatePlayer = false; + + _isWalking = false; + _bootsRunning = false; + + // stop movement + // on the boat the player should still move up/down while playing the sequence + if (Map != null && !Map.Is2dMap) + { + // make sure to fall down when jumping into a game sequence + _body.Velocity.X = 0; + _body.Velocity.Y = 0; + if (CurrentState == State.Jumping || CurrentState == State.Powdering) + CurrentState = State.Idle; + } + + _body.VelocityTarget = Vector2.Zero; + _moveVelocity = Vector2.Zero; + _hitVelocity = Vector2.Zero; + _swimVelocity = Vector2.Zero; + + // stop push animation + if (CurrentState == State.Pushing) + CurrentState = State.Idle; + + if (Map != null && Map.Is2dMap) + UpdateAnimation2D(); + else + UpdateAnimation(); + } + + public bool HitPlayer(Box box, HitType type, int damage, float pushMultiplier = 1.75f) + { + var boxDir = BodyRectangle.Center - box.Center; + + // if the player is standing inside the box the hit is not blockable + var blockable = Math.Abs(boxDir.X) > box.Width / 2 || + Math.Abs(boxDir.Y) > box.Height / 2; + + var intersection = BodyRectangle.GetIntersection(box.Rectangle()); + var direction = BodyRectangle.Center - intersection.Center; + + if (direction == Vector2.Zero) + direction = boxDir; + if (direction != Vector2.Zero) + direction.Normalize(); + + return HitPlayer(direction * pushMultiplier, type, damage, blockable); + } + + public bool HitPlayer(Vector2 direction, HitType type, int damage, bool blockable, int damageCooldown = CooldownTime) + { + if (_hitCount > 0 || + CurrentState == State.Dying || + CurrentState == State.PickingUp || + CurrentState == State.Drowning || + CurrentState == State.Drowned || + CurrentState == State.Knockout || + IsDiving() || + Game1.GameManager.UseShockEffect || + !UpdatePlayer || + _isTrapped) + return false; + + // block the attack? + if (blockable && (CurrentState == State.Blocking || _bootsRunning && CarryShield)) + { + _bootsHolding = false; + _bootsRunning = false; + _bootsCounter = 0; + + // is the player blocking this direction + var vectorDirection = ToDirection(-direction); + if (Direction == vectorDirection) + return false; + } + + // jump a little if we get hit by a spike + if ((type & HitType.Spikes) != 0) + { + _body.Velocity.Z = 1.0f; + } + + // redirect the down force to the sides + if (Map.Is2dMap && _body.IsGrounded && direction.Y > 0) + { + direction.X += Math.Sign(direction.X) * Math.Abs(direction.Y) * 0.5f; + direction.Y = 0; + } + + // fall down on damage taken while climbing + if (Map.Is2dMap && _isClimbing) + _isClimbing = false; + + if (!_isRafting) + _hitVelocity += direction; + + if (_hitCount > 0) + return false; + + Game1.GameManager.PlaySoundEffect("D370-03-03"); + + _hitCount = damageCooldown; + Game1.GameManager.InflictDamage(damage); + + // TODO_2: this should be optional (in config file or game settings?) + //if(false) + { + // freeze the screen and shake + var freezeTime = 67; + var shakeMult = (100.0f / freezeTime) * MathF.PI; + Game1.FreezeTime = Game1.TotalGameTime + freezeTime; + Game1.GameManager.ShakeScreen(freezeTime, (int)(direction.X * 2), (int)(direction.Y * 2), shakeMult, shakeMult); + UpdateDamageShader(); + } + + return true; + } + + public void FreezeAnimationState() + { + CurrentState = State.Frozen; + Animation.Pause(); + } + + public void StartOcarinaDuo() + { + CurrentState = State.Ocarina; + + _ocarinaNoteIndex = 0; + _ocarinaCounter = 0; + + Animation.Play("ocarina_duo"); + } + + public void StopOcarinaDuo() + { + CurrentState = State.Idle; + } + + public void StartFlying(ObjCock objCock) + { + _isFlying = true; + _objRooster = objCock; + } + + public void StopFlying() + { + _isFlying = false; + + _body.IgnoresZ = false; + _body.IsGrounded = false; + _body.JumpStartHeight = 0; + + _lastMoveVelocity = Vector2.Zero; + + if (_objRooster != null) + _objRooster.StopFlying(); + } + + public void SeqLockPlayer() + { + UpdatePlayer = false; + + if (Map.Is2dMap) + UpdateAnimation2D(); + else + UpdateAnimation(); + } + + public void LockPlayer() + { + _isLocked = true; + } + + public void TrapPlayer(bool disableItems = false) + { + _isTrapped = true; + _trappedDisableItems = disableItems; + _trapInteractionCount = 8; + } + + public bool StealShield() + { + // steal the shield if it is in the first 4 slots + for (var i = 0; i < 4; i++) + { + if (Game1.GameManager.Equipment[i] != null && + Game1.GameManager.Equipment[i].Name == "shield") + { + Game1.GameManager.RemoveItem("shield", 1); + return true; + } + } + + return false; + } + + public void FreeTrappedPlayer() + { + _isTrapped = false; + } + + public void ShortenDive() + { + _diveCounter = 350; + } + + public void StartRaftRiding(ObjRaft objRaft) + { + if (CurrentState != State.Jumping) + CurrentState = State.Rafting; + + _isRafting = true; + _objRaft = objRaft; + _body.VelocityTarget = Vector2.Zero; + _body.IgnoreHeight = true; + } + + public void RaftJump(Vector2 targetPosition) + { + if (CurrentState == State.Jumping) + return; + + CurrentState = State.Jumping; + + Game1.GameManager.PlaySoundEffect("D360-13-0D"); + + Direction = 3; + Animation.Play("jump_" + Direction); + + if (_objRaft != null) + { + _objRaft.Jump(targetPosition, 100); + } + } + + public void ExitRaft() + { + CurrentState = State.Idle; + + _isRafting = false; + _objRaft = null; + + EntityPosition.Set(new Vector2(EntityPosition.X, EntityPosition.Y - 1)); + } + + public void SetHoleResetPosition(Vector2 position, int direction) + { + if (direction == 0) + _alternativeHoleResetPosition = new Vector2(position.X + MathF.Ceiling(_body.Width / 2f), position.Y + 8 + MathF.Ceiling(_body.Height / 2f)); + else if (direction == 1) + _alternativeHoleResetPosition = new Vector2(position.X + 8, position.Y + _body.Height); + else if (direction == 2) + _alternativeHoleResetPosition = new Vector2(position.X + 16 - MathF.Ceiling(_body.Width / 2f), position.Y + 8 + MathF.Ceiling(_body.Height / 2f)); + else if (direction == 3) + _alternativeHoleResetPosition = new Vector2(position.X + 8, position.Y + 16); + + // also used for the drown reseet point + _drownResetPosition = _alternativeHoleResetPosition; + } + + public void Knockout(Vector2 direction, string resetDoor) + { + if (CurrentState == State.Knockout) + return; + + CurrentState = State.Knockout; + + MapTransitionStart = MapManager.ObjLink.EntityPosition.Position; + MapTransitionEnd = MapManager.ObjLink.EntityPosition.Position + direction * 80; + TransitionOutWalking = false; + + // append a map change + var transitionSystem = ((MapTransitionSystem)Game1.GameManager.GameSystems[typeof(MapTransitionSystem)]); + transitionSystem.AppendMapChange(Map.MapName, resetDoor, false, false, Color.White, false); + transitionSystem.StartKnockoutTransition = true; + } + + public void GroundStun(int stunTime = 1250) + { + // do not stun the player when he is in the air + if (_body.IsGrounded && CurrentState != State.Jumping) + Stun(stunTime); + } + + public void Stun(int stunTime, bool particle = false) + { + if (CurrentState == State.Dying) + return; + + CurrentState = State.InitStunned; + + _stunnedParticles = particle; + _stunnedCounter = stunTime; + } + + public void StartGrab() + { + _isGrabbed = true; + } + + public void EndGrab() + { + _isGrabbed = false; + } + + public void StartThrow(Vector3 direction) + { + _body.Velocity = direction; + _body.IsGrounded = false; + _body.JumpStartHeight = 0; + } + + public void StartHoldingItem(GameItem item) + { + CurrentState = State.CarryingItem; + + StoreItem = item; + + _storeItemWidth = item.SourceRectangle.Value.Width; + _storeItemHeight = item.SourceRectangle.Value.Height; + + EntityPosition.AddPositionListener(typeof(ObjLink), UpdateStoreItemPosition); + UpdateStoreItemPosition(EntityPosition); + + Game1.GameManager.SaveManager.SetString("holdItem", "1"); + } + + public void StopHoldingItem() + { + CurrentState = State.Idle; + + StoreItem = null; + + // this removes all listeners with the ObjLink as a key + EntityPosition.PositionChangedDict.Remove(typeof(ObjLink)); + + Game1.GameManager.SaveManager.SetString("holdItem", "0"); + } + + public void SlowDown(float speed) + { + if (CurrentState != State.Jumping) + _currentWalkSpeed = speed; + } + + public void StartBedTransition() + { + _startBedTransition = true; + } + + public void StartJump() + { + if (CurrentState != State.Dying && CurrentState != State.PickingUp) + Jump(true); + } + + public void StartRailJump(Vector2 goalPosition, float jumpHeightMultiply, float jumpSpeedMultiply, float goalPositionZ = 0) + { + if (CurrentState == State.Swimming) + CurrentState = State.Idle; + + if (!Jump(false, false)) + return; + + Game1.GameManager.PlaySoundEffect("D360-08-08"); + + _railJump = true; + + _railJumpStartPosition = EntityPosition.Position; + _railJumpTargetPosition = goalPosition; + + // values for distance of 16 + _railJumpSpeed = 0.045f * jumpSpeedMultiply; + _railJumpHeight = 12 * jumpHeightMultiply; + _railJumpPositionZ = goalPositionZ; + + _railJumpPercentage = 0; + + _body.IgnoreHeight = true; + _body.IgnoresZ = true; + _body.Velocity.Z = 0; + } + + public Vector2 RailJumpTarget() + { + return _railJumpTargetPosition; + } + + public float RailJumpSpeed() + { + return _railJumpSpeed; + } + + public float RailJumpHeight() + { + return _railJumpHeight; + } + + public float GetRailJumpAmount() + { + if (!_railJump) + return 0; + + return _railJumpPercentage; + } + + public void RotatePlayer() + { + if (_bootsRunning) + return; + + _rotationCounter += Game1.DeltaTime; + // 8 frames per direction + if (_rotationCounter > 133) + { + _rotationCounter -= 133; + if (!_isWalking) + { + Direction = (Direction + 1) % 4; + // rotate the sword if the player is currently charging + if (CurrentState == State.Charging) + AnimatorWeapons.Play("stand_" + Direction); + } + } + } + + public void StartTeleportation(ObjDungeonTeleporter teleporter) + { + _teleporter = teleporter; + + CurrentState = State.Teleporting; + _drawBody.Layer = Values.LayerTop; + + _teleportState = 0; + _teleportCounter = 0; + _teleportCounterFull = 0; + + } + + public void ShockPlayer(int time) + { + // stop running to not continuously run into the enemy + _bootsHolding = false; + _bootsRunning = false; + _bootsCounter = 0; + + CurrentState = State.Idle; + + // shock the player + Game1.GameManager.UseShockEffect = true; + + Game1.GameManager.ShakeScreen(time, 4, 0, 8.5f, 0); + + Game1.GameManager.InflictDamage(4); + } + + public void StartHookshotPull() + { + _hookshotPull = true; + if (Map.Is2dMap) + { + _body.Velocity.Y = 0; + _body.LastVelocityCollision = Values.BodyCollision.None; + } + + // if the player is on the upper level he will not get pulled through water and we can move through colliders + if ((_body.CurrentFieldState & MapStates.FieldStates.UpperLevel) != 0) + { + _body.IsGrounded = false; + _body.Level = MapStates.GetLevel(_body.CurrentFieldState); + } + } + + public bool UpdateHookshotPull() + { + var distance = _body.BodyBox.Box.Center - Hookshot.HookshotPosition.Position; + var pullVector = AnimationHelper.DirectionOffset[Direction]; + + // reached the end of the hook or collided with an object before + if (distance.Length() < (distance + pullVector).Length() || + (_body.LastVelocityCollision != Values.BodyCollision.None && (_body.SlideOffset == Vector2.Zero || _body.BodyBox.Box.Contains(Hookshot.HookshotPosition.Position))) || + CurrentState == State.Dying) + { + _hookshotPull = false; + _body.IgnoresZ = false; + _body.IgnoreHoles = false; + _body.Level = 0; + return false; + } + + _body.VelocityTarget = pullVector * 3; + + return true; + } + + public void StartTeleportation(string teleportMap, string teleporterId) + { + _teleporter = null; + + CurrentState = State.Teleporting; + _drawBody.Layer = Values.LayerTop; + + _teleportMap = teleportMap; + _teleporterId = teleporterId; + _teleportState = 0; + _teleportCounter = 0; + _teleportCounterFull = 0; + + ReleaseCarriedObject(); + } + + public void StartWorldTelportation(Vector2 newPosition) + { + CurrentState = State.TeleportFallWait; + + var positionDistance = EntityPosition.Position - newPosition; + var fallPosition = new Vector3(newPosition.X, newPosition.Y, 128); + EntityPosition.Set(fallPosition); + + if (_objFollower != null) + { + var itemGhost = Game1.GameManager.GetItem("ghost"); + if (itemGhost != null && itemGhost.Count >= 0) + _objFollower.EntityPosition.Set(new Vector2(fallPosition.X, fallPosition.Y)); + else + _objFollower.EntityPosition.Set(fallPosition); + } + + // only jump to the new position if it is a different teleporter at a different location + if (positionDistance.Length() > 64) + MapManager.Camera.ForceUpdate(Game1.GameManager.MapManager.GetCameraTarget()); + } + + public void SetWalkingDirection(int direction) + { + Direction = direction; + UpdateAnimation(); + } + + public void PickUpItem(GameItemCollected itemCollected, bool showItem, bool showDialog = true, bool playSound = true) + { + if (itemCollected == null) + return; + + var item = Game1.GameManager.ItemManager[itemCollected.Name]; + // the base item has the max count and other information + var baseItem = Game1.GameManager.ItemManager[item.Name]; + + // save the game before entering the show animation to support exiting the game while the item is shown + _savedPreItemPickup = true; + if (item.PickUpDialog != null && !Game1.GameManager.SaveManager.HistoryEnabled) + { + SaveGameSaveLoad.FillSaveState(Game1.GameManager); + Game1.GameManager.SaveManager.EnableHistory(); + } + + _showItem = false; + _pickingUpInstrument = false; + _pickingUpSword = false; + + // upgrade the sword + var equipmentPosition = 0; + if (item.Name == "sword1") + { + _pickingUpSword = true; + Game1.GameManager.SetMusic(14, 2); + } + else if (item.Name == "sword2") + { + equipmentPosition = Game1.GameManager.GetEquipmentSlot("sword1"); + Game1.GameManager.RemoveItem("sword1", 99); + Game1.GameManager.CollectItem(itemCollected, equipmentPosition); + Game1.GameManager.SetMusic(14, 2); + } + else if (item.Name == "mirrorShield") + { + equipmentPosition = Game1.GameManager.GetEquipmentSlot("shield"); + Game1.GameManager.RemoveItem("shield", 99); + Game1.GameManager.CollectItem(itemCollected, equipmentPosition); + } + else if (baseItem.Name == "shield") + { + var mirrorShield = Game1.GameManager.GetItem("mirrorShield"); + if (mirrorShield != null) + { + Game1.GameManager.PlaySoundEffect(item.SoundEffectName, true, 1, 0, item.TurnDownMusic); + return; + } + } + else if (itemCollected.Name == "stonelifter2") + { + equipmentPosition = Game1.GameManager.GetEquipmentSlot("stonelifter"); + Game1.GameManager.RemoveItem("stonelifter", 99); + Game1.GameManager.CollectItem(itemCollected, equipmentPosition); + } + else if (itemCollected.Name == "heartMeterFull") + { + Game1.GameManager.SetMusic(36, 2); + } + else if (itemCollected.Name == "heartMeter") + { + var heart = Game1.GameManager.GetItem("heartMeter"); + // hearts was expanded => show different dialog + if (heart?.Count == 3) + _additionalPickupDialog = "heartMeterFilled"; + } + + // hearth + if (item.Name == "heart") + { + Game1.GameManager.CurrentHealth += itemCollected.Count * 4; + + if (Game1.GameManager.CurrentHealth > Game1.GameManager.MaxHearths * 4) + Game1.GameManager.CurrentHealth = Game1.GameManager.MaxHearths * 4; + } + // pick up item is an accessory + else if ((item.ShowAnimation == 1 || item.ShowAnimation == 2) && showItem) + { + // stop player movement + _body.Velocity = Vector3.Zero; + _body.VelocityTarget = Vector2.Zero; + _moveVelocity = Vector2.Zero; + _hitVelocity = Vector2.Zero; + + // pick up and show an item + ShowItem = item; + + // hold the item over the head with one or two hands (to the left side or the middle) + if (item.ShowAnimation == 1) + _showItemOffset.X = 0; + else + _showItemOffset.X = -4; + + _showItemOffset.Y = -15; + + if (ShowItem.Name == "guardianAcorn") + Game1.GameManager.InitGuardianAcorn(); + else if (ShowItem.Name == "pieceOfPower") + Game1.GameManager.InitPieceOfPower(); + + // @HACK: piece of power shows the sword image when picked up + if (ShowItem.Name == "pieceOfPower") + { + var swordItem = Game1.GameManager.GetItem("sword1"); + if (swordItem != null && swordItem.Count > 0) + ShowItem = Game1.GameManager.ItemManager["sword1PoP"]; + else + ShowItem = Game1.GameManager.ItemManager["sword2PoP"]; + } + + // make sure to use the right source rectangle if the shown item does not have one + var sourceRectangle = ShowItem.SourceRectangle ?? baseItem.SourceRectangle.Value; + if (ShowItem.MapSprite != null) + sourceRectangle = ShowItem.MapSprite.SourceRectangle; + else if (baseItem.MapSprite != null) + sourceRectangle = baseItem.MapSprite.SourceRectangle; + + // spawn pickup animation + if (item.ShowEffect) + Map.Objects.SpawnObject(new ObjPickupAnimation(Map, + EntityPosition.X + _showItemOffset.X, EntityPosition.Y - EntityPosition.Z + _showItemOffset.Y - sourceRectangle.Height / 2)); + + _showItemOffset -= new Vector2(sourceRectangle.Width / 2f, sourceRectangle.Height); + + CurrentState = State.PickingUp; + Game1.GameManager.SaveManager.SetString("player_shows_item", "1"); + Animation.Play("show" + item.ShowAnimation); + _itemShowCounter = item.ShowTime; + _showItem = true; + + // make sure to collect the item the player is currently showing + if (_collectedShowItem != null) + Game1.GameManager.CollectItem(_collectedShowItem, 0); + + _collectedShowItem = itemCollected; + + if (ShowItem.Name == "sword2") + { + _shownSwordLv2Dialog = false; + _showSwordL2ParticleCounter = 0; + CurrentState = State.SwordShowLv2; + } + + // not sure if this is what should happen here + ReleaseCarriedObject(); + } + else + { + Game1.GameManager.CollectItem(itemCollected, equipmentPosition); + } + + if (item.Name.StartsWith("instrument")) + { + // stop playing music + Game1.GameManager.SetMusic(26, 2); + + _instrumentPickupTime = Game1.TotalGameTime; + + _instrumentIndex = int.Parse(item.Name.Replace("instrument", "")); + _pickingUpInstrument = true; + } + + if (item.PickUpDialog != null && !_showItem && showDialog) + { + Game1.GameManager.StartDialogPath(item.PickUpDialog); + } + + // play sound + if (playSound && item.SoundEffectName != null) + Game1.GameManager.PlaySoundEffect(item.SoundEffectName, true, 1, 0, item.TurnDownMusic); + if (item.MusicName >= 0) + Game1.GameManager.SetMusic(item.MusicName, 1); + } + + #region map change + + public void SetNextMapPosition(Vector2 playerPosition) + { + // this will be used to set the position of the player after loading the map + // one of them should always be null + // the playerPosition is used after loading a savestate + NextMapPositionStart = playerPosition; + NextMapPositionEnd = playerPosition; + + NextMapPositionId = null; + } + + public void SetNextMapPosition(string nextMapPositionId) + { + // this will be used to set the position of the player after loading the map + // one of them should always be null + // the nextMapPositionId is used after going though a door + NextMapPositionId = nextMapPositionId; + + NextMapPositionStart = null; + NextMapPositionEnd = null; + } + + public void OnAppendMapChange() + { + if (_objMaria != null) + _objMaria.OnAppendMapChange(); + } + + public void StartTransitioning() + { + IsTransitioning = true; + + _drawBody.Layer = Values.LayerTop; + + // if the transitioning starts from a jump the player would have no animation otherwise + //_moved = true; + _isWalking = true; + _bootsRunning = false; + + // stole item? + if (StoreItem != null) + StealItem(); + + ReleaseCarriedObject(); + + // release the cock if link is flying + if (MapManager.ObjLink.IsFlying()) + MapManager.ObjLink.StopFlying(); + + // make sure the player walks + if (MapTransitionStart.HasValue && MapTransitionEnd.HasValue && + CurrentState != State.Swimming && CurrentState != State.BedTransition && CurrentState != State.Knockout && CurrentState != State.OcarinaTelport) + CurrentState = State.Idle; + + _body.VelocityTarget = Vector2.Zero; + + if (Map.Is2dMap) + { + if (_ladderCollision) + { + _isClimbing = true; + Direction = 1; + } + + // prefent the player from falling down while climbing up a ladder + //if ((Direction % 2) != 0) + _body.IgnoresZ = true; + // fall down + //else if (_body.Velocity.Y < 0) + _body.Velocity.Y = 0.0f; + } + else + { + _body.Velocity = Vector3.Zero; + } + } + + public void UpdateMapTransitionOut(float state) + { + if (MapTransitionStart.HasValue && MapTransitionEnd.HasValue) + { + var newPosition = Vector2.Lerp(MapTransitionStart.Value, MapTransitionEnd.Value, state); + + // fall down to the ground + //if (Map.Is2dMap && (Direction % 2) == 0) + // newPosition.Y = EntityPosition.Y; + + SetPosition(newPosition); + } + + // lock the camera while transitioning + if (!Map.Is2dMap || Direction == 1) + Game1.GameManager.MapManager.UpdateCameraY = MapTransitionStart == MapTransitionEnd; + + _isWalking = TransitionOutWalking; + + if (Is2DMode) + UpdateAnimation2D(); + else + UpdateAnimation(); + } + + public void UpdateMapTransitionIn(float state) + { + // make sure to not start falling while transitioning into a 2d map with a ladder + if (state == 0 && Map.Is2dMap) + _body.IgnoresZ = true; + + if (DirectionEntry >= 0) + Direction = DirectionEntry; + + if (NextMapPositionStart.HasValue && NextMapPositionEnd.HasValue) + { + var newPosition = Vector2.Lerp(NextMapPositionStart.Value, NextMapPositionEnd.Value, state); + SetPosition(newPosition); + + // transition the follower out + if (_objFollower != null && NextMapPositionStart.Value != NextMapPositionEnd.Value) + { + var followerPosition = Vector2.Lerp(NextMapPositionStart.Value, NextMapPositionEnd.Value, state * 0.5f); + _objFollower.SetPosition(followerPosition); + } + } + + // lock the camera while transitioning + if (!Map.Is2dMap || Direction == 1) + Game1.GameManager.MapManager.UpdateCameraY = NextMapPositionStart == NextMapPositionEnd; + + _isWalking = TransitionInWalking; + + // set the hole and water reset position to be at the transition entrance + _holeResetPoint = EntityPosition.Position; + _drownResetPosition = EntityPosition.Position; + + UpdateSwimming(); + + UpdateIgnoresZ(); + + if (Is2DMode) + UpdateAnimation2D(); + else + UpdateAnimation(); + } + + public void EndTransitioning() + { + _body.HoleAbsorption = Vector2.Zero; + + IsTransitioning = false; + + if (!Map.Is2dMap) + { + _body.Velocity.X = 0; + _body.Velocity.Y = 0; + } + + // this is because the water is deeper than 0 + if ((SystemBody.GetFieldState(_body) & MapStates.FieldStates.DeepWater) == 0 && CurrentState != State.Swimming && !_isClimbing) + _body.IgnoresZ = false; + + _drawBody.Layer = Values.LayerPlayer; + + MapManager.Camera.CameraFollowMultiplier = 1.0f; + + if (_showStealMessage) + { + _showStealMessage = false; + Game1.GameManager.StartDialogPath("shopkeeper_steal"); + } + + // restart the music + if (Game1.GameManager.PieceOfPowerIsActive || Game1.GameManager.GuardianAcornIsActive) + Game1.GameManager.StartPieceOfPowerMusic(); + } + + #endregion + + public Vector2 GetSwimVelocity() + { + return _swimVelocity; + } + + public ObjMarin GetMarin() + { + return _objMaria; + } + + #endregion + + #region is functions + + public bool IsDiving() + { + return _diveCounter > 0; + } + + public bool IsGrounded() + { + return _body.IsGrounded && !_railJump && !_isFlying; + } + + public bool IsJumping() + { + return CurrentState == State.Jumping; + } + + public bool IsRailJumping() + { + return _railJump; + } + + public bool IsHoleAbsorb() + { + return _isFallingIntoHole; + } + + public bool IsDashing() + { + return _bootsRunning; + } + + public bool IsStunned() + { + return CurrentState == State.Stunned; + } + + public bool IsTrapped() + { + return _isTrapped; + } + + public bool IsFlying() + { + return _isFlying && CurrentState == State.Carrying; + } + + public bool IsUsingHookshot() + { + return CurrentState == State.Hookshot; + } + + #endregion + } +} diff --git a/InGame/GameObjects/ObjLink2d.cs b/InGame/GameObjects/ObjLink2d.cs new file mode 100644 index 0000000..e2af1ed --- /dev/null +++ b/InGame/GameObjects/ObjLink2d.cs @@ -0,0 +1,697 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.GameObjects.Base.Systems; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects +{ + public partial class ObjLink + { + public bool Fall2DEntry; + + private Vector2 _moveVector2D; + + private bool Is2DMode; + + // swim stuff + private const float MaxSwimSpeed2D = 0.65f; // speed in the original is 0.5f + private float _swimAnimationMult; + private int _swimDirection; + private bool _inWater; + private bool _wasInWater; + + // climb stuff + private const float ClimbSpeed = 0.7f; + private bool _isClimbing; + private bool _wasClimbing; + private bool _tryClimbing; + private bool _ladderCollision; + + // jump stuff + private double _jumpStartTime; + private bool _playedJumpAnimation; + private bool _waterJump; + + private bool _init; + private bool _spikeDamage; + + private void MapInit2D() + { + // start climbing it the player is touching a ladder at the init position + var box = Box.Empty; + if (Map.Objects.Collision(_body.BodyBox.Box, Box.Empty, Values.CollisionTypes.Ladder, 3, 0, ref box)) + { + _isWalking = true; + _isClimbing = true; + DirectionEntry = 1; + UpdateAnimation2D(); + } + else if (Fall2DEntry) + { + Fall2DEntry = false; + CurrentState = State.Jumping; + _body.Velocity.Y = 1.5f; + _playedJumpAnimation = true; + if (Direction != 0 && Direction != 2) + Direction = 2; + DirectionEntry = Direction; + Animation.Play("fall_" + Direction); + } + + // move down a little bit after coming from the top + if (DirectionEntry == 3) + _swimVelocity.Y = 0.4f; + + _init = true; + _swimAnimationMult = 0.75f; + EntityPosition.Z = 0; + _body.DeepWaterOffset = -9; + _jumpStartTime = 0; + + _swimDirection = DirectionEntry; + // look towards the middle of the map + if (DirectionEntry % 2 != 0) + _swimDirection = EntityPosition.X < Map.MapWidth * Values.TileSize / 2f ? 2 : 0; + } + + private void Update2DFrozen() + { + // make sure to not fall down while frozen + if (_isClimbing) + _body.Velocity.Y = 0; + } + + private void Update2D() + { + var initState = CurrentState; + + var box = Box.Empty; + // is the player touching a ladder? + _ladderCollision = Map.Objects.Collision(_body.BodyBox.Box, Box.Empty, Values.CollisionTypes.Ladder, 1, 0, ref box); + + if (!_ladderCollision && _isClimbing) + { + _isClimbing = false; + + if (CurrentState != State.Carrying) + { + _body.Velocity.Y = 0; + CurrentState = State.Idle; + } + } + + if (!_body.IsGrounded && !_isClimbing && (!_tryClimbing || !_ladderCollision) && + (CurrentState == State.Idle || CurrentState == State.Blocking) && + !_bootsRunning) + { + CurrentState = State.Jumping; + _waterJump = false; + + // if we get pushed down we change the direction in the push direction + // this does not work for all cases but we only need if for the evil eagle boss where it should work correctly + if (_body.LastAdditionalMovementVT.X != 0) + Direction = _body.LastAdditionalMovementVT.X < 0 ? 0 : 2; + + if (_wasClimbing) + { + // not ontop of a ladder + if (SystemBody.MoveBody(_body, new Vector2(0, 2), _body.CollisionTypes | Values.CollisionTypes.LadderTop, false, false, true) == Values.BodyCollision.None) + { + SystemBody.MoveBody(_body, new Vector2(0, -2), _body.CollisionTypes | Values.CollisionTypes.LadderTop, false, false, true); + + if (Math.Abs(_moveVector2D.X) >= Math.Abs(_moveVector2D.Y)) + Direction = _moveVector2D.X < 0 ? 0 : 2; + else + Direction = 1; + } + // aligned with the top of the ladder + else + { + _body.IsGrounded = true; + _body.Velocity.Y = _body.Gravity2D; + CurrentState = initState; + } + } + } + + if (_isClimbing && + CurrentState != State.Attacking && CurrentState != State.PickingUp && + CurrentState != State.Dying && CurrentState != State.Blocking && + CurrentState != State.PreCarrying && CurrentState != State.Carrying && + CurrentState != State.Hookshot && CurrentState != State.MagicRod && + CurrentState != State.Powdering && CurrentState != State.Throwing) + CurrentState = State.Idle; + + var inLava = (_body.CurrentFieldState & MapStates.FieldStates.Lava) != 0; + _inWater = (_body.CurrentFieldState & MapStates.FieldStates.DeepWater) != 0 || inLava; + + if (_init) + _wasInWater = _inWater; + + // need to make sure to play the animation when the player walks over a cliff + if (_body.IsGrounded || _isClimbing) + _playedJumpAnimation = false; + + // is the player in deep water? + if (_inWater) + { + if (!_wasInWater) + { + _swimDirection = Direction; + if (_swimDirection % 2 != 0) + _swimDirection = 0; + } + + // start swimming if the player has flippers + if (HasFlippers && !inLava) + { + if (!_wasInWater) + { + _swimVelocity.X = _body.VelocityTarget.X * 0.35f; + _swimVelocity.Y = _isClimbing ? _body.VelocityTarget.Y * 0.35f : _body.Velocity.Y; + _body.Velocity = Vector3.Zero; + } + + if (CurrentState != State.Attacking && + CurrentState != State.PickingUp && + CurrentState != State.Hookshot && + CurrentState != State.Bombing && + CurrentState != State.Powdering && + CurrentState != State.MagicRod && + CurrentState != State.Dying && + CurrentState != State.PreCarrying) + CurrentState = State.Swimming; + + _isClimbing = false; + } + else + { + if (CurrentState != State.Drowning && CurrentState != State.Drowned) + { + _body.Velocity = Vector3.Zero; + _body.Velocity.X = _lastMoveVelocity.X * 0.25f; + + if (CurrentState != State.Dying) + { + Game1.GameManager.PlaySoundEffect("D370-03-03"); + + CurrentState = State.Drowning; + _isClimbing = false; + _drownCounter = 650; + + // blink in lava + _hitCount = inLava ? CooldownTime : 0; + } + } + } + } + // jump a little bit out of the water + else if (CurrentState == State.Swimming) + { + Direction = _swimDirection; + _lastMoveVelocity.X = _body.VelocityTarget.X; + + // jump out of the water? + if (_swimVelocity.Y < -MaxSwimSpeed2D) + { + CurrentState = State.Idle; + Jump2D(); + } + // just jump up a little out of the water + else + { + CurrentState = State.Jumping; + _body.Velocity.Y = -0.75f; + _playedJumpAnimation = true; + _waterJump = true; + } + } + + if (CurrentState == State.Drowning) + { + if (_drownCounter < 300) + { + _body.Velocity = Vector3.Zero; + // align the player to the pixel grid + EntityPosition.Set(new Vector2( + MathF.Round(EntityPosition.X), MathF.Round(EntityPosition.Y))); + } + + _drownCounter -= Game1.DeltaTime; + if (_drownCounter <= 0) + { + IsVisible = false; + CurrentState = State.Drowned; + _drownResetCounter = 500; + } + } + else if (CurrentState == State.Drowned) + { + _body.Velocity = Vector3.Zero; + + _drownResetCounter -= Game1.DeltaTime; + if (_drownResetCounter <= 0) + { + CurrentState = State.Idle; + CanWalk = true; + IsVisible = true; + + _hitCount = CooldownTime; + Game1.GameManager.CurrentHealth -= 2; + + _body.CurrentFieldState = MapStates.FieldStates.None; + EntityPosition.Set(_drownResetPosition); + } + } + + _body.IgnoresZ = _inWater || _hookshotPull; + + // walk + UpdateWalking2D(); + + // swimming + UpdateSwimming2D(); + + // update the animation + UpdateAnimation2D(); + + if (_isClimbing) + _body.Velocity.Y = 0; + + // first frame getting hit + if (_hitCount == CooldownTime) + { + if (_hitVelocity != Vector2.Zero) + _hitVelocity.Normalize(); + + _hitVelocity *= 1.75f; + + _swimVelocity *= 0.25f; + + // repell the player up and in the direction the player came from + if (_spikeDamage) + { + _hitVelocity *= 0.85f; + + if (_moveVector2D.X < 0) + _hitVelocity += new Vector2(2, 0); + else if (_moveVector2D.X > 0) + _hitVelocity += new Vector2(-2, 0); + + _body.Velocity.X = _hitVelocity.X; + _body.Velocity.Y = _hitVelocity.Y; + _hitVelocity = Vector2.Zero; + } + } + + _spikeDamage = false; + + if (_hitCount > 0) + _hitVelocity *= (float)Math.Pow(0.9f, Game1.TimeMultiplier); + else + _hitVelocity = Vector2.Zero; + + // slows down the walk movement when the player is hit + var moveMultiplier = MathHelper.Clamp(1f - _hitVelocity.Length(), 0, 1); + + // move the player + if (CurrentState != State.Hookshot) + _body.VelocityTarget = _moveVector2D * moveMultiplier + _hitVelocity; + + // remove ladder collider while climbing + if (_isClimbing || _tryClimbing) + _body.CollisionTypes &= ~(Values.CollisionTypes.LadderTop); + else if (CurrentState == State.Jumping) + { + // only collide with the top of a ladder block + _body.CollisionTypes |= Values.CollisionTypes.LadderTop; + } + else + _body.CollisionTypes |= Values.CollisionTypes.LadderTop; + + // save the last position the player is grounded to use for the reset position if the player drowns + if (_body.IsGrounded) + { + var bodyCenter = new Vector2(EntityPosition.X, EntityPosition.Y); + // center the position + // can lead to the position being inside something + bodyCenter.X = (int)(bodyCenter.X / 16) * 16 + 8; + + // found new reset position? + var bodyBox = new Box(bodyCenter.X + _body.OffsetX, bodyCenter.Y + _body.OffsetY, 0, _body.Width, _body.Height, _body.Depth); + var bodyBoxFloor = new Box(bodyCenter.X + _body.OffsetX, bodyCenter.Y + _body.OffsetY + 1, 0, _body.Width, _body.Height, _body.Depth); + var cBox = Box.Empty; + + // check it the player is not standing inside something; why??? + if (//!Game1.GameManager.MapManager.CurrentMap.Objects.Collision(bodyBox, Box.Empty, _body.CollisionTypes, 0, 0, ref cBox) && + Map.Objects.Collision(bodyBoxFloor, Box.Empty, _body.CollisionTypes, Values.CollisionTypes.MovingPlatform, 0, 0, ref cBox)) + _drownResetPosition = bodyCenter; + } + + _wasClimbing = _isClimbing; + _wasInWater = _inWater; + _init = false; + } + + private void UpdateAnimation2D() + { + var shieldString = Game1.GameManager.ShieldLevel == 2 ? "ms_" : "s_"; + if (!CarryShield) + shieldString = "_"; + + // start the jump animation + if (CurrentState == State.Jumping && !_playedJumpAnimation) + { + Animation.Play("jump_" + Direction); + _playedJumpAnimation = true; + } + + if (_bootsHolding || _bootsRunning) + { + if (!_bootsRunning) + Animation.Play("walk" + shieldString + Direction); + else + { + // run while blocking with the shield + Animation.Play((CarryShield ? "walkb" : "walk") + shieldString + Direction); + } + + Animation.SpeedMultiplier = 2.0f; + return; + } + + Animation.SpeedMultiplier = 1.0f; + + if ((CurrentState != State.Jumping || !Animation.IsPlaying || _waterJump) && CurrentState != State.Attacking) + { + if (CurrentState == State.Jumping) + Animation.Play("fall_" + Direction); + else if (CurrentState == State.Idle) + { + if (_isWalking || _isClimbing) + { + var newAnimation = "walk" + shieldString + Direction; + + if (Animation.CurrentAnimation.Id != newAnimation) + Animation.Play(newAnimation); + else if (_isClimbing) + // continue/pause the animation + Animation.IsPlaying = _isWalking; + } + else + Animation.Play("stand" + shieldString + Direction); + } + else if (!_isWalking && CurrentState == State.Charging) + Animation.Play("stand" + shieldString + Direction); + else if (CurrentState == State.Carrying) + Animation.Play((_isWalking ? "walkc_" : "standc_") + Direction); + else if (_isWalking && CurrentState == State.Charging) + Animation.Play("walk" + shieldString + Direction); + else if (CurrentState == State.Blocking) + Animation.Play((!_isWalking ? "standb" : "walkb") + shieldString + Direction); + else if (CurrentState == State.Grabbing) + Animation.Play("grab_" + Direction); + else if (CurrentState == State.Pulling) + Animation.Play("pull_" + Direction); + else if (CurrentState == State.Swimming) + { + Animation.Play("swim_2d_" + _swimDirection); + Animation.SpeedMultiplier = _swimAnimationMult; + } + // TODO: create a different sprite for 2d drowning + else if (CurrentState == State.Drowning) + Animation.Play(_drownCounter > 300 ? "swim_" + _swimDirection : "dive"); + } + } + + private void UpdateWalking2D() + { + _isWalking = false; + + if ((CurrentState != State.Idle && CurrentState != State.Jumping && + CurrentState != State.Carrying && CurrentState != State.Blocking && + CurrentState != State.Charging && CurrentState != State.Attacking && + (CurrentState != State.MagicRod || _body.IsGrounded || _isClimbing)) || _inWater) + { + _moveVector2D = Vector2.Zero; + _lastBaseMoveVelocity = _moveVector2D; + return; + } + + var walkVelocity = Vector2.Zero; + if (!_isLocked && (CurrentState != State.Attacking || !_body.IsGrounded)) + walkVelocity = ControlHandler.GetMoveVector2(); + + var walkVelLength = walkVelocity.Length(); + var vectorDirection = ToDirection(walkVelocity); + + // start climbing? + if (_ladderCollision && ((walkVelocity.Y != 0 && Math.Abs(walkVelocity.X) <= Math.Abs(walkVelocity.Y)) || _tryClimbing) && _jumpStartTime + 175 < Game1.TotalGameTime) + { + _isClimbing = true; + _tryClimbing = false; + } + // try climbing down? + else if (walkVelocity.Y > 0 && Math.Abs(walkVelocity.X) <= Math.Abs(walkVelocity.Y) && !_bootsRunning) + { + if (_tryClimbing && !_isHoldingSword) + Direction = 3; + + _tryClimbing = true; + } + else + _tryClimbing = false; + + if (_isClimbing && _ladderCollision) + { + _moveVector2D = walkVelocity * ClimbSpeed; + _lastMoveVelocity = new Vector2(_moveVector2D.X, 0); + + if (_isClimbing) + Direction = 1; + } + // boot running; stop if the player tries to move in the opposite direction + else if (_bootsRunning && (walkVelLength < Values.ControllerDeadzone || vectorDirection != (Direction + 2) % 4)) + { + if (!_bootsStop) + _moveVector2D = AnimationHelper.DirectionOffset[Direction] * 2; + + _lastMoveVelocity = _moveVector2D; + } + // normally walking on the floor + else if (walkVelLength > Values.ControllerDeadzone) + { + // if the player is walking he is walking left or right + if (walkVelocity.X != 0) + walkVelocity.Y = 0; + + // update the direction if not attacking/charging + var newDirection = AnimationHelper.GetDirection(walkVelocity); + + // reset boot counter if the player changes the direction + if (newDirection != Direction) + _bootsCounter %= _bootsParticleTime; + _bootsRunning = false; + + if (CurrentState != State.Charging && CurrentState != State.Attacking && CurrentState != State.Jumping && newDirection != 3) + Direction = newDirection; + + if (_body.IsGrounded) + { + _moveVector2D = new Vector2(walkVelocity.X, 0); + _lastMoveVelocity = _moveVector2D; + } + } + else if (_body.IsGrounded) + { + _moveVector2D = Vector2.Zero; + _lastMoveVelocity = Vector2.Zero; + } + + // the player has momentum when he is in the air and can not be controlled directly like on the ground + if (!_body.IsGrounded && !_isClimbing) + { + walkVelocity.Y = 0; + + var distance = (_lastMoveVelocity - walkVelocity * _currentWalkSpeed).Length(); + + if (distance > 0 && walkVelocity != Vector2.Zero) + { + // we make sure that when walkVelocity is pointing in the same direction as _lastMoveVelocity we do not decrease the velocity if walkVelocity is smaller + var direction = walkVelocity; + direction.Normalize(); + var speed = Math.Max(walkVelocity.Length(), _lastMoveVelocity.Length()); + _lastMoveVelocity = AnimationHelper.MoveToTarget(_lastMoveVelocity, direction * speed, 0.05f * Game1.TimeMultiplier); + } + + _moveVector2D = _lastMoveVelocity; + + // update the direction if the player goes left or right in the air + // only update the animation after the jump animation was played + if (CurrentState == State.Jumping && _moveVector2D != Vector2.Zero && _playedJumpAnimation) + { + var newDirection = AnimationHelper.GetDirection(_moveVector2D); + if (newDirection % 2 == 0) + Direction = newDirection; + } + } + + if (_moveVector2D.X != 0 || (_isClimbing && _moveVector2D.Y != 0)) + _isWalking = true; + + _lastBaseMoveVelocity = _moveVector2D; + } + + private void UpdateSwimming2D() + { + if (!_inWater || CurrentState == State.Drowning || CurrentState == State.Drowned) + return; + + // direction can only be 0 or 2 while swimming + if (Direction % 2 != 0) + Direction = _swimDirection; + + var moveVector = Vector2.Zero; + if (!_isLocked && CurrentState != State.Attacking) + moveVector = ControlHandler.GetMoveVector2(); + + var moveVectorLength = moveVector.Length(); + moveVectorLength = Math.Clamp(moveVectorLength, 0, MaxSwimSpeed2D); + + if (moveVectorLength > Values.ControllerDeadzone) + { + moveVector.Normalize(); + moveVector *= moveVectorLength; + + // accelerate to the target velocity + var distance = (moveVector - _swimVelocity).Length(); + var lerpPercentage = MathF.Min(1, (0.0225f * Game1.TimeMultiplier) / distance); + _swimVelocity = Vector2.Lerp(_swimVelocity, moveVector, lerpPercentage); + + Game1.DebugText += "\n" + lerpPercentage; + + _swimAnimationMult = moveVector.Length() / MaxSwimSpeed2D; + + Direction = AnimationHelper.GetDirection(moveVector); + if (moveVector.X != 0) + _swimDirection = moveVector.X < 0 ? 0 : 2; + } + else + { + // slows down and stop + var distance = _swimVelocity.Length(); + var lerpPercentage = MathF.Min(1, (0.0225f / distance) * Game1.TimeMultiplier); + _swimVelocity = Vector2.Lerp(_swimVelocity, Vector2.Zero, lerpPercentage); + + _swimAnimationMult = Math.Max(0.35f, _swimVelocity.Length() / MaxSwimSpeed2D); + } + + _moveVector2D = _swimVelocity; + _lastMoveVelocity.X = _swimVelocity.X; + } + + private void Jump2D() + { + // TODO: In 2d you can adjust the jump height by pressing shorter/longer + + // swim faster + if (CurrentState == State.Swimming) + _swimVelocity.Y = -0.9f; + + if (CurrentState == State.Carrying || + (CurrentState != State.Idle && + CurrentState != State.Attacking && + CurrentState != State.Charging)) + return; + + + if (!_body.IsGrounded && !_wasInWater && !_isClimbing) + return; + + if (_isClimbing) + { + if (Math.Abs(_moveVector2D.X) > Math.Abs(_moveVector2D.Y)) + Direction = _moveVector2D.X < 0 ? 0 : 2; + else + Direction = 1; + } + + Game1.GameManager.PlaySoundEffect("D360-13-0D"); + + _jumpStartTime = Game1.TotalGameTime; + + _body.IsGrounded = false; + _body.Velocity.Y = _isClimbing ? -1.5f : -1.9f; + _moveVector2D = Vector2.Zero; + + + _isClimbing = false; + _waterJump = false; + + // while attacking the player can still jump but without the animation + if (CurrentState != State.Attacking && + CurrentState != State.Charging) + { + _playedJumpAnimation = false; + CurrentState = State.Jumping; + } + else + { + _playedJumpAnimation = true; + } + } + + private void OnMoveCollision2D(Values.BodyCollision collision) + { + // prevent the body from trying to move up and directly falling down in the next step + if ((collision & Values.BodyCollision.Horizontal) != 0 && !_isClimbing) + _body.SlideOffset = Vector2.Zero; + + // collision with the ground + if ((collision & Values.BodyCollision.Bottom) != 0) + { + // we cant use the check because the player can attack while jumping and avoid the jump animation the next time + if (CurrentState == State.Jumping || + CurrentState == State.BootKnockback) + { + CurrentState = State.Idle; + Game1.GameManager.PlaySoundEffect("D378-07-07"); + } + } + // collision with the ceiling + else if ((collision & Values.BodyCollision.Top) != 0) + { + _body.Velocity.Y = 0; + } + else if ((collision & Values.BodyCollision.Horizontal) != 0) + { + _lastMoveVelocity = Vector2.Zero; + _swimVelocity.X = 0; + } + + if ((collision & Values.BodyCollision.Vertical) != 0) + { + _hitVelocity.Y = 0; + _swimVelocity.Y = 0; + } + } + + public bool IsClimbing() + { + return _isClimbing; + } + + public bool IsInWater2D() + { + return _inWater; + } + + public void InflictSpikeDamage2D() + { + _spikeDamage = true; + } + } +} diff --git a/InGame/GameObjects/ObjLinkHelper.cs b/InGame/GameObjects/ObjLinkHelper.cs new file mode 100644 index 0000000..735172a --- /dev/null +++ b/InGame/GameObjects/ObjLinkHelper.cs @@ -0,0 +1,52 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.GameObjects +{ + public partial class ObjLink + { + /// + /// Check if the box is colliding with a destroyable wall + /// + private bool DestroyableWall(Box box) + { + _destroyableWallList.Clear(); + Map.Objects.GetComponentList(_destroyableWallList, (int)box.X, (int)box.Y, (int)box.Width + 1, (int)box.Height + 1, CollisionComponent.Mask); + + var collidingBox = Box.Empty; + foreach (var gameObject in _destroyableWallList) + { + var collisionObject = gameObject.Components[CollisionComponent.Index] as CollisionComponent; + if ((collisionObject.CollisionType & Values.CollisionTypes.Destroyable) != 0 && + collisionObject.Collision(box, 0, 0, ref collidingBox)) + { + return true; + } + } + + return false; + } + + /// + /// Get the direction with a tolerance in the current direction + /// + /// + /// + private int ToDirection(Vector2 direction) + { + int value; + + // this makes it so that if you start walking diagonal the player won't change the direction + var dirMultiply = (Direction == 0 || Direction == 2) ? 1.05f : 0.95f; + if (Math.Abs(direction.X) * dirMultiply > Math.Abs(direction.Y)) + value = direction.X > 0 ? 2 : 0; + else + value = direction.Y > 0 ? 3 : 1; + + return value; + } + } +} diff --git a/InGame/GameObjects/TestObjects/ObjTestObject.cs b/InGame/GameObjects/TestObjects/ObjTestObject.cs new file mode 100644 index 0000000..b6a3e39 --- /dev/null +++ b/InGame/GameObjects/TestObjects/ObjTestObject.cs @@ -0,0 +1,64 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + internal class ObjTestObject : GameObject + { + private BodyComponent _body; + + private double _spawnTime; + + public ObjTestObject(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(-2, -2, 4, 4); + + // this is the same size as the player so that it can not get thrown into the wall + _body = new BodyComponent(EntityPosition, -2, -2, 4, 4, 14) + { + CollisionTypes = + Values.CollisionTypes.Normal | + Values.CollisionTypes.NPCWall, + IgnoreHoles = true, + DragAir = 1.0f, + Drag = 1.0f, + Bounciness = 1.0f, + MoveCollision = OnMoveCollision + }; + + _spawnTime = Game1.TotalGameTime; + + var speed = 2.5f; + var direction = Game1.RandomNumber.Next(0, 1000) / 10f; + _body.VelocityTarget.X = MathF.Sin(direction) * speed; + _body.VelocityTarget.Y = MathF.Cos(direction) * speed; + + var cSprite = new CSprite("teleporter_outer", EntityPosition, new Vector2(-2, -2)); + + AddComponent(BodyComponent.Index, _body); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(cSprite, Values.LayerPlayer)); + } + + private void Update() + { + if (_spawnTime + 7500 < Game1.TotalGameTime) + { + Map.Objects.DeleteObjects.Add(this); + } + } + + private void OnMoveCollision(Values.BodyCollision collision) + { + if ((collision & Values.BodyCollision.Horizontal) != 0) + _body.VelocityTarget.X = -_body.VelocityTarget.X; + if ((collision & Values.BodyCollision.Vertical) != 0) + _body.VelocityTarget.Y = -_body.VelocityTarget.Y; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/TestObjects/ObjWaterCurrentTester.cs b/InGame/GameObjects/TestObjects/ObjWaterCurrentTester.cs new file mode 100644 index 0000000..5554c53 --- /dev/null +++ b/InGame/GameObjects/TestObjects/ObjWaterCurrentTester.cs @@ -0,0 +1,64 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.GameObjects.Dungeon +{ + internal class ObjWaterCurrentTester : GameObject + { + private BodyComponent _body; + + private double _spawnTime; + + public ObjWaterCurrentTester(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(-2, -2, 4, 4); + + // this is the same size as the player so that it can not get thrown into the wall + _body = new BodyComponent(EntityPosition, -2, -2, 4, 4, 14) + { + CollisionTypes = + Values.CollisionTypes.Normal | + Values.CollisionTypes.NPCWall, + IgnoreHoles = true, + DragAir = 1.0f, + Drag = 1.0f, + Bounciness = 1.0f, + //MoveCollision = OnMoveCollision + }; + + _spawnTime = Game1.TotalGameTime; + + //var speed = 2.5f; + //var direction = Game1.RandomNumber.Next(0, 1000) / 10f; + //_body.VelocityTarget.X = MathF.Sin(direction) * speed; + //_body.VelocityTarget.Y = MathF.Cos(direction) * speed; + + var cSprite = new CSprite("teleporter_outer", EntityPosition, new Vector2(-2, -2)); + + AddComponent(BodyComponent.Index, _body); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(cSprite, Values.LayerPlayer)); + } + + private void Update() + { + if (_spawnTime + 1000 < Game1.TotalGameTime) + { + Map.Objects.DeleteObjects.Add(this); + } + } + + //private void OnMoveCollision(Values.BodyCollision collision) + //{ + // if ((collision & Values.BodyCollision.Horizontal) != 0) + // _body.VelocityTarget.X = -_body.VelocityTarget.X; + // if ((collision & Values.BodyCollision.Vertical) != 0) + // _body.VelocityTarget.Y = -_body.VelocityTarget.Y; + //} + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjAnimatedShiftedTile.cs b/InGame/GameObjects/Things/ObjAnimatedShiftedTile.cs new file mode 100644 index 0000000..1a956ce --- /dev/null +++ b/InGame/GameObjects/Things/ObjAnimatedShiftedTile.cs @@ -0,0 +1,59 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjAnimatedShiftedTile : GameObject + { + private readonly CSprite _sprite; + private readonly Rectangle _sourceRectangle; + private readonly int _offsetX; + private readonly int _offsetY; + + private readonly int _frames; + private readonly int _animationSpeed; + + public ObjAnimatedShiftedTile(Map.Map map, int posX, int posY, + Rectangle sourceRectangle, int offsetX, int offsetY, int animationSpeed, int spriteEffect) : base(map) + { + SprEditorImage = Resources.SprObjects; + EditorIconSource = sourceRectangle; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, sourceRectangle.Width, sourceRectangle.Height); + + _sourceRectangle = sourceRectangle; + _offsetX = offsetX; + _offsetY = offsetY; + _animationSpeed = animationSpeed; + + _sprite = new CSprite(Resources.SprObjects, EntityPosition, sourceRectangle, Vector2.Zero) + { + SpriteEffect = (SpriteEffects)spriteEffect + }; + + _frames = Math.Min( + _sourceRectangle.Width / Math.Max(1, Math.Abs(offsetX)), + _sourceRectangle.Height / Math.Max(1, Math.Abs(offsetY))); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerBottom)); + } + + private void Update() + { + // all the animations are in sync + var currentFrame = (int)Game1.TotalGameTime % (_frames * _animationSpeed) / _animationSpeed; + + _sprite.SourceRectangle = new Rectangle( + _sourceRectangle.X + _offsetX * currentFrame, + _sourceRectangle.Y + _offsetY * currentFrame, + _sourceRectangle.Width, _sourceRectangle.Height); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjAnimatedTile.cs b/InGame/GameObjects/Things/ObjAnimatedTile.cs new file mode 100644 index 0000000..4da07cb --- /dev/null +++ b/InGame/GameObjects/Things/ObjAnimatedTile.cs @@ -0,0 +1,100 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjAnimatedTile : GameObject + { + public readonly CSprite Sprite; + + private readonly Rectangle _sourceRectangle; + + private int _currentFrame; + private float _timeCounter; + + private readonly int _frames; + private readonly int _animationSpeed; + + // TODO_OPT: should probably only switch the tilemap values + // one object could update a lot of tiles in the tilemap + // would be better for performance + public ObjAnimatedTile(Map.Map map, int posX, int posY, + string spriteId, int frames, int animationSpeed, bool sync, int spriteEffects, int drawLayer) : base(map) + { + var sprite = Resources.GetSprite(spriteId); + + _sourceRectangle = sprite.ScaledRectangle; + + SprEditorImage = sprite.Texture; + EditorIconSource = _sourceRectangle; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, _sourceRectangle.Width, _sourceRectangle.Height); + + _frames = frames; + _animationSpeed = animationSpeed; + Sprite = new CSprite(sprite.Texture, EntityPosition, _sourceRectangle, Vector2.Zero) + { + Scale = sprite.Scale, + SpriteEffect = (SpriteEffects)spriteEffects + }; + + AddComponent(UpdateComponent.Index, new UpdateComponent(sync ? UpdateSync : UpdateNoSync)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(Sprite, drawLayer)); + + // randomize the starting state of the animation + if (!sync) + RandomizeStartFrame(); + } + + public void RandomizeStartFrame() + { + var pX = EntityPosition.X / 200f; + var pY = EntityPosition.Y / 200f; + _timeCounter = (int)((pX * pX + pY * pY) * 30f); + + while (_timeCounter >= _animationSpeed) + { + _currentFrame++; + if (_currentFrame >= _frames) + _currentFrame = 0; + + _timeCounter -= _animationSpeed; + } + } + + public void UpdateSync() + { + // all the animations are in sync + _currentFrame = (int)Game1.TotalGameTime % + (_frames * _animationSpeed) / _animationSpeed; + + UpdateSourceRectangle(); + } + + public void UpdateNoSync() + { + _timeCounter += Game1.DeltaTime; + + if (_timeCounter > _animationSpeed) + { + _currentFrame++; + _timeCounter -= _animationSpeed; + + if (_currentFrame >= _frames) + _currentFrame = 0; + + UpdateSourceRectangle(); + } + } + + public void UpdateSourceRectangle() + { + Sprite.SourceRectangle.X = _sourceRectangle.X + _sourceRectangle.Width * _currentFrame; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjAnimator.cs b/InGame/GameObjects/Things/ObjAnimator.cs new file mode 100644 index 0000000..0358b6e --- /dev/null +++ b/InGame/GameObjects/Things/ObjAnimator.cs @@ -0,0 +1,55 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjAnimator : GameObject + { + public Animator Animator; + public AnimationComponent AnimationComponent; + public CSprite Sprite; + + public ObjAnimator(Map.Map map, int posX, int posY, int offsetX, int offsetY, + int layer, string animatorName, string animationName, bool deleteOnFinish) : base(map) + { + SprEditorImage = Resources.SprItem; + EditorIconSource = new Rectangle(64, 168, 16, 16); + + EntityPosition = new CPosition(posX, posY, 0); + + Animator = AnimatorSaveLoad.LoadAnimator(animatorName); + + // this should never happen... + if (Animator == null) + { + Console.WriteLine("Error: could not load animation \"{0}\"", animatorName); + IsDead = true; + return; + } + + Animator.Play(animationName); + + EntitySize = new Rectangle( + offsetX + Animator.CurrentAnimation.Offset.X + Animator.CurrentAnimation.AnimationLeft, + offsetY + Animator.CurrentAnimation.Offset.Y + Animator.CurrentAnimation.AnimationTop, + Animator.CurrentAnimation.AnimationWidth, Animator.CurrentAnimation.AnimationHeight); + + Sprite = new CSprite(EntityPosition); + AnimationComponent = new AnimationComponent(Animator, Sprite, new Vector2(offsetX, offsetY)); + if (deleteOnFinish) + Animator.OnAnimationFinished = () => Map.Objects.DeleteObjects.Add(this); + + AddComponent(BaseAnimationComponent.Index, AnimationComponent); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(Sprite, layer)); + } + + public ObjAnimator(Map.Map map, int posX, int posY, int layer, string animatorName, string animationName, + bool deleteOnFinish) : this(map, posX, posY, 0, 0, layer, animatorName, animationName, deleteOnFinish) + { } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjAquaticPlant.cs b/InGame/GameObjects/Things/ObjAquaticPlant.cs new file mode 100644 index 0000000..f99e388 --- /dev/null +++ b/InGame/GameObjects/Things/ObjAquaticPlant.cs @@ -0,0 +1,58 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjAquaticPlant : GameObject + { + private readonly CSprite _topPlant; + private readonly CSprite _bottomPlant; + + private double _counter; + + private readonly float _topLeafDivider; + private readonly float _bottomLeafDivider; + + public ObjAquaticPlant() : base("aquatic_plant") { } + + public ObjAquaticPlant(Map.Map map, int posX, int posY) : base(map) + { + var sourceTop = Resources.SourceRectangle("aquatic_plant_top"); + var sourceBottom = Resources.SourceRectangle("aquatic_plant_bottom"); + + EntityPosition = new CPosition(posX, posY + 16, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + _topPlant = new CSprite(Resources.SprObjects, new CPosition(posX + 1, posY, 0), sourceTop, Vector2.Zero); + _bottomPlant = new CSprite(Resources.SprObjects, new CPosition(posX + 7, posY + 10, 0), sourceBottom, Vector2.Zero); + + // so not all leafs move in parallel + _counter = Game1.RandomNumber.Next(0, 450); + _topLeafDivider = Game1.RandomNumber.Next(350, 450); + _bottomLeafDivider = Game1.RandomNumber.Next(250, 350); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBottom, EntityPosition)); + } + + public void Update() + { + _counter += Game1.DeltaTime; + + _topPlant.DrawOffset.X = (float)Math.Sin(_counter / _topLeafDivider); + _bottomPlant.DrawOffset.X = (float)Math.Sin(_counter / _bottomLeafDivider); + } + + public void Draw(SpriteBatch spriteBatch) + { + // draw top and bottom leafs + _topPlant.Draw(spriteBatch); + _bottomPlant.Draw(spriteBatch); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjArrow.cs b/InGame/GameObjects/Things/ObjArrow.cs new file mode 100644 index 0000000..979e394 --- /dev/null +++ b/InGame/GameObjects/Things/ObjArrow.cs @@ -0,0 +1,202 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjArrow : GameObject + { + private readonly Animator _animator; + private readonly AiComponent _aiComponent; + private readonly ShadowBodyDrawComponent _shadowBody; + private readonly CSprite _sprite; + private readonly BodyComponent _body; + private readonly BodyDrawComponent _drawComponent; + + private readonly CBox _damageBox; + + private const int DespawnTime = 375; + private const int FadeOutTime = 75; + + private float _despawnPercentage = 1; + private int _dir; + private bool _isFalling; + + private Vector2[] _bombOffset = new Vector2[] { new Vector2(-4, 0), new Vector2(0, -4), new Vector2(4, 0), new Vector2(0, 6) }; + private ObjBomb _objBomb; + private bool _bombMode; + + private Vector2 _startPosition; + private Point[] _collisionBoxSize = { new Point(2, 2), new Point(2, 2), new Point(2, 2), new Point(2, 2) }; + + public ObjArrow(Map.Map map, Vector3 position, int dir, float speed) : base(map) + { + EntityPosition = new CPosition(position.X, position.Y, position.Z); + EntitySize = new Rectangle(-8, -12, 16, 16); + + _startPosition = new Vector2(position.X, position.Y); + + _dir = dir; + var velocity = AnimationHelper.DirectionOffset[_dir] * speed; + + _animator = AnimatorSaveLoad.LoadAnimator("Objects/spear"); + _animator.Play(dir.ToString()); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero); + + _body = new BodyComponent(EntityPosition, + -_collisionBoxSize[dir].X / 2, -_collisionBoxSize[dir].Y / 2, + _collisionBoxSize[dir].X, _collisionBoxSize[dir].Y, 8) + { + CollisionTypes = Values.CollisionTypes.Normal, + CollisionTypesIgnore = Values.CollisionTypes.ThrowWeaponIgnore, + MoveCollision = OnCollision, + VelocityTarget = velocity, + Bounciness = 0.35f, + Drag = 0.75f, + DragAir = 0.95f, + Gravity = -0.025f, + IgnoreHeight = true, + IgnoresZ = true, + IgnoreInsideCollision = false, + Level = MapStates.GetLevel(MapManager.ObjLink._body.CurrentFieldState) + }; + + _damageBox = new CBox(EntityPosition, + -_collisionBoxSize[dir].X / 2 - 1, -_collisionBoxSize[dir].Y - 1, 0, + _collisionBoxSize[dir].X + 2, _collisionBoxSize[dir].Y + 2, 8); + + var stateIdle = new AiState(UpdateIdle); + var stateDespawn = new AiState() { Init = InitDespawn }; + stateDespawn.Trigger.Add(new AiTriggerCountdown(DespawnTime, TickDespawn, () => TickDespawn(0))); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("despawn", stateDespawn); + _aiComponent.ChangeState("idle"); + + _drawComponent = new BodyDrawComponent(_body, _sprite, Values.LayerPlayer); + + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + AddComponent(DrawShadowComponent.Index, _shadowBody = new ShadowBodyDrawComponent(EntityPosition)); + } + + private void UpdateIdle() + { + var distance = _startPosition - EntityPosition.Position; + if (Math.Abs(distance.X) > 112 || Math.Abs(distance.Y) > 96) + { + _isFalling = true; + _body.IgnoresZ = false; + + ExplodeBomb(); + } + + DealDamage(); + } + + private void ExplodeBomb() + { + if (!_bombMode) + return; + + _bombMode = false; + _objBomb.Explode(); + Map.Objects.DeleteObjects.Add(this); + } + + private void InitDespawn() + { + _body.Gravity = -0.1f; + _body.IgnoresZ = false; + + if (!_isFalling) + _body.Velocity = new Vector3(-_body.VelocityTarget.X * 0.35f, -_body.VelocityTarget.Y * 0.35f, 1f); + else + _body.Velocity = new Vector3(_body.VelocityTarget.X * 0.35f, _body.VelocityTarget.Y * 0.35f, 1f); + + _body.VelocityTarget = Vector2.Zero; + + _animator.Play(_dir == 2 ? "rotatel" : "rotate"); + _animator.SetFrame((_dir + 1) % 4); + + Game1.GameManager.PlaySoundEffect("D360-07-07"); + } + + private void TickDespawn(double time) + { + if (_animator.CurrentFrameIndex == (_dir + 2) % 4) + _animator.Pause(); + + _despawnPercentage = (float)(time / FadeOutTime); + if (_despawnPercentage > 1) + _despawnPercentage = 1; + + _sprite.Color = Color.White * _despawnPercentage; + _shadowBody.Transparency = _despawnPercentage; + + if (time <= 0) + Map.Objects.DeleteObjects.Add(this); + } + + private void OnCollision(Values.BodyCollision collision) + { + if (_aiComponent.CurrentStateId == "despawn") + return; + + _aiComponent.ChangeState("despawn"); + + // make sure the deal damage one last time + DealDamage(); + + ExplodeBomb(); + } + + private void DealDamage() + { + var collision = Map.Objects.Hit(this, EntityPosition.Position, _damageBox.Box, HitType.Bow, 2, false, false); + if ((collision & (Values.HitCollision.Blocking | Values.HitCollision.Enemy)) != 0) + { + Map.Objects.DeleteObjects.Add(this); + + ExplodeBomb(); + } + + if ((collision & Values.HitCollision.Repelling) != 0) + { + _aiComponent.ChangeState("despawn"); + + ExplodeBomb(); + } + } + + private void Draw(SpriteBatch spriteBatch) + { + _drawComponent.Draw(spriteBatch); + + // make sure to draw the bomb ontop of the arrow + if (_objBomb != null) + _objBomb.Draw(spriteBatch); + } + + public void InitBombMode(ObjBomb bomb) + { + _bombMode = true; + _objBomb = bomb; + _body.CollisionTypesIgnore = Values.CollisionTypes.None; + + EntityPosition.AddPositionListener(typeof(ObjBomb), (position) => bomb.EntityPosition.Set(position.Position + _bombOffset[_dir])); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjBackgroundColor.cs b/InGame/GameObjects/Things/ObjBackgroundColor.cs new file mode 100644 index 0000000..082af24 --- /dev/null +++ b/InGame/GameObjects/Things/ObjBackgroundColor.cs @@ -0,0 +1,38 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjBackgroundColor : GameObject + { + public Color BackgroundColor = Color.White; + public float Percentage; + + public ObjBackgroundColor() : base((Map.Map) null) + { + SprEditorImage = Resources.SprObjects; + EditorIconSource = new Rectangle(240, 16, 16, 16); + + // should be on top of every other object, + // except the player object but only while transitioning + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerTop, new CPosition(0, 0, 0))); + } + + private void Draw(SpriteBatch spriteBatch) + { + spriteBatch.End(); + + // draw the background + spriteBatch.Begin(); + spriteBatch.Draw(Resources.SprWhite, new Rectangle(0, 0, Game1.RenderWidth, Game1.RenderHeight), BackgroundColor * Percentage); + spriteBatch.End(); + + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, MapManager.Camera.TransformMatrix); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjBed.cs b/InGame/GameObjects/Things/ObjBed.cs new file mode 100644 index 0000000..2a97fe3 --- /dev/null +++ b/InGame/GameObjects/Things/ObjBed.cs @@ -0,0 +1,79 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameSystems; +using ProjectZ.InGame.Map; + +namespace ProjectZ.InGame.GameObjects.Things +{ + public class ObjBed : GameObject + { + private readonly string _nextMap; + private readonly string _lampKey; + + private bool _startBed; + private bool _startTransition; + + private const int TransitionTime = 2750; + private float _transitionCounter = TransitionTime; + private int _lightState; + + public ObjBed() : base("editor bed") { } + + public ObjBed(Map.Map map, int posX, int posY, string nextMap, string lampKey) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 32); + + _nextMap = nextMap; + _lampKey = lampKey; + + var boxPushable = new CBox(EntityPosition, 0, 0, 16, 32 - MapManager.ObjLink.BodyRectangle.Height, 8); + + AddComponent(PushableComponent.Index, new PushableComponent(boxPushable, OnPush)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType pushType) + { + _startBed = true; + + Game1.GameManager.SetMusic(29, 2); + + // jump into the bed + MapManager.ObjLink.StartRailJump(new Vector2(EntityPosition.X + 8, EntityPosition.Y + 21), 1, 1); + + MapManager.ObjLink.StartBedTransition(); + + return false; + } + + public void Update() + { + if (!_startBed || _startTransition) + return; + + _transitionCounter -= Game1.DeltaTime; + + // turn of the lights + if (_lightState < 4 && _transitionCounter < TransitionTime - 1000 - _lightState * 250) + { + _lightState++; + Game1.GameManager.SaveManager.SetString(_lampKey + _lightState, "0"); + } + + if (_transitionCounter < 0) + { + _startTransition = true; + + MapManager.ObjLink.MapTransitionStart = MapManager.ObjLink.EntityPosition.Position; + MapManager.ObjLink.MapTransitionEnd = MapManager.ObjLink.EntityPosition.Position; + + var transitionSystem = ((MapTransitionSystem)Game1.GameManager.GameSystems[typeof(MapTransitionSystem)]); + transitionSystem.AppendMapChange(_nextMap, "bed"); + transitionSystem.StartDreamTransition = true; + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjBoat.cs b/InGame/GameObjects/Things/ObjBoat.cs new file mode 100644 index 0000000..e1523f3 --- /dev/null +++ b/InGame/GameObjects/Things/ObjBoat.cs @@ -0,0 +1,238 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Systems; +using ProjectZ.InGame.GameObjects.NPCs; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjBoat : GameObject + { + private readonly ObjFishermanBoat _objFisherman; + + private readonly List _collidingObjects = new List(); + + private readonly CBox _moveBox; + private Box _lastBox; + + private readonly CBox _collisionBox; + private Box _lastCollisionBox; + + private readonly Vector2 _topPosition; + private readonly Vector2 _bottomPosition; + + private Vector2 _currentPosition; + private Vector2 _positionOffset; + + private Vector2 _newPosition; + + private float _velocity; + private float _offsetTime; + private bool _offset; + + private bool _isStandingOnTop; + + public ObjBoat() : base("boat") { } + + public ObjBoat(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX + 20, posY + 15, 0); + EntitySize = new Rectangle(-20, -15, 40, 15); + + _topPosition = EntityPosition.Position; + _bottomPosition = _topPosition + new Vector2(0, 5); + + _currentPosition = _topPosition; + + _collisionBox = new CBox(EntityPosition, -16, -14, 32, 14, 16); + _moveBox = new CBox(EntityPosition, + _collisionBox.OffsetX, _collisionBox.OffsetY - 8, _collisionBox.OffsetZ, + _collisionBox.Box.Width, _collisionBox.Box.Height, _collisionBox.Box.Depth); + + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(_collisionBox, Values.CollisionTypes.Normal) { DirectionFlag = 8 }); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawSpriteComponent("boat", EntityPosition, Values.LayerBottom)); + + _objFisherman = new ObjFishermanBoat(map, posX + 1, posY - 16, null, "npc_fisherman", "npc_bridge", new Rectangle(0, 1, 14, 20)); + map.Objects.SpawnObject(_objFisherman); + } + + private void OnKeyChange() + { + var spawnKey = "spawn_necklace"; + var spawnNecklace = Game1.GameManager.SaveManager.GetString(spawnKey); + if (!string.IsNullOrEmpty(spawnNecklace) && spawnNecklace == "1") + { + var spawnPosition = new Vector2(EntityPosition.X - 48, EntityPosition.Y - 16); + Game1.GameManager.SaveManager.RemoveString(spawnKey); + var objNecklace = new ObjItem(Map, (int)spawnPosition.X, (int)spawnPosition.Y, null, null, "trade11", null); + objNecklace.SpawnBoatSequence(); + Map.Objects.SpawnObject(objNecklace); + + // spawn splash effect + var fallAnimation = new ObjAnimator(Map, (int)(spawnPosition.X + 8), (int)(spawnPosition.Y + 5), + Values.LayerPlayer, "Particles/fishingSplash", "idle", true); + Map.Objects.SpawnObject(fallAnimation); + } + } + + private void Update() + { + _lastBox = _moveBox.Box; + _lastCollisionBox = _collisionBox.Box; + + UpdateMove(); + + var moveDirection = _newPosition - EntityPosition.Position; + EntityPosition.Set(_newPosition); + + MoveBodies(moveDirection); + } + + // move to target if the player is standing on top of the plaform + private void UpdateMove() + { + // is the player standing on the platform? + var wasStandingOnTop = _isStandingOnTop; + _isStandingOnTop = MapManager.ObjLink._body.IsGrounded && + MapManager.ObjLink._body.BodyBox.Box.Intersects(_moveBox.Box); + + // jumped ontop of the boat? + if (_isStandingOnTop && !wasStandingOnTop) + { + _velocity = 0.75f; + _offsetTime = -100; + _offset = false; + _currentPosition.Y += _positionOffset.Y; + _positionOffset = Vector2.Zero; + } + // jumped off the boat? + if (!_isStandingOnTop && wasStandingOnTop) + { + _velocity = 0.0f; + _offsetTime = -100; + _offset = false; + _currentPosition.Y += _positionOffset.Y; + _positionOffset = Vector2.Zero; + } + + var target = 0.25f; + + // slow down at the top/bottom + if (_isStandingOnTop && _currentPosition.Y > _bottomPosition.Y - 2) + target = 0.0125f; + if (!_isStandingOnTop && _currentPosition.Y < _topPosition.Y + 1) + target = 0.05f; + + _velocity = AnimationHelper.MoveToTarget(_velocity, target, 0.05f * Game1.TimeMultiplier); + + if (!_offset) + { + // move up or down + if (_isStandingOnTop) + _currentPosition.Y = AnimationHelper.MoveToTarget(_currentPosition.Y, _bottomPosition.Y, _velocity * Game1.TimeMultiplier); + else + _currentPosition.Y = AnimationHelper.MoveToTarget(_currentPosition.Y, _topPosition.Y, _velocity * Game1.TimeMultiplier); + + if (_currentPosition.Y == _topPosition.Y) + { + _offset = true; + _currentPosition.Y += 1; + } + if (_currentPosition.Y == _bottomPosition.Y) + { + _offset = true; + _currentPosition.Y -= 1; + } + } + + if (_offset) + { + _offsetTime += Game1.DeltaTime; + var offsetRadiant = _offsetTime / 1000 * MathF.PI * 2; + var goUp = !_isStandingOnTop; + + //if (Game1.GameManager.DialogIsRunning() && _objFisherman.Animator.CurrentAnimation.Id == "down") + // goUp = _objFisherman.Animator.CurrentAnimation.Id == "down"; + + if (goUp) + offsetRadiant = offsetRadiant + MathF.PI; + + if (!Game1.GameManager.DialogIsRunning()) + _objFisherman.Animator.Play(MathF.Sin(offsetRadiant) > 0 ? "idle" : "down"); + + // 1sec up/down + _positionOffset.Y = MathHelper.Clamp(MathF.Cos(offsetRadiant) * 1.1f, -1, 1); + } + else if (!Game1.GameManager.DialogIsRunning()) + { + _objFisherman.Animator.Play(_isStandingOnTop ? "down" : "idle"); + } + + _newPosition = _currentPosition + _positionOffset; + } + + private void MoveBodies(Vector2 direction) + { + // check for colliding bodies and push them forward + _collidingObjects.Clear(); + Map.Objects.GetComponentList(_collidingObjects, + (int)_lastBox.Left, (int)_lastBox.Back - 8, (int)_lastBox.Width, (int)_lastBox.Height, BodyComponent.Mask); + + foreach (var collidingObject in _collidingObjects) + { + var body = (BodyComponent)collidingObject.Components[BodyComponent.Index]; + + if (body.BodyBox.Box.Front <= _lastCollisionBox.Back && body.BodyBox.Box.Intersects(_lastBox)) + { + var offset = Vector2.Zero; + + // body standing on the platform + if (body.IsGrounded) + { + var add = Vector2.Zero; + + // align the body with the platform so that the body is not wobbling around + if (Math.Abs(body.VelocityTarget.X) < 0.1f && Math.Abs(body.Velocity.X) < 0.1f) + { + var distance = (body.Position.X + direction.X) - EntityPosition.X; + var distanceNormal = (int)Math.Round(distance * MapManager.Camera.Scale, MidpointRounding.AwayFromZero) / MapManager.Camera.Scale; + + var dir = distanceNormal - distance; + if (Math.Abs(dir) > 0.005) + add.X += dir; + } + + offset = direction + add; + + // put the body on top of the platform + if (direction.Y != 0) + offset.Y = _collisionBox.Box.Back - body.BodyBox.Box.Front; + } + // did the platform already move into the body? + else if (body.BodyBox.Box.Intersects(_collisionBox.Box)) + { + // move the body up/down + if (direction.Y < 0) + offset.Y = _collisionBox.Box.Back - body.BodyBox.Box.Front - 0.05f; + else if (direction.Y > 0) + offset.Y = _collisionBox.Box.Back - body.BodyBox.Box.Front + 0.05f; + } + + if (offset != Vector2.Zero) + { + SystemBody.MoveBody(body, offset, body.CollisionTypes, false, false, false); + body.Position.NotifyListeners(); + } + } + } + } + } +} diff --git a/InGame/GameObjects/Things/ObjBomb.cs b/InGame/GameObjects/Things/ObjBomb.cs new file mode 100644 index 0000000..4a67225 --- /dev/null +++ b/InGame/GameObjects/Things/ObjBomb.cs @@ -0,0 +1,343 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjBomb : GameObject + { + public BodyComponent Body; + public bool DamageEnemies; + + private readonly Animator _animator; + private readonly BodyDrawShadowComponent _bodyShadow; + private readonly CarriableComponent _carriableComponent; + private readonly BodyDrawComponent _drawComponent; + + private readonly bool _playerBomb; + private readonly bool _floorExplode; + + public const int BlinkTime = 1000 / 60 * 4; + + private const int ExplosionTime = 1500; + + private double _bombCounter; + private double _explostionTime; + private double _lastHitTime; + private double _deepWaterCounter; + + private bool _exploded; + private bool _arrowMode; + + public ObjBomb(Map.Map map, float posX, float posY, bool playerBomb, bool floorExplode, int explosionTime = ExplosionTime) : base(map) + { + if (!map.Is2dMap) + EntityPosition = new CPosition(posX, posY, 5); + else + EntityPosition = new CPosition(posX, posY - 5, 0); + + EntitySize = new Rectangle(-8, -16, 16, 20); + + Body = new BodyComponent(EntityPosition, -4, -8, 8, 8, 4) + { + Bounciness = 0.5f, + Bounciness2D = 0.5f, + Drag = 0.85f, + DragAir = 1.0f, + DragWater = 0.985f, + Gravity = -0.15f, + HoleAbsorb = FallDeath, + MoveCollision = OnCollision, + IgnoreInsideCollision = false, + }; + + if (map.Is2dMap) + { + Body.OffsetY = -1; + Body.Height = 1; + } + + _playerBomb = playerBomb; + // explode on collision with the floor + _floorExplode = floorExplode; + + _animator = AnimatorSaveLoad.LoadAnimator("Objects/bomb"); + _animator.OnAnimationFinished = FinishedAnimation; + _animator.Play("idle"); + + _explostionTime = explosionTime; + _bombCounter = _explostionTime; + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, Vector2.Zero); + _drawComponent = new BodyDrawComponent(Body, sprite, Values.LayerPlayer); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(HittableComponent.Index, new HittableComponent(new CBox(EntityPosition, -4, -10, 8, 10, 8), OnHit)); + AddComponent(BodyComponent.Index, Body); + AddComponent(BaseAnimationComponent.Index, animationComponent); + + // can not push away the bombs from enemies; would probably be fun + if (playerBomb) + AddComponent(PushableComponent.Index, new PushableComponent(Body.BodyBox, OnPush) { RepelMultiplier = 0.5f }); + + AddComponent(CarriableComponent.Index, _carriableComponent = new CarriableComponent( + new CRectangle(EntityPosition, new Rectangle(-4, -8, 8, 8)), CarryInit, CarryUpdate, CarryThrow)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + AddComponent(DrawShadowComponent.Index, _bodyShadow = new BodyDrawShadowComponent(Body, sprite)); + } + + private void Update() + { + if (_exploded) + { + // use the collision data from the animation to deal damage + if (!_playerBomb) + { + var collisionRect = _animator.CollisionRectangle; + if (collisionRect != Rectangle.Empty) + { + var collisionBox = new Box( + EntityPosition.X + collisionRect.X, + EntityPosition.Y + collisionRect.Y, 0, + collisionRect.Width, collisionRect.Height, 16); + + if (collisionBox.Intersects(MapManager.ObjLink._body.BodyBox.Box)) + MapManager.ObjLink.HitPlayer(collisionBox, HitType.Bomb, 4); + } + } + + // remove bomb if the animation is finished + if (!_animator.IsPlaying) + Map.Objects.DeleteObjects.Add(this); + } + else + { + // blink + if (_bombCounter < 500) + { + if (_bombCounter % (BlinkTime * 2) < BlinkTime) + _animator.Play("blink"); + else + _animator.Play("idle"); + } + + _bombCounter -= Game1.DeltaTime; + if (_bombCounter <= 0) + Explode(); + } + + // fall into the water + if (!Map.Is2dMap && Body.IsGrounded && Body.CurrentFieldState.HasFlag(MapStates.FieldStates.DeepWater)) + { + _deepWaterCounter -= Game1.DeltaTime; + + if (_deepWaterCounter <= 0) + { + // spawn splash effect + var fallAnimation = new ObjAnimator(Map, + (int)(Body.Position.X + Body.OffsetX + Body.Width / 2.0f), + (int)(Body.Position.Y + Body.OffsetY + Body.Height / 2.0f), + Values.LayerPlayer, "Particles/fishingSplash", "idle", true); + Map.Objects.SpawnObject(fallAnimation); + + Map.Objects.DeleteObjects.Add(this); + } + } + else if (Body.IsGrounded) + { + _deepWaterCounter = 75; + } + } + + public void Draw(SpriteBatch spriteBatch) + { + _drawComponent.Draw(spriteBatch); + } + + private void FallDeath() + { + // play sound effect + Game1.GameManager.PlaySoundEffect("D360-24-18"); + + var fallAnimation = new ObjAnimator(Map, 0, 0, Values.LayerBottom, "Particles/fall", "idle", true); + fallAnimation.EntityPosition.Set(new Vector2( + Body.Position.X + Body.OffsetX + Body.Width / 2.0f - 5, + Body.Position.Y + Body.OffsetY + Body.Height / 2.0f - 5)); + Map.Objects.SpawnObject(fallAnimation); + + Map.Objects.DeleteObjects.Add(this); + } + + private Vector3 CarryInit() + { + _animator.Play("idle"); + + // the bomb was picked up + Body.IsActive = false; + + return EntityPosition.ToVector3(); + } + + private bool CarryUpdate(Vector3 newPosition) + { + _bombCounter = ExplosionTime; + + EntityPosition.X = newPosition.X; + + if (!Map.Is2dMap) + { + EntityPosition.Y = newPosition.Y; + EntityPosition.Z = newPosition.Z; + } + else + { + EntityPosition.Y = newPosition.Y - newPosition.Z; + EntityPosition.Z = 0; + } + + EntityPosition.NotifyListeners(); + return true; + } + + private void CarryThrow(Vector2 velocity) + { + Body.Drag = 0.75f; + Body.DragAir = 1.0f; + Body.IsGrounded = false; + Body.IsActive = true; + if (_playerBomb) + Body.Level = MapStates.GetLevel(MapManager.ObjLink._body.CurrentFieldState); + + // do not throw the bomb up when the player lets it fall down (e.g. by walking into a door) + if (velocity == Vector2.Zero) + Body.Velocity = Vector3.Zero; + else + Body.Velocity = new Vector3(velocity.X * 0.45f, velocity.Y * 0.45f, 1.25f); + + if (Map.Is2dMap) + Body.Velocity.Y = -0.75f; + + Body.CollisionTypesIgnore = Values.CollisionTypes.ThrowWeaponIgnore; + + _carriableComponent.IsActive = false; + } + + public void Explode() + { + _exploded = true; + Body.Velocity = Vector3.Zero; + Body.IsActive = false; + _bodyShadow.IsActive = false; + _carriableComponent.IsActive = false; + + // deals damage to the player or to the enemies + if (_playerBomb || DamageEnemies) + Map.Objects.Hit(this, new Vector2(EntityPosition.X, EntityPosition.Y), + new Box(EntityPosition.X - 20, EntityPosition.Y - 20 - 5, 0, 40, 40, 16), HitType.Bomb, 2, false); + + Game1.GameManager.PlaySoundEffect("D378-12-0C"); + + _animator.Play("explode"); + _animator.SetFrame(1); + + // shake the screen + Game1.GameManager.ShakeScreen(150, 8, 2, 5, 2.5f); + } + + private void FinishedAnimation() + { + // explode after the idle animation is finished + if (_animator.CurrentAnimation.Id == "idle") + Explode(); + } + + private void OnCollision(Values.BodyCollision collision) + { + if (Map.Is2dMap) + { + if ((collision & Values.BodyCollision.Horizontal) != 0) + { + Body.Velocity.X = -Body.Velocity.X * 0.25f; + Game1.GameManager.PlaySoundEffect("D360-09-09"); + } + if ((collision & Values.BodyCollision.Bottom) != 0 && Body.Velocity.Y < -0.075f) + { + Body.DragAir *= 0.975f; + _carriableComponent.IsActive = true; + Game1.GameManager.PlaySoundEffect("D360-09-09"); + } + } + + if ((collision & Values.BodyCollision.Floor) != 0) + { + if (Body.Velocity.Z > 0.5f) + Game1.GameManager.PlaySoundEffect("D360-09-09"); + + //Body.Level = 0; + Body.Drag *= 0.8f; + _carriableComponent.IsActive = true; + + if (_floorExplode && Body.Velocity.Z <= 0) + Explode(); + } + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (_exploded) + return false; + + // push the bomb away + if (type == PushableComponent.PushType.Impact) + { + Body.Drag = 0.85f; + Body.Velocity = new Vector3(direction.X * 1.5f, direction.Y * 1.5f, Body.Velocity.Z); + return true; + } + + return false; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + // got picked up by an arrow? + if (_playerBomb && _bombCounter + 175 > _explostionTime && gameObject is ObjArrow objArrow) + { + _arrowMode = true; + Body.IgnoresZ = true; + Body.IgnoreHoles = true; + Body.Velocity = Vector3.Zero; + EntityPosition.Z = 0; + objArrow.InitBombMode(this); + } + + if (_arrowMode) + return Values.HitCollision.None; + + if (_exploded || (_lastHitTime != 0 && Game1.TotalGameTime - _lastHitTime < 250) || damageType == HitType.Bow) + return Values.HitCollision.None; + + _lastHitTime = Game1.TotalGameTime; + + Body.Drag = 0.85f; + Body.DragAir = 0.85f; + Body.Velocity.X += direction.X * 4; + Body.Velocity.Y += direction.Y * 4; + + if (Map.Is2dMap) + { + Body.DragAir = 0.925f; + Body.Velocity.Y = direction.Y * 2f; + } + + return Values.HitCollision.Blocking; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjBook.cs b/InGame/GameObjects/Things/ObjBook.cs new file mode 100644 index 0000000..20a1caf --- /dev/null +++ b/InGame/GameObjects/Things/ObjBook.cs @@ -0,0 +1,104 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjBook : GameObject + { + private readonly BodyComponent _body; + private readonly CSprite _sprite; + private readonly DictAtlasEntry _spriteBook; + private readonly DictAtlasEntry _spriteBookOpen; + private readonly string _strKey; + private readonly string _dialogKey; + // when the dialogKey + "_open" key is set the book sprite will be shown as opened + private readonly string _openBookKey; + private bool _hasFallen; + + public ObjBook() : base("book_0") { } + + public ObjBook(Map.Map map, int posX, int posY, string strKey, string dialogKey, int spriteIndex) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 18); + + _strKey = strKey; + _dialogKey = dialogKey; + _openBookKey = dialogKey + "_open"; + + spriteIndex = MathHelper.Clamp(spriteIndex, 0, 3); + + // has the book already fallen down? + if (!string.IsNullOrEmpty(_strKey) && Game1.GameManager.SaveManager.GetString(_strKey) != "1") + { + EntityPosition.Z = 30; + EntitySize = new Rectangle(-Values.FieldWidth / 2, -32, Values.FieldWidth, Values.FieldHeight); + } + else + _hasFallen = true; + + _spriteBook = Resources.GetSprite("book_" + spriteIndex); + _spriteBookOpen = Resources.GetSprite("book_open"); + _sprite = new CSprite(_spriteBook, EntityPosition, new Vector2(-4, -11)); + + var tileRectangle = map.GetField(posX, posY); + _body = new BodyComponent(EntityPosition, -4, -11, 8, 11, 8) + { + IsActive = false, + Gravity = -0.125f, + Bounciness = 0.45f, + }; + + var interactionBox = new CBox(EntityPosition, -6, -11, 0, 12, 13, 8); + if (!_hasFallen) + { + var hitBox = new CBox(EntityPosition.X + EntitySize.X, EntityPosition.Y + EntitySize.Y, 0, EntitySize.Width, EntitySize.Height, 16); + AddComponent(HittableComponent.Index, new HittableComponent(hitBox, OnHit)); + } + AddComponent(BodyComponent.Index, _body); + AddComponent(InteractComponent.Index, new InteractComponent(interactionBox, OnInteract)); + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerBottom)); + } + + private void OnKeyChange() + { + var keyState = Game1.GameManager.SaveManager.GetString(_openBookKey); + var openBook = keyState == "1"; + _sprite.SetSprite(openBook ? _spriteBookOpen : _spriteBook); + _sprite.DrawOffset.X = -_sprite.SourceRectangle.Width / 2 * _sprite.Scale; + _sprite.DrawOffset.Y = -11; + } + + private bool OnInteract() + { + Game1.GameManager.StartDialogPath(_dialogKey); + + return true; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_hasFallen) + return Values.HitCollision.None; + + if (damageType == HitType.PegasusBootsPush) + StartFalling(); + + return Values.HitCollision.None; + } + + private void StartFalling() + { + _hasFallen = true; + _body.IsActive = true; + + if (!string.IsNullOrEmpty(_strKey)) + Game1.GameManager.SaveManager.SetString(_strKey, "1"); + } + } +} diff --git a/InGame/GameObjects/Things/ObjBoomerang.cs b/InGame/GameObjects/Things/ObjBoomerang.cs new file mode 100644 index 0000000..83a15c0 --- /dev/null +++ b/InGame/GameObjects/Things/ObjBoomerang.cs @@ -0,0 +1,187 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjBoomerang : GameObject + { + private readonly List _itemList = new List(); + + private readonly BodyComponent _body; + private readonly CBox _damageBox; + + private ObjItem _item; + + private Vector2 _startPosition; + private Vector2 _direction; + + private bool _comingBack; + + private bool _isReady = true; + public bool IsReady => _isReady; + + public ObjBoomerang() + { + EntityPosition = new CPosition(0, 0, 4); + EntityPosition.AddPositionListener(typeof(ObjBoomerang), UpdateItemPosition); + EntitySize = new Rectangle(-8, -12, 16, 16); + + _damageBox = new CBox(EntityPosition, -5, -5, 0, 10, 10, 4, true); + + var animation = AnimatorSaveLoad.LoadAnimator("Objects/boomerang"); + animation.Play("run"); + + _body = new BodyComponent(EntityPosition, -1, -1, 2, 2, 8) + { + IgnoresZ = true, + MoveCollision = OnCollision, + CollisionTypesIgnore = Values.CollisionTypes.ThrowWeaponIgnore, + IgnoreInsideCollision = false, + }; + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(animation, sprite, new Vector2(-6, -6)); + + AddComponent(BodyComponent.Index, _body); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, sprite)); + } + + public void Reset() + { + _isReady = true; + } + + public void Start(Map.Map map, Vector3 position, Vector2 direction) + { + Map = map; + + EntityPosition.Set(new Vector3(position.X, position.Y, position.Z + 4)); + + _startPosition = new Vector2(position.X, position.Y); + _direction = direction; + _body.VelocityTarget = Vector2.Zero; + _body.CollisionTypes = Values.CollisionTypes.Normal; + // if the player is on an upper level he can shoot down through walls that are blocking if the is not on the upper level + _body.Level = MapStates.GetLevel(MapManager.ObjLink._body.CurrentFieldState); + + _comingBack = false; + _isReady = false; + _item = null; + } + + private void Update() + { + // play sound effect + Game1.GameManager.PlaySoundEffect("D378-45-2D", false); + + if (!_comingBack) + { + EntityPosition.Z = AnimationHelper.MoveToTarget(EntityPosition.Z, 4, 0.35f * Game1.TimeMultiplier); + + var distance = (_startPosition - EntityPosition.Position).Length(); + var speed = 3f - (float)Math.Sin(MathHelper.Clamp(distance / 80, 0, 1) * (Math.PI / 2)); + _body.VelocityTarget = _direction * speed; + + if (distance >= 80) + ComeBack(); + } + else + { + EntityPosition.Z = AnimationHelper.MoveToTarget(EntityPosition.Z, 4, 1.25f * Game1.TimeMultiplier); + + var direction = new Vector2( + MapManager.ObjLink.EntityPosition.Position.X, + MapManager.ObjLink.EntityPosition.Position.Y - 3) - EntityPosition.Position; + var distance = direction.Length(); + var speed = 3f - (float)Math.Sin(MathHelper.Clamp(distance / 80, 0, 1) * (Math.PI / 2)); + speed = Math.Min(speed, distance); + + if (direction != Vector2.Zero) + direction.Normalize(); + _body.VelocityTarget = direction * speed; + + // MapManager.ObjLink.IsGrounded() + if ((Map.Is2dMap || Math.Abs(MapManager.ObjLink.EntityPosition.Z - EntityPosition.Z) <= 6) && distance < 2) + { + _isReady = true; + Map.Objects.DeleteObjects.Add(this); + } + } + + CollectItem(); + + var collision = Map.Objects.Hit(this, EntityPosition.Position, _damageBox.Box, HitType.Boomerang, 32, false); + if (!_comingBack && + (collision & (Values.HitCollision.Blocking | Values.HitCollision.Repelling | Values.HitCollision.Enemy)) != 0) + { + var particle = (collision & Values.HitCollision.Repelling) != 0; + ComeBack(particle); + } + } + + private void CollectItem() + { + if (_item != null && !_item.Collected) + return; + + _item = null; + + _itemList.Clear(); + Map.Objects.GetComponentList(_itemList, (int)_damageBox.Box.X, (int)_damageBox.Box.Y, + (int)_damageBox.Box.Width, (int)_damageBox.Box.Height, CollisionComponent.Mask); + + // check if an item was found + foreach (var gameObject in _itemList) + { + var collidingBox = Box.Empty; + var collisionObject = gameObject.Components[CollisionComponent.Index] as CollisionComponent; + if ((collisionObject.CollisionType & Values.CollisionTypes.Item) != 0 && + collisionObject.Collision(_damageBox.Box, 0, 0, ref collidingBox)) + { + var newItem = (ObjItem)collisionObject.Owner; + if (!newItem.Collected) + { + _item = newItem; + _item.InitCollection(); + } + } + } + } + + private void UpdateItemPosition(CPosition position) + { + _item?.EntityPosition.Set(new Vector3(position.X, position.Y + 4, position.Z)); + } + + private void OnCollision(Values.BodyCollision collision) + { + ComeBack(true); + } + + private void ComeBack(bool particle = false) + { + if (particle) + { + var animation = new ObjAnimator(Map, 0, 0, Values.LayerTop, "Particles/swordPoke", "run", true); + animation.EntityPosition.Set(new Vector3(EntityPosition.X, EntityPosition.Y, EntityPosition.Z)); + Map.Objects.SpawnObject(animation); + + Game1.GameManager.PlaySoundEffect("D360-07-07"); + } + + _comingBack = true; + _body.CollisionTypes = Values.CollisionTypes.None; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjBridge.cs b/InGame/GameObjects/Things/ObjBridge.cs new file mode 100644 index 0000000..28943e8 --- /dev/null +++ b/InGame/GameObjects/Things/ObjBridge.cs @@ -0,0 +1,117 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.NPCs; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjBridge : GameObject + { + private readonly Rectangle _sourceRectangle; + + private readonly ObjMonkeyWorker[] _workers = new ObjMonkeyWorker[7]; + + private float _counter; + private const float Segment1Time = 5000; + private const float Segment2Time = Segment3Time + 1000; + private const float Segment3Time = Segment1Time + 1000; + private const float FinishedTime = Segment3Time + 1500; + + private bool _isRunning; + private bool _spawnedMonkeys; + + public ObjBridge() : base("bridge") { } + + public ObjBridge(Map.Map map, int posX, int posY) : base(map) + { + _sourceRectangle = Resources.SourceRectangle("bridge"); + + EntityPosition = new CPosition(posX, posY + 48, 0); + EntitySize = new Rectangle(0, -48, 16, 48); + + var value = Game1.GameManager.SaveManager.GetString("monkeyBusiness"); + var finished = value == "3"; + + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBottom, EntityPosition)); + + if (finished) + { + // make sure that the stick is there if it was not already collected + SpawnStick(); + _counter = FinishedTime; + return; + } + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + + // create the workers + for (var i = 0; i < _workers.Length; i++) + { + var randomDir = (Game1.RandomNumber.Next(0, 50) / 50.0f) * MathF.PI * 2; + var startPosition = new Vector2(EntityPosition.X + 8, EntityPosition.Y - 24) + + new Vector2(MathF.Sin(randomDir), MathF.Cos(randomDir)) * 150; + var workPosition = new Vector2(EntityPosition.X + 8, EntityPosition.Y - 36 * (i / 6.0f)); + _workers[i] = new ObjMonkeyWorker(map, startPosition, workPosition, startPosition); + } + } + + private void KeyChanged() + { + var value = Game1.GameManager.SaveManager.GetString("monkeyBusiness"); + + if (!_spawnedMonkeys && value == "2") + { + _isRunning = true; + _spawnedMonkeys = true; + + for (var i = 0; i < _workers.Length; i++) + Map.Objects.SpawnObject(_workers[i]); + } + } + + private void SpawnStick() + { + // spawn the stick + var objStick = new ObjItem(Map, (int)EntityPosition.X, (int)EntityPosition.Y - 32, "", "ow_trade4", "trade4", null); + if (!objStick.IsDead) + Map.Objects.SpawnObject(objStick); + } + + private void Update() + { + if (!_isRunning) + return; + + _counter += Game1.DeltaTime; + + if (_counter > FinishedTime) + { + _isRunning = false; + Game1.GameManager.StartDialogPath("castle_monkey_business"); + + SpawnStick(); + + for (var i = 0; i < _workers.Length; i++) + { + _workers[i].ToLeave(); + } + } + } + + private void Draw(SpriteBatch spriteBatch) + { + // draw the segments of the bridge + if (_counter > Segment1Time) + spriteBatch.Draw(Resources.SprObjects, new Vector2(EntityPosition.X, EntityPosition.Y - 48), _sourceRectangle, Color.White); + if (_counter > Segment2Time) + spriteBatch.Draw(Resources.SprObjects, new Vector2(EntityPosition.X, EntityPosition.Y - 32), _sourceRectangle, Color.White); + if (_counter > Segment3Time) + spriteBatch.Draw(Resources.SprObjects, new Vector2(EntityPosition.X, EntityPosition.Y - 16), _sourceRectangle, Color.White); + } + } +} diff --git a/InGame/GameObjects/Things/ObjBubble.cs b/InGame/GameObjects/Things/ObjBubble.cs new file mode 100644 index 0000000..e22f36f --- /dev/null +++ b/InGame/GameObjects/Things/ObjBubble.cs @@ -0,0 +1,45 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjBubble : GameObject + { + private readonly Animator _animator; + + public ObjBubble(Map.Map map, Vector3 position, Vector3 velocity) : base(map) + { + EntityPosition = new CPosition(position.X, position.Y, position.Z); + EntitySize = new Rectangle(-3, -32, 6, 35); + + _animator = AnimatorSaveLoad.LoadAnimator("NPCs/walrus particle"); + _animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, sprite, Vector2.Zero); + + var body = new BodyComponent(EntityPosition, -3, -3, 6, 6, 3) + { + Velocity = velocity, + Gravity = 0, + DragAir = 0.975f + //IgnoresZ = true + }; + + AddComponent(BodyComponent.Index, body); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerPlayer)); + } + + private void Update() + { + if (!_animator.IsPlaying) + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjBush.cs b/InGame/GameObjects/Things/ObjBush.cs new file mode 100644 index 0000000..2613b18 --- /dev/null +++ b/InGame/GameObjects/Things/ObjBush.cs @@ -0,0 +1,251 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjBush : GameObject + { + private readonly BodyComponent _body; + private readonly BoxCollisionComponent _collisionComponent; + private readonly CBox _hittableBox; + private readonly CBox _hittableBoxSmall; + + private readonly CSprite _sprite; + + private readonly string _spawnItem; + private readonly string _spriteId; + private readonly bool _hasCollider; + private readonly bool _drawShadow; + private readonly bool _setGrassField; + private readonly int _drawLayer; + private readonly string _pickupKey; + + private readonly object[] _spawnObjectParameter; + private readonly string _spawnObjectId; + + private readonly int _fieldPosX; + private readonly int _fieldPosY; + + public bool RespawnGras = true; + + public ObjBush(Map.Map map, int posX, int posY, string spawnItem, string spriteId, + bool hasCollider, bool drawShadow, bool setGrassField, int drawLayer, string pickupKey) : base(map, spriteId) + { + var sprite = Resources.GetSprite(spriteId); + + EntityPosition = new CPosition(posX + 8, posY + 8, 0); + EntitySize = new Rectangle(-8, -8, 16, 16); + + _spawnItem = spawnItem; + _spriteId = spriteId; + _hasCollider = hasCollider; + _drawShadow = drawShadow; + _setGrassField = setGrassField; + _drawLayer = drawLayer; + _pickupKey = pickupKey; + + _fieldPosX = posX / 16; + _fieldPosY = posY / 16; + + // {objName}:{parameter.parameter1...} + if (!string.IsNullOrEmpty(spawnItem)) + { + var split = spawnItem?.Split(':'); + if (split?.Length >= 1) + { + _spawnObjectId = split[0]; + string[] parameter = null; + + if (split.Length >= 2) + parameter = split[1].Split('.'); + + _spawnObjectParameter = MapData.GetParameter(_spawnObjectId, parameter); + if (_spawnObjectParameter == null) + return; + + _spawnObjectParameter[1] = posX; + _spawnObjectParameter[2] = posY; + } + } + + _hittableBox = new CBox(EntityPosition, -7, -7, 0, 14, 13, 8, true); + _hittableBoxSmall = new CBox(EntityPosition, -4, -4, 0, 8, 8, 8, true); + + if (hasCollider) + { + _body = new BodyComponent(EntityPosition, -8, -7, 16, 15, 8) + { + MoveCollision = Collision, + DragAir = 1.0f, + Gravity = -0.125f + }; + AddComponent(BodyComponent.Index, _body); + + var collisionBox = new CBox(EntityPosition, -8, -7, 0, 16, 14, 16, true); + AddComponent(CollisionComponent.Index, _collisionComponent = + new BoxCollisionComponent(collisionBox, Values.CollisionTypes.Normal | Values.CollisionTypes.ThrowWeaponIgnore)); + AddComponent(CarriableComponent.Index, new CarriableComponent( + new CRectangle(EntityPosition, new Rectangle(-8, -7, 16, 15)), CarryInit, CarryUpdate, CarryThrow)); + } + + if (setGrassField) + Map.SetFieldState(_fieldPosX, _fieldPosY, MapStates.FieldStates.Grass); + + AddComponent(HittableComponent.Index, new HittableComponent(_hittableBox, OnHit)); + + _sprite = new CSprite(spriteId, EntityPosition, Vector2.Zero); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, drawLayer)); + + if (drawShadow) + { + // not sure where this is used + if (_body == null) + AddComponent(DrawShadowComponent.Index, new DrawShadowSpriteComponent( + Resources.SprObjects, EntityPosition, sprite.ScaledRectangle, + new Vector2(sprite.Origin.X + 1.0f, sprite.Origin.Y - 1.0f), 1.0f, 0.0f)); + else + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, _sprite)); + } + } + + private Vector3 CarryInit() + { + // the stone was picked up + _collisionComponent.IsActive = false; + _body.IsActive = false; + + SpawnItem(Vector2.Zero); + + return new Vector3(EntityPosition.X, EntityPosition.Y + 6, EntityPosition.Z); + } + + private bool CarryUpdate(Vector3 newPosition) + { + EntityPosition.X = newPosition.X; + EntityPosition.Y = newPosition.Y - 6; + EntityPosition.Z = newPosition.Z; + + EntityPosition.NotifyListeners(); + return true; + } + + private void CarryThrow(Vector2 velocity) + { + _body.IsGrounded = false; + _body.IsActive = true; + _body.Velocity = new Vector3(velocity.X, velocity.Y, 0) * 1.0f; + } + + private void Collision(Values.BodyCollision direction) + { + DestroyBush(new Vector2(_body.Velocity.X, _body.Velocity.Y)); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (IsDead || + (damageType & HitType.SwordHold) != 0 || + damageType == HitType.Bow || + damageType == HitType.Hookshot || + damageType == HitType.SwordShot || + damageType == HitType.PegasusBootsPush || + damageType == HitType.MagicRod && !_hasCollider || + damageType == HitType.Boomerang && !_hasCollider || + damageType == HitType.ThrownObject && !_hasCollider) + return Values.HitCollision.None; + + // this is really stupid + // for the sword attacks a smaller hitbox is used + if (_hasCollider && + (damageType & HitType.Sword) != 0 && + gameObject is ObjLink player && !player.IsPoking) + { + var collidingRec = player.SwordDamageBox.Rectangle().GetIntersection(_hittableBoxSmall.Box.Rectangle()); + var collidingArea = collidingRec.Width * collidingRec.Height; + + if (collidingArea < 16) + return Values.HitCollision.None; + } + + SpawnItem(direction); + + DestroyBush(direction); + + return Values.HitCollision.NoneBlocking; + } + + private void SpawnItem(Vector2 direction) + { + // set the pickup key + if (!string.IsNullOrEmpty(_pickupKey)) + Game1.GameManager.SaveManager.SetString(_pickupKey, "1"); + + // spawn the object if it exists + bool spawnedObject = false; + + // try to spawn the object + if (!string.IsNullOrEmpty(_spawnObjectId)) + { + var objSpawnedObject = ObjectManager.GetGameObject(Map, _spawnObjectId, _spawnObjectParameter); + spawnedObject = Map.Objects.SpawnObject(objSpawnedObject); + if (spawnedObject && objSpawnedObject is ObjItem spawnedItem) + spawnedItem.SetVelocity(new Vector3(direction.X * 0.5f, direction.Y * 0.5f, 0.75f)); + } + + if (!spawnedObject) + { + // TODO_End reevaluate + // need to find a source for this data + // rube1 = 6/100, hearth = 3/100 + string strObject = null; + var random = Game1.RandomNumber.Next(0, 100); + if (random < 6) + strObject = "ruby"; + else if (random < 9) + strObject = "heart"; + + // spawn a heart or a ruby + if (strObject != null) + { + var objItem = new ObjItem(Map, (int)EntityPosition.X - 8, (int)EntityPosition.Y - 8, "j", null, strObject, null, true); + objItem.SetVelocity(new Vector3(direction.X * 0.5f, direction.Y * 0.5f, 0.75f)); + Map.Objects.SpawnObject(objItem); + } + } + } + + public void DestroyBush(Vector2 direction) + { + if (IsDead) + return; + IsDead = true; + + // sound effect + Game1.GameManager.PlaySoundEffect("D378-05-05"); + + if (RespawnGras) + Map.Objects.SpawnObject(new ObjBushRespawner(Map, (int)EntityPosition.X - 8, (int)EntityPosition.Y - 8, + _spawnItem, _spriteId, _hasCollider, _drawShadow, _setGrassField, _drawLayer, _pickupKey)); + + // delete this object + Map.Objects.DeleteObjects.Add(this); + + // reset FieldStates + Map.RemoveFieldState(_fieldPosX, _fieldPosY, MapStates.FieldStates.Grass); + + // spawn the leafs + var offsets = new[] { new Point(-7, -1), new Point(1, -1), new Point(-7, 7), new Point(1, 7) }; + for (var i = 0; i < offsets.Length; i++) + { + var posZ = EntityPosition.Z + 5 - Game1.RandomNumber.Next(0, 40) / 10f; + var newLeaf = new ObjLeaf(Map, (int)EntityPosition.X + offsets[i].X, (int)EntityPosition.Y + offsets[i].Y, posZ, direction); + Map.Objects.SpawnObject(newLeaf); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjBushRespawner.cs b/InGame/GameObjects/Things/ObjBushRespawner.cs new file mode 100644 index 0000000..1784396 --- /dev/null +++ b/InGame/GameObjects/Things/ObjBushRespawner.cs @@ -0,0 +1,56 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjBushRespawner : GameObject + { + private readonly string _spawnItem; + private readonly string _spriteId; + private readonly bool _hasCollider; + private readonly bool _drawShadow; + private readonly bool _setGrassField; + private readonly int _drawLayer; + private readonly string _pickupKey; + + private int _lastFieldTime; + + public ObjBushRespawner(Map.Map map, int posX, int posY, string spawnItem, string spriteId, + bool hasCollider, bool drawShadow, bool setGrassField, int drawLayer, string pickupKey) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + _spawnItem = spawnItem; + _spriteId = spriteId; + _hasCollider = hasCollider; + _drawShadow = drawShadow; + _setGrassField = setGrassField; + _drawLayer = drawLayer; + _pickupKey = pickupKey; + + _lastFieldTime = Map.GetUpdateState(EntityPosition.Position); + + // add key change listener + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + private void Update() + { + // field went out of the update range? + var updateState = Map.GetUpdateState(EntityPosition.Position); + if (_lastFieldTime < updateState) + SpawnObject(); + } + + private void SpawnObject() + { + Map.Objects.DeleteObjects.Add(this); + + Map.Objects.SpawnObject(new ObjBush(Map, (int)EntityPosition.X, (int)EntityPosition.Y, + _spawnItem, _spriteId, _hasCollider, _drawShadow, _setGrassField, _drawLayer, _pickupKey)); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjButton.cs b/InGame/GameObjects/Things/ObjButton.cs new file mode 100644 index 0000000..5f2f47e --- /dev/null +++ b/InGame/GameObjects/Things/ObjButton.cs @@ -0,0 +1,92 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjButton : GameObject + { + private readonly BoxCollisionComponent _collisionComponent; + private readonly DrawSpriteComponent _sprite; + + private readonly string _strKey; + + private float _counter; + private readonly int _pushTime = 200; + + private bool _isColliding; + private bool _isActivated; + + public ObjButton() : base("button") { } + + public ObjButton(Map.Map map, int posX, int posY, string strKey) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + _strKey = strKey; + + _collisionComponent = new BoxCollisionComponent(new CBox(EntityPosition, 3, 3, 10, 10, 2), Values.CollisionTypes.Normal); + _sprite = new DrawSpriteComponent("button", EntityPosition, Vector2.Zero, Values.LayerBottom); + + AddComponent(ObjectCollisionComponent.Index, new ObjectCollisionComponent(new Rectangle(posX + 3, posY + 3, 10, 10), OnCollision)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(CollisionComponent.Index, _collisionComponent); + AddComponent(DrawComponent.Index, _sprite); + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + } + + private void OnKeyChange() + { + // was the button already pressed before? + if (!string.IsNullOrEmpty(_strKey) && Game1.GameManager.SaveManager.GetString(_strKey) == "1") + Activate(); + } + + private void Update() + { + if (_isActivated) + return; + + if (_isColliding) + { + _counter -= Game1.DeltaTime; + + // activate the button if the player is standing on it long enough + if (_counter <= 0) + { + Game1.GameManager.PlaySoundEffect("D370-14-0E"); + + if (!string.IsNullOrEmpty(_strKey)) + Game1.GameManager.SaveManager.SetString(_strKey, "1"); + + Activate(); + } + } + else + _counter = _pushTime; + + _isColliding = false; + } + + private void OnCollision(GameObject gameObject) + { + // is the player standing on the button? + if (MapManager.ObjLink._body.IsGrounded) + _isColliding = true; + } + + private void Activate() + { + if (_isActivated) + return; + + _isActivated = true; + _collisionComponent.CollisionBox.Box.Depth = 0; + _sprite.Sprite.SourceRectangle.X += 16; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjButtonLeave.cs b/InGame/GameObjects/Things/ObjButtonLeave.cs new file mode 100644 index 0000000..263e7a3 --- /dev/null +++ b/InGame/GameObjects/Things/ObjButtonLeave.cs @@ -0,0 +1,69 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjButtonLeave : GameObject + { + private readonly Rectangle _collisionRectangle; + + private readonly string _strKey; + private readonly int _buttonDir; + private readonly bool _negate; + + private bool _isColliding; + private bool _wasColliding; + + public ObjButtonLeave(Map.Map map, int posX, int posY, string strKey, int direction, int buttonWidth, int buttonHeight, bool negate) : base(map) + { + SprEditorImage = Resources.SprWhite; + EditorIconSource = new Rectangle(0, 0, 16, 16); + EditorColor = Color.Yellow * 0.5f; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, buttonWidth, buttonHeight); + + _strKey = strKey; + _buttonDir = direction; + + _negate = negate; + + if (string.IsNullOrEmpty(_strKey)) + { + IsDead = true; + return; + } + + _collisionRectangle = new Rectangle(posX, posY, buttonWidth, buttonHeight); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + private void Update() + { + _isColliding = MapManager.ObjLink.BodyRectangle.Intersects(_collisionRectangle); + + // check if player leaved the collision field + if (_wasColliding && !_isColliding && + (_buttonDir == 0 && _collisionRectangle.X >= MapManager.ObjLink.BodyRectangle.Right || + _buttonDir == 2 && _collisionRectangle.X + _collisionRectangle.Width <= MapManager.ObjLink.BodyRectangle.Left || + _buttonDir == 1 && _collisionRectangle.Y >= MapManager.ObjLink.BodyRectangle.Bottom || + _buttonDir == 3 && _collisionRectangle.Y + _collisionRectangle.Height <= MapManager.ObjLink.BodyRectangle.Top)) + { + Activate(); + } + + _wasColliding = _isColliding; + _isColliding = false; + } + + private void Activate() + { + // set the key + Game1.GameManager.SaveManager.SetString(_strKey, _negate ? "0" : "1"); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjButtonTouch.cs b/InGame/GameObjects/Things/ObjButtonTouch.cs new file mode 100644 index 0000000..7d39a68 --- /dev/null +++ b/InGame/GameObjects/Things/ObjButtonTouch.cs @@ -0,0 +1,95 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjButtonTouch : GameObject + { + private readonly Rectangle _collisionRectangle; + private readonly string _strKey; + private readonly string _value; + private readonly bool _deleteOnTouch; + private readonly bool _resetKey; + + private bool _currentState; + + public ObjButtonTouch(Map.Map map, int posX, int posY, int buttonWidth, int buttonHeight, string strKey, string value, bool deleteOnTouch, bool resetKey) : base(map, "button") + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, buttonWidth, buttonHeight); + + _strKey = strKey; + _value = string.IsNullOrEmpty(value) ? "0" : value; + _deleteOnTouch = deleteOnTouch; + _resetKey = resetKey; + + if (string.IsNullOrEmpty(_strKey)) + { + IsDead = true; + return; + } + + _collisionRectangle = new Rectangle(posX, posY, buttonWidth, buttonHeight); + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + public override void Init() + { + // check if the player spawns on the button + CheckNextMapPosition(); + } + + private void OnKeyChange() + { + var keyState = Game1.GameManager.SaveManager.GetString(_strKey, "0"); + _currentState = keyState == _value; + } + + private void CheckNextMapPosition() + { + if (MapManager.ObjLink.NextMapPositionStart.HasValue && + _collisionRectangle.Contains(MapManager.ObjLink.NextMapPositionStart.Value)) + { + Activate(); + + // do not spawn the object + if (_deleteOnTouch) + IsDead = true; + + // trigger event on the right map + Map.Objects.TriggerKeyChange(); + } + } + + private void Update() + { + var collision = MapManager.ObjLink.BodyRectangle.Intersects(_collisionRectangle); + + if (!_currentState && collision) + Activate(); + else if (_resetKey && _currentState && !collision) + Deactivate(); + } + + private void Activate() + { + // set the key + _currentState = true; + Game1.GameManager.SaveManager.SetString(_strKey, _value); + + if (_deleteOnTouch) + Map.Objects.DeleteObjects.Add(this); + } + + private void Deactivate() + { + // set the key + _currentState = false; + Game1.GameManager.SaveManager.RemoveString(_strKey); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjCactus.cs b/InGame/GameObjects/Things/ObjCactus.cs new file mode 100644 index 0000000..c66aa47 --- /dev/null +++ b/InGame/GameObjects/Things/ObjCactus.cs @@ -0,0 +1,29 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjCactus : GameObject + { + public ObjCactus() : base("cactus") { } + + public ObjCactus(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + var sprite = new CSprite("cactus", EntityPosition); + + var collisionBox = new CBox(posX + 3, posY + 3, 0, 10, 12, 8); + var damageBox = new CBox(posX + 2, posY + 2, 0, 12, 14, 8); + + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(collisionBox, Values.CollisionTypes.Normal)); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 2)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite)); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjCandyGrabber.cs b/InGame/GameObjects/Things/ObjCandyGrabber.cs new file mode 100644 index 0000000..e964338 --- /dev/null +++ b/InGame/GameObjects/Things/ObjCandyGrabber.cs @@ -0,0 +1,345 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.NPCs; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjCandyGrabber : GameObject + { + private readonly Rectangle _recTop; + // why is this split into left and right? + private readonly Rectangle _recGrabberLeft; + private readonly Rectangle _recGrabberRight; + private readonly Rectangle _recGrabberLeftClosed; + private readonly Rectangle _recGrabberRightClosed; + private readonly Rectangle _recLine; + + //private readonly CPosition EntityPosition; + + private readonly List _collidingObjects = new List(); + + private Box _grabberRectangle; + private Vector2 _vecStart; + + private const float MoveSpeed = 0.25f; + private const float MoveSpeedGrab = 0.25f; + private const float MoveSpeedBack = 0.5f; + + private float _blinkCount; + private float _grabState; + private float _grab2Count = 5000; + private float _waitCounter; + + private bool _marinGame; + + private BodyComponent _grabbedBody; + + enum State + { + Idle, MoveX, IdleY, WaitY, MoveY, Grab0, Grab1, Grab2, Grab3, BackY, BackX, BackWait + } + + private State _currentState = State.Idle; + + public ObjCandyGrabber() : base("candy_grabber") { } + + public ObjCandyGrabber(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX, posY + 38, 0); + //EntityPosition = new CPosition(EntityPosition.X, EntityPosition.Y, EntityPosition.Z); + + _recTop = Resources.SourceRectangle("candy_grabber_top"); + _recGrabberLeft = Resources.SourceRectangle("candy_grabber_left"); + _recGrabberRight = Resources.SourceRectangle("candy_grabber_right"); + _recGrabberLeftClosed = Resources.SourceRectangle("candy_grabber_left_closed"); + _recGrabberRightClosed = Resources.SourceRectangle("candy_grabber_right_closed"); + _recLine = Resources.SourceRectangle("candy_grabber_line"); + + _vecStart = new Vector2(posX, posY + 38); + + var shadowSourceRectangle = new Rectangle(0, 0, 65, 66); + var shadowComponent = new DrawShadowSpriteComponent(Resources.SprShadow, EntityPosition, shadowSourceRectangle, new Vector2(0, -5), 1.0f, 0.0f); + shadowComponent.Width = 16; + shadowComponent.Height = 8; + + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + AddComponent(DrawShadowComponent.Index, shadowComponent); + } + + private void Update() + { + _blinkCount += Game1.DeltaTime; + if (_blinkCount > 500) + _blinkCount -= 500; + + _grabberRectangle = new Box(EntityPosition.X + 6, EntityPosition.Y - 3, 0, 4, 4, 2); + + switch (_currentState) + { + case State.Idle: + if (ControlHandler.ButtonDown(CButtons.B)) + StartGrabbing(); + + break; + case State.MoveX: + if ((_marinGame || ControlHandler.ButtonDown(CButtons.B)) && + EntityPosition.X < _vecStart.X + 112) + { + Game1.GameManager.PlaySoundEffect("D378-32-20", false); + + EntityPosition.Move(new Vector2(MoveSpeed, 0)); + + if (EntityPosition.X > _vecStart.X + 112) + EntityPosition.Set(new Vector2(_vecStart.X + 112, EntityPosition.Y)); + } + else + { + Game1.GameManager.StopSoundEffect("D378-32-20"); + Game1.GameManager.SaveManager.SetString("trendy_button_1", "0"); + Game1.GameManager.SaveManager.SetString("trendy_button_2", "1"); + _currentState = _marinGame ? State.WaitY : State.IdleY; + } + + break; + case State.IdleY: + if (ControlHandler.ButtonDown(CButtons.A)) + _currentState = State.MoveY; + + break; + case State.WaitY: + _waitCounter += Game1.DeltaTime; + if (_waitCounter > 1000) + _currentState = State.MoveY; + + break; + case State.MoveY: + if ((_marinGame || ControlHandler.ButtonDown(CButtons.A)) && + EntityPosition.Y < _vecStart.Y + 64) + { + Game1.GameManager.PlaySoundEffect("D378-32-20", false); + + EntityPosition.Move(new Vector2(0, MoveSpeed)); + + if (EntityPosition.Y > _vecStart.Y + 64) + EntityPosition.Set(new Vector2(EntityPosition.X, _vecStart.Y + 64)); + } + else + { + Game1.GameManager.StopSoundEffect("D378-32-20"); + Game1.GameManager.SaveManager.SetString("trendy_button_2", "0"); + + _waitCounter = 0; + _currentState = State.Grab0; + } + + break; + case State.Grab0: + _waitCounter += Game1.DeltaTime; + + if (_waitCounter > 800) + { + _waitCounter = 0; + // open the grabber + _grab2Count = 0; + _currentState = State.Grab1; + } + + break; + case State.Grab1: + _waitCounter += Game1.DeltaTime; + + if (_waitCounter > 800) + { + _currentState = State.Grab2; + } + + break; + case State.Grab2: + _grabState += MoveSpeedGrab * Game1.TimeMultiplier; + + if (_grabState > 15) + { + _grabState = 15; + _currentState = State.Grab3; + } + + break; + case State.Grab3: + _grab2Count += Game1.DeltaTime; + + if (_grab2Count > 500) + _grabState = 16; + + if (_grab2Count > 2000) + Grab(); + + if (_grab2Count > 3000) + _currentState = State.BackY; + + break; + case State.BackY: + _grabState -= MoveSpeedGrab * Game1.TimeMultiplier; + if (_grabState < 0) + { + _grabState = 0; + _currentState = State.BackX; + } + break; + case State.BackX: + Game1.GameManager.PlaySoundEffect("D378-32-20", false); + + var vecBack = _vecStart - EntityPosition.Position; + vecBack.Normalize(); + + EntityPosition.Move(vecBack * MoveSpeedBack); + + if (EntityPosition.X <= _vecStart.X && EntityPosition.Y <= _vecStart.Y) + { + Game1.GameManager.StopSoundEffect("D378-32-20"); + + _waitCounter = 0; + _currentState = State.BackWait; + + EntityPosition.Set(_vecStart); + + } + break; + case State.BackWait: + _waitCounter += Game1.DeltaTime; + + if (_waitCounter > 1500) + { + _grab2Count = 0; + _currentState = State.Idle; + // release the item + EndGrabbing(); + } + + break; + } + + if (_currentState != State.Idle) + MapManager.ObjLink.FreezePlayer(); + + // update the position of the grabbed body + UpdateItemPos(); + } + + private void OnKeyChange() + { + var strMarinGame = "trendy_marin_game"; + if (!_marinGame && Game1.GameManager.SaveManager.GetString(strMarinGame, "0") == "1") + { + Game1.GameManager.SaveManager.RemoveString(strMarinGame); + + _marinGame = true; + _currentState = State.MoveX; + } + } + + private void StartGrabbing() + { + // allowed to play and standing on the right spot? + if (!Game1.GameManager.SaveManager.GetBool("trendy_ready", false)) + return; + + MapManager.ObjLink.Direction = 1; + MapManager.ObjLink.CurrentState = ObjLink.State.Idle; + MapManager.ObjLink.FreezePlayer(); + + Game1.GameManager.SaveManager.SetString("can_play", "0"); + _currentState = State.MoveX; + } + + private void Grab() + { + // already grabbed an item + if (_grabbedBody != null) + return; + + _collidingObjects.Clear(); + Map.Objects.GetComponentList(_collidingObjects, + (int)_grabberRectangle.Left, (int)_grabberRectangle.Back, (int)_grabberRectangle.Width, (int)_grabberRectangle.Height, BodyComponent.Mask); + + // grab the first body the grabber is colliding with + foreach (var gameObject in _collidingObjects) + { + var objBody = ((BodyComponent)gameObject.Components[BodyComponent.Index]); + if ((gameObject is ObjItem || _marinGame) && objBody.BodyBox.Box.Intersects(_grabberRectangle)) + { + StartGrabbing(objBody); + return; + } + } + } + + private void StartGrabbing(BodyComponent body) + { + _grabbedBody = body; + _grabbedBody.AdditionalMovementVT = Vector2.Zero; + _grabbedBody.IgnoresZ = true; + + Game1.GameManager.PlaySoundEffect("D360-25-19", false); + } + + private void UpdateItemPos() + { + // update the position of the grabbed object + _grabbedBody?.Position.Set(new Vector3( + EntityPosition.X + 8, EntityPosition.Y + 0.001f, 13 - _grabState)); + } + + private void EndGrabbing() + { + if (_grabbedBody == null) + return; + + //_grabbedBody.Height = 0; + _grabbedBody.AdditionalMovementVT = new Vector2(0, 1 / 6.0f); + _grabbedBody.IgnoresZ = false; + _grabbedBody = null; + } + + private void Draw(SpriteBatch spriteBatch) + { + // draw the top + spriteBatch.Draw(Resources.SprObjects, new Vector2(EntityPosition.Position.X, EntityPosition.Position.Y - 38), + new Rectangle(_recTop.X, _recTop.Y + (_blinkCount >= 250 ? _recTop.Height : 0), _recTop.Width, _recTop.Height), Color.White); + + // line + spriteBatch.Draw(Resources.SprObjects, new Vector2( + EntityPosition.X + 6, EntityPosition.Y - 38 + _recTop.Height), + new Rectangle(_recLine.X, _recLine.Y, _recLine.Width, (int)Math.Ceiling(_grabState)), Color.White); + + // left claw + spriteBatch.Draw(Resources.SprObjects, new Vector2( + EntityPosition.X, EntityPosition.Y - 38 + _recTop.Height + _grabState), + _grab2Count > 1000 ? _recGrabberLeftClosed : _recGrabberLeft, Color.White); + + // right claw + spriteBatch.Draw(Resources.SprObjects, new Vector2( + EntityPosition.X + _recGrabberLeft.Width, + EntityPosition.Y - 38 + _recTop.Height + _grabState), + _grab2Count > 2000 ? _recGrabberRightClosed : _recGrabberRight, Color.White); + + // draw the collision rectangle + if (Game1.DebugMode) + { + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + (int)(_grabberRectangle.X), (int)(_grabberRectangle.Y), + (int)(_grabberRectangle.Width), (int)(_grabberRectangle.Height)), Color.SaddleBrown * 0.5f); + } + } + } +} diff --git a/InGame/GameObjects/Things/ObjCandyGrabberControls.cs b/InGame/GameObjects/Things/ObjCandyGrabberControls.cs new file mode 100644 index 0000000..f0f63db --- /dev/null +++ b/InGame/GameObjects/Things/ObjCandyGrabberControls.cs @@ -0,0 +1,66 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjCandyGrabberControls : GameObject + { + private readonly Rectangle _sourceTop; + private readonly Rectangle _sourceButton0; + private readonly Rectangle _sourceButton1; + + private readonly Box _collisionBox; + + private int _buttonFrame; + private int _animationSpeed = 100; + + public ObjCandyGrabberControls() : base("candy_grabber_controls_top") { } + + public ObjCandyGrabberControls(Map.Map map, int posX, int posY) : base(map) + { + _sourceTop = Resources.SourceRectangle("candy_grabber_controls_top"); + _sourceButton0 = Resources.SourceRectangle("candy_grabber_controls_button_0"); + _sourceButton1 = Resources.SourceRectangle("candy_grabber_controls_button_1"); + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + _collisionBox = new Box(posX + 6, posY + 32, 0, 4, 10, 8); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBottom, EntityPosition)); + } + + public void Update() + { + _buttonFrame = ((int)Game1.TotalGameTime % (2 * _animationSpeed)) / _animationSpeed; + + // check if the player is standing on the right spot and has payed for the game + var allowedToStartGame = MapManager.ObjLink._body.BodyBox.Box.Intersects(_collisionBox) && + Game1.GameManager.SaveManager.GetString("can_play") == "1"; + Game1.GameManager.SaveManager.SetBool("trendy_ready", allowedToStartGame); + } + + public void Draw(SpriteBatch spriteBatch) + { + // draw the top + spriteBatch.Draw(Resources.SprObjects, EntityPosition.Position + new Vector2(1, 1), _sourceTop, Color.White); + + // left button + var pressFirstButton = Game1.GameManager.SaveManager.GetString("trendy_button_1") == "1"; + spriteBatch.Draw(Resources.SprObjects, EntityPosition.Position + new Vector2(1, 17), + pressFirstButton && _buttonFrame == 1 ? _sourceButton1 : _sourceButton0, Color.White); + + // right button + var pressSecondButton = Game1.GameManager.SaveManager.GetString("trendy_button_2") == "1"; + spriteBatch.Draw(Resources.SprObjects, EntityPosition.Position + new Vector2(9, 17), + pressSecondButton && _buttonFrame == 1 ? _sourceButton1 : _sourceButton0, Color.White); + } + } +} diff --git a/InGame/GameObjects/Things/ObjCastleDoor.cs b/InGame/GameObjects/Things/ObjCastleDoor.cs new file mode 100644 index 0000000..ca6f259 --- /dev/null +++ b/InGame/GameObjects/Things/ObjCastleDoor.cs @@ -0,0 +1,32 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjCastleDoor : GameObject + { + public ObjCastleDoor() : base("castle_door") { } + + public ObjCastleDoor(Map.Map map, int posX, int posY, string saveKey) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 48, 32); + + // don't spawn the door if the key was already set + if (saveKey != null && Game1.GameManager.SaveManager.GetString(saveKey) == "1") + { + IsDead = true; + return; + } + + var sprite = Resources.GetSprite("castle_door"); + var cSprite = new CSprite(sprite, EntityPosition); + + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(new CBox(posX, posY, 0, 48, 32, 16), Values.CollisionTypes.Normal)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(cSprite, Values.LayerBottom)); + } + } +} diff --git a/InGame/GameObjects/Things/ObjChain.cs b/InGame/GameObjects/Things/ObjChain.cs new file mode 100644 index 0000000..2435c00 --- /dev/null +++ b/InGame/GameObjects/Things/ObjChain.cs @@ -0,0 +1,131 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjChain : GameObject + { + class Chain + { + public Vector2 StartPosition; + public Vector2 EndPosition; + public float Height; + + public Chain(Vector2 startPosition, Vector2 endPosition) + { + StartPosition = startPosition; + EndPosition = endPosition; + } + } + + private const int ChainCount = 6; + + private ObjSprite[] _objChains = new ObjSprite[ChainCount - 1]; + private Chain[] _chains = new Chain[ChainCount]; + + private float _chainLength; + private float _chainLengthInit = 7.5f; + private float _chainLengthEnd = 4f; + + public ObjChain(Map.Map map, Vector2 startPosition) : base(map) + { + // init the chain + for (var i = 0; i < ChainCount; i++) + { + _chains[i] = new Chain(startPosition, startPosition); + } + + for (var i = 0; i < ChainCount - 1; i++) + { + _objChains[i] = new ObjSprite(map, (int)startPosition.X, (int)startPosition.Y, "bowwow chain", Vector2.Zero, Values.LayerPlayer, null); + map.Objects.SpawnObject(_objChains[i]); + } + } + + public void SetChainPosition(Vector2 position) + { + for (var i = 0; i < _chains.Length; i++) + { + _chains[i].StartPosition = position; + _chains[i].EndPosition = position; + } + } + + public void UpdateChain(Vector3 startPosition, Vector3 endPosition) + { + var distance = (new Vector2(startPosition.X, startPosition.Y) - new Vector2(endPosition.X, endPosition.Y)).Length(); + if ((distance - _chainLengthEnd) > (_chains.Length - 1) * _chainLengthInit) + _chainLength = (distance - _chainLengthEnd) / (_chains.Length - 1); + else + _chainLength = _chainLengthInit; + + BackwardPass(endPosition); + ForwardPass(startPosition); + } + + private void BackwardPass(Vector3 goalPosition) + { + _chains[_chains.Length - 1].EndPosition = new Vector2(goalPosition.X, goalPosition.Y); + _chains[_chains.Length - 1].Height = goalPosition.Z; + + for (var i = _chains.Length - 1; i > 0; i--) + { + var direction = _chains[i].StartPosition - _chains[i].EndPosition; + var chainLength = i < _chains.Length - 1 ? _chainLength : _chainLengthEnd; + if (direction.Length() > chainLength) + { + direction.Normalize(); + direction *= chainLength; + } + _chains[i].StartPosition = _chains[i].EndPosition + direction; + _chains[i - 1].EndPosition = _chains[i].StartPosition; + + if (_chains[i].Height > 1.5f) + _chains[i - 1].Height = _chains[i].Height - 1.5f; + else + _chains[i - 1].Height = 0; + } + } + + private void ForwardPass(Vector3 startPosition) + { + _chains[0].StartPosition = new Vector2(startPosition.X, startPosition.Y); + _chains[0].Height = startPosition.Z * 0.75f; + + for (var i = 0; i < _chains.Length; i++) + { + var direction = _chains[i].EndPosition - _chains[i].StartPosition; + var chainLength = i < _chains.Length - 1 ? _chainLength : _chainLengthEnd; + if (direction.Length() > chainLength) + { + direction.Normalize(); + direction *= chainLength; + } + + _chains[i].EndPosition = _chains[i].StartPosition + direction; + + if (i < _objChains.Length) + { + _objChains[i].EntityPosition.Set(new Vector2(_chains[i].EndPosition.X, _chains[i].EndPosition.Y + 3)); + _objChains[i].EntityPosition.Z = _chains[i].Height; + } + + if (i < _chains.Length - 1) + { + _chains[i + 1].StartPosition = _chains[i].EndPosition; + + if (_chains[i].Height > (i + 1) * 3f + 3f) + _chains[i + 1].Height = _chains[i].Height - ((i + 1) * 3f + 3f); + else + _chains[i + 1].Height = 0; + } + } + } + + public Vector2 GetEndPosition() + { + return _chains[_chains.Length - 1].EndPosition; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjChainPlatform.cs b/InGame/GameObjects/Things/ObjChainPlatform.cs new file mode 100644 index 0000000..e41c40f --- /dev/null +++ b/InGame/GameObjects/Things/ObjChainPlatform.cs @@ -0,0 +1,214 @@ +using System; +using System.Globalization; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Systems; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjChainPlatform : GameObject + { + private readonly DictAtlasEntry _spritePlatform; + private readonly DictAtlasEntry _spriteChain; + + private readonly BoxCollisionComponent _cBoxCollision; + + private readonly CBox _moveBox; + + private readonly CBox _collisionBox; + + private Vector2 _chainPosition; + + private Vector2 _startPosition; + private Vector2 _bottomPosition; + private Vector2 _currentVelocity; + + private string _strPlatformKey; + private string _strPlatformMovedKey; + private string _strPlatformRestKey; + + private const float MaxSpeed = 1.0f; + private float _resetVelocity; + + private bool _wasMoved; + private bool _resettingPlatforms; + + public ObjChainPlatform(Map.Map map, int posX, int posY, string strPlatformKey, int bottom, int chainTop) : base(map) + { + _spritePlatform = Resources.GetSprite("small_platform"); + _spriteChain = Resources.GetSprite("platformchain"); + + _strPlatformKey = strPlatformKey; + _strPlatformMovedKey = strPlatformKey + "moved"; + _strPlatformRestKey = strPlatformKey + "reset"; + + SprEditorImage = _spritePlatform.Texture; + EditorIconSource = _spritePlatform.SourceRectangle; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, chainTop, 16, -chainTop + bottom + 16); + + _chainPosition = new Vector2(posX + 8 - _spriteChain.SourceRectangle.Width / 2, posY + chainTop); + + _startPosition = new Vector2(posX, posY); + _bottomPosition = new Vector2(posX, posY + bottom); + + _moveBox = new CBox(EntityPosition, 0, -1, 0, 16, 16, 16); + _collisionBox = new CBox(EntityPosition, 0, 0, 16, 16, 16); + + AddComponent(CollisionComponent.Index, _cBoxCollision = new BoxCollisionComponent(_collisionBox, Values.CollisionTypes.Normal) { DirectionFlag = 8 }); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBottom, EntityPosition)); + + if (_strPlatformKey != null) + { + Game1.GameManager.SaveManager.SetString(_strPlatformKey, "0"); + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + } + } + + private void OnKeyChange() + { + if (!_wasMoved && Game1.GameManager.SaveManager.GetString(_strPlatformMovedKey) == "true") + { + var strPlatformOffset = Game1.GameManager.SaveManager.GetString(_strPlatformKey); + if (!string.IsNullOrEmpty(strPlatformOffset)) + { + var newOffset = float.Parse(strPlatformOffset, CultureInfo.InvariantCulture); + EntityPosition.Set(_startPosition + new Vector2(0, newOffset)); + Game1.GameManager.SaveManager.SetString(_strPlatformMovedKey, "false"); + _resettingPlatforms = false; + } + } + + // reset the platforms? + var strReset = Game1.GameManager.SaveManager.GetString(_strPlatformRestKey); + if (strReset != null && strReset == "true") + { + _resettingPlatforms = true; + Game1.GameManager.SaveManager.SetString(_strPlatformRestKey, "false"); + } + } + + private void Update() + { + _wasMoved = false; + + // is the player standing on the platform? + var standingOnTop = MapManager.ObjLink._body.BodyBox.Box.Intersects(_moveBox.Box) && MapManager.ObjLink._body.IsGrounded; + + if (standingOnTop && PlayerIsMovable()) + { + // accelerate the platform + _currentVelocity += new Vector2(0, 0.025f * Game1.TimeMultiplier); + _currentVelocity.Y = MathHelper.Clamp(_currentVelocity.Y, 0, MaxSpeed); + + _resettingPlatforms = false; + } + else + { + // slow down the platform + _currentVelocity *= (float)Math.Pow(0.85f, Game1.TimeMultiplier); + } + + if (_currentVelocity.Length() > 0.1f) + MovePlatform(_currentVelocity); + + // move back to the start position + if (_resettingPlatforms) + { + var offset = _startPosition.Y - EntityPosition.Y; + + _resetVelocity += 0.035f * Game1.TimeMultiplier; + _resetVelocity = MathHelper.Clamp(_resetVelocity, 0, 0.4f); + + if (Math.Abs(offset) > _resetVelocity) + { + offset = Math.Sign(offset) * MathHelper.Clamp(Math.Abs(offset), 0, _resetVelocity * Game1.TimeMultiplier); + SetPosition(EntityPosition.Y + offset); + } + else + { + _resettingPlatforms = false; + SetPosition(_startPosition.Y); + } + } + else + { + _resetVelocity = 0; + } + } + + private void SetPosition(float newPositionY) + { + _wasMoved = true; + EntityPosition.Set(new Vector2(EntityPosition.X, newPositionY)); + + var platformOffset = _startPosition.Y - EntityPosition.Position.Y; + Game1.GameManager.SaveManager.SetString(_strPlatformKey, platformOffset.ToString(CultureInfo.InvariantCulture)); + Game1.GameManager.SaveManager.SetString(_strPlatformMovedKey, "true"); + } + + private void MovePlatform(Vector2 offset) + { + // do not allow the platform to move lower than the max + var maxOffset = _bottomPosition.Y - EntityPosition.Y; + if (maxOffset <= 0) + return; + if (offset.Y > maxOffset) + offset.Y = maxOffset; + + // make sure to not move the platform more than the player was able to move + EntityPosition.Move(offset); + + // move the player down + SystemBody.MoveBody(MapManager.ObjLink._body, offset * Game1.TimeMultiplier, + Values.CollisionTypes.Normal, false, false, false); + + _wasMoved = true; + if (_strPlatformKey != null) + { + // make sure other linked platforms will also be moved + var platformOffset = _startPosition.Y - EntityPosition.Position.Y; + Game1.GameManager.SaveManager.SetString(_strPlatformKey, platformOffset.ToString(CultureInfo.InvariantCulture)); + Game1.GameManager.SaveManager.SetString(_strPlatformMovedKey, "true"); + } + } + + // this checks if the player can be moved down with the platform or if the player + // is also standing on a ledge and is not really pushing down on the platform + private bool PlayerIsMovable() + { + var lastPosition = MapManager.ObjLink.EntityPosition.Position; + + _cBoxCollision.IsActive = false; + SystemBody.MoveBody(MapManager.ObjLink._body, new Vector2(0, 1), Values.CollisionTypes.Normal, false, false, false); + _cBoxCollision.IsActive = true; + + // check if the player was moved + var playerCanMove = MapManager.ObjLink.EntityPosition.Y != lastPosition.Y; + + // move the player back to the original position + MapManager.ObjLink.EntityPosition.Set(lastPosition); + + return playerCanMove; + } + + private void Draw(SpriteBatch spriteBatch) + { + // draw the chain + var chainLinkCount = (int)Math.Ceiling((EntityPosition.Y - _chainPosition.Y) / 16); + for (var i = 0; i < chainLinkCount; i++) + spriteBatch.Draw(_spriteChain.Texture, new Vector2(_chainPosition.X, _chainPosition.Y + i * 16), _spriteChain.ScaledRectangle, Color.White); + + // draw the platform + spriteBatch.Draw(_spritePlatform.Texture, EntityPosition.Position, _spritePlatform.ScaledRectangle, Color.White); + } + } +} diff --git a/InGame/GameObjects/Things/ObjChest.cs b/InGame/GameObjects/Things/ObjChest.cs new file mode 100644 index 0000000..7f9c02e --- /dev/null +++ b/InGame/GameObjects/Things/ObjChest.cs @@ -0,0 +1,272 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Enemies; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjChest : GameObject + { + private readonly AiComponent _aiComponent; + private readonly ObjSprite _spriteFront; + private readonly CSprite _spriteBack; + private readonly GameObject _spawnObject; + + private ObjSprite _itemSprite; + private GameItem _item; + + private readonly string _itemName; + private readonly string _locationBound; + public readonly string ItemKey; + private readonly string _dialogPath; + + // @INFO: this time is also used in the "seashell" script and should be changed there also + private const int FadeTime = 175; + private const int MoveTime = 250; + + private bool _isActive = true; + public override bool IsActive + { + get => _isActive; + set + { + _isActive = value; + _spriteFront.IsActive = value; + + // this is needed when the last shell in a chest is found because the chest will get deactivated + if (_itemSprite != null) + _itemSprite.Sprite.Color = Color.Transparent; + + CheckOpened(); + } + } + + private bool _opened; + + public ObjChest() : base("chest") { } + + public ObjChest(Map.Map map, int posX, int posY, string itemName, string itemBounding, string itemKey, int spriteType, bool hitMode) : base(map) + { + EntityPosition = new CPosition(posX, posY + 13, 0); + EntitySize = new Rectangle(0, -13, 16, 16); + + _itemName = itemName; + _locationBound = itemBounding; + ItemKey = itemKey; + + var openingTrigger = new AiTriggerCountdown(MoveTime, OpeningTick, OpeningEnd); + var fadingTrigger = new AiTriggerCountdown(FadeTime, FadeTick, FadeEnd); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("closed", new AiState()); + _aiComponent.States.Add("opening", new AiState { Init = InitOpen, Trigger = { openingTrigger } }); + _aiComponent.States.Add("opened", new AiState { Init = InitOpen }); + _aiComponent.States.Add("textbox", new AiState(UpdateTextBox)); + _aiComponent.States.Add("fading", new AiState { Trigger = { fadingTrigger } }); + _aiComponent.ChangeState("closed"); + + AddComponent(AiComponent.Index, _aiComponent); + + if (!hitMode) + AddComponent(InteractComponent.Index, new InteractComponent(new CBox(posX + 4, posY + 3, 0, 8, 13, 16), Interact)); + else + { + AddComponent(HittableComponent.Index, new HittableComponent(new CBox(posX + 4, posY + 3, 0, 8, 13, 16), OnHit)); + } + + AddComponent(CollisionComponent.Index, new BoxCollisionComponent( + new CBox(posX, posY + 3, 0, 16, 11, 12), Values.CollisionTypes.Normal | Values.CollisionTypes.Hookshot)); + + _spriteBack = new CSprite("chest_back", new CPosition(posX, posY + 12.9f, 0), new Vector2(0, -12.9f)); + _spriteBack.SourceRectangle.X += spriteType * 32; + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_spriteBack, Values.LayerPlayer)); + + // sprite front + _spriteFront = new ObjSprite(map, posX, posY + 13, "chest_front", Vector2.Zero, Values.LayerPlayer, null); + _spriteFront.Sprite.SourceRectangle.X += spriteType * 32; + Map.Objects.SpawnObject(_spriteFront); + + // check if the chest was already opened + if (!CheckOpened()) + { + if (_itemName == "greenZol") + { + // @TODO: sound effect + var greenZol = new EnemyGreenZol(Map, posX, posY, 8, false); + greenZol.SpawnDelay(); + _spawnObject = greenZol; + } + else if (_itemName != null && _itemName.StartsWith("dialog:")) + { + _dialogPath = _itemName.Remove(0, 7); + } + else if (!CreateItem()) + IsDead = true; + } + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + if ((type & HitType.ThrownObject) != 0) + { + OpenChest(); + return Values.HitCollision.Blocking; + } + + return Values.HitCollision.None; + } + + private bool CheckOpened() + { + if (!string.IsNullOrEmpty(ItemKey) && Game1.GameManager.SaveManager.GetString(ItemKey) == "1") + { + _aiComponent.ChangeState("opened"); + return true; + } + + return false; + } + + private bool CreateItem() + { + if (_itemName == null) + return false; + + _item = Game1.GameManager.ItemManager[_itemName]; + + if (_item == null) + return false; + + Rectangle itemSource; + + if (_item.SourceRectangle.HasValue) + itemSource = _item.SourceRectangle.Value; + else + { + var baseItem = Game1.GameManager.ItemManager[_item.Name]; + itemSource = baseItem.SourceRectangle.Value; + } + + // the offset is needed so the item would not be behind the chest + _itemSprite = new ObjSprite(Map, 0, 0, Resources.SprItem, itemSource, new Vector2(0, -itemSource.Height + 1), Values.LayerPlayer); + _itemSprite.EntityPosition.Set(new Vector2(EntityPosition.X + 8 - itemSource.Width / 2f, EntityPosition.Y - 0.05f)); + _itemSprite.Sprite.Color = Color.Transparent; + + Map.Objects.SpawnObject(_itemSprite); + + return true; + } + + private void InitOpen() + { + if (_opened) + return; + + _opened = true; + _spriteBack.SourceRectangle.X += 16; + _spriteFront.Sprite.SourceRectangle.X += 16; + } + + private void OpeningTick(double tick) + { + MapManager.ObjLink.FreezePlayer(); + _itemSprite.EntityPosition.Z = (float)Math.Sin((float)(MoveTime - tick) / MoveTime * Math.PI / 1.55f) * 10; + } + + private void OpeningEnd() + { + OpeningTick(0); + PickUpItem(); + } + + private void PickUpItem() + { + _aiComponent.ChangeState("textbox"); + + var collectedItem = new GameItemCollected(_itemName) + { Count = _item.Count, LocationBounding = _locationBound }; + MapManager.ObjLink.PickUpItem(collectedItem, true); + + SetKey(); + } + + private void UpdateTextBox() + { + // don't fade away if the item is shown + if (_item.ShowAnimation != 0) + FadeEnd(); + else + _aiComponent.ChangeState("fading"); + } + + private void FadeTick(double time) + { + _itemSprite.Sprite.Color = Color.White * (float)(time / FadeTime); + } + + private void FadeEnd() + { + _itemSprite.Sprite.Color = Color.Transparent; + _aiComponent.ChangeState("opened"); + } + + private void SpawnObject() + { + // spawn the object + Map.Objects.SpawnObject(_spawnObject); + } + + private void SetKey() + { + if (!string.IsNullOrEmpty(ItemKey)) + Game1.GameManager.SaveManager.SetString(ItemKey, "1"); + } + + private bool OpenChest() + { + if (_aiComponent.CurrentStateId != "closed") + return false; + + Game1.GameManager.PlaySoundEffect("D378-04-04"); + + // spawn object + if (_spawnObject != null) + { + Game1.GameManager.PlaySoundEffect("D360-29-1D"); + + _aiComponent.ChangeState("opened"); + SpawnObject(); + SetKey(); + } + // show dialog + else if (_dialogPath != null) + { + _aiComponent.ChangeState("opened"); + Game1.GameManager.StartDialogPath(_dialogPath); + SetKey(); + } + // spawn item + else + { + _aiComponent.ChangeState("opening"); + _itemSprite.Sprite.Color = Color.White; + } + + return true; + } + + private bool Interact() + { + // only open if the player is facing up and the chest is closed + if (MapManager.ObjLink.Direction != 1) + return false; + + return OpenChest(); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjCockParticle.cs b/InGame/GameObjects/Things/ObjCockParticle.cs new file mode 100644 index 0000000..3a6e3e5 --- /dev/null +++ b/InGame/GameObjects/Things/ObjCockParticle.cs @@ -0,0 +1,193 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Things; +using Microsoft.Xna.Framework.Graphics; +using System; +using ProjectZ.InGame.GameObjects.Base.Components.AI; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjCockParticle : GameObject + { + private readonly CSprite[] _sprites = new CSprite[4]; + private readonly CPosition[] _positions = new CPosition[4]; + + private readonly Color _color0 = new Color(57, 0, 189); + private readonly Color _color1 = new Color(255, 181, 49); + + // center where the particle is circling around + private readonly Vector2[] _circleCenters = new Vector2[7]; + // the amount we circle a specifiy center + private readonly float[] _circleRadians = new float[7]; + + private readonly Vector2 _endPosition; + + // 800ms to circle the circle with a radius of 10px = ~1px per frame + private const float CircleSpeed = MathF.PI / 800; + private const int Radius = 10; + private const int OffsetEnd = 12; + // 0/1 clockwise/reversed clockwise + private const int Direction = 1; + + private float _moveCounter; + private float _startRadiants; + + private bool _isRunning = true; + + public ObjCockParticle(Map.Map map, Vector2 endPosition) : base(map) + { + Tags = Values.GameObjectTag.Enemy; + + EntityPosition = new CPosition(endPosition.X, endPosition.Y, 0); + EntitySize = new Rectangle(-8, -8, 16, 16); + + _circleRadians[0] = 2.1f * (MathF.PI / 2); + _circleRadians[1] = 2.1f * (MathF.PI / 2); + _circleRadians[2] = 3.4f * (MathF.PI / 2); + _circleRadians[3] = 2.2f * (MathF.PI / 2); + _circleRadians[4] = 1.8f * (MathF.PI / 2); + _circleRadians[5] = 2.9f * (MathF.PI / 2); + _circleRadians[6] = 1 * (MathF.PI / 2); + + var startOffset = new Vector2(-Radius, -OffsetEnd); + _circleCenters[_circleCenters.Length - 1] = endPosition + startOffset; + // calculate the center positions + var radiantSum = MathF.PI; + for (int i = _circleCenters.Length - 2; i >= 0; i--) + { + var radiant = radiantSum - _circleRadians[i + 1]; + if (i % 2 == Direction) + radiant = radiantSum + _circleRadians[i + 1]; + + if (i % 2 == Direction) + radiantSum += _circleRadians[i + 1] + MathF.PI; + else + radiantSum -= _circleRadians[i + 1] + MathF.PI; + + var offset = new Vector2(-MathF.Cos(radiant), MathF.Sin(radiant)) * Radius * 2; + _circleCenters[i] = _circleCenters[i + 1] + offset; + } + + _startRadiants = MathF.PI; + for (int i = 0; i < _circleRadians.Length; i++) + { + if (i % 2 == Direction) + _startRadiants -= _circleRadians[i]; + else + _startRadiants += _circleRadians[i]; + } + if (_circleRadians.Length % 2 == 0) + _startRadiants += MathF.PI; + + _sprites[0] = new CSprite("cock_particle_0", _positions[0] = new CPosition(0, 0, 0), new Vector2(-4, -4)); + _sprites[1] = new CSprite("cock_particle_1", _positions[1] = new CPosition(0, 0, 0), new Vector2(-3, -3)); + _sprites[2] = new CSprite("cock_particle_2", _positions[2] = new CPosition(0, 0, 0), new Vector2(-2, -2)); + _sprites[3] = new CSprite("cock_particle_2", _positions[3] = new CPosition(0, 0, 0), new Vector2(-2, -2)); + + _endPosition = endPosition; + + var damageCollider = new CBox(EntityPosition, -3, -3, 0, 6, 6, 8); + var hittableBox = new CBox(EntityPosition, -4, -4, 0, 8, 8, 8); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerTop, EntityPosition)); + AddComponent(LightDrawComponent.Index, new LightDrawComponent(DrawLight)); + } + + private void Update() + { + _moveCounter += Game1.DeltaTime; + + var position0 = GetPosition(_moveCounter); + _positions[0].Set(position0); + var position1 = GetPosition(_moveCounter - 100); + _positions[1].Set(position1); + var position2 = GetPosition(_moveCounter - 200); + _positions[2].Set(position2); + var position3 = GetPosition(_moveCounter - 300); + _positions[3].Set(position3); + + if (position0 == Vector2.Zero) + _isRunning = false; + } + + private Vector2 GetPosition(float time) + { + var circleTime = time * CircleSpeed; + var radiantSum = _startRadiants; + for (int i = 0; i < _circleRadians.Length; i++) + { + if (circleTime < _circleRadians[i]) + { + var radiant = radiantSum + circleTime; + // move arount the circle in clockwise or reversed clockwise + if (i % 2 != Direction) + radiant = radiantSum - circleTime; + + return _circleCenters[i] + new Vector2(-MathF.Cos(radiant), MathF.Sin(radiant)) * Radius; + } + else + { + circleTime -= _circleRadians[i]; + + if (i % 2 == Direction) + radiantSum += _circleRadians[i] + MathF.PI; + else + radiantSum -= _circleRadians[i] + MathF.PI; + } + } + + var startPosition = _circleCenters[_circleCenters.Length - 1] - new Vector2(-MathF.Cos(radiantSum), MathF.Sin(radiantSum)) * Radius; + var targetPosition = _endPosition; + var percentage = (circleTime / CircleSpeed) / 1000 * (60 / 12); + var newPosition = Vector2.Lerp(startPosition, targetPosition, percentage); + + if (percentage < 1) + return newPosition; + else + return Vector2.Zero; + } + + private void Draw(SpriteBatch spriteBatch) + { + // debug points + //for (int i = 0; i < _circleCenters.Length; i++) + // spriteBatch.Draw(Resources.SprWhite, _circleCenters[i] - new Vector2(1, 1), new Rectangle(0, 0, 2, 2), Color.Red); + + // blink + var color = (Game1.TotalGameTime % (AiDamageState.BlinkTime * 2) < AiDamageState.BlinkTime) ? _color0 : _color1; + + for (int i = 0; i < _sprites.Length; i++) + { + // zero vector => invisible + if (_positions[i].Position != Vector2.Zero) + { + _sprites[i].Color = color; + _sprites[i].Draw(spriteBatch); + } + } + } + + private void DrawLight(SpriteBatch spriteBatch) + { + for (int i = 0; i < _sprites.Length; i++) + { + // zero vector => invisible + if (_positions[i].Position != Vector2.Zero) + { + var sizeMult = i == 0 ? 1 : 0.75f;// (4 - i) / 4f; + DrawHelper.DrawLight(spriteBatch, + new Rectangle((int)(_positions[i].X - 16 * sizeMult), (int)(_positions[i].Y - 16 * sizeMult), + (int)(32 * sizeMult), (int)(32 * sizeMult)), Color.White); + } + } + } + + public bool IsRunning() + { + return _isRunning; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjCollider.cs b/InGame/GameObjects/Things/ObjCollider.cs new file mode 100644 index 0000000..4fd5788 --- /dev/null +++ b/InGame/GameObjects/Things/ObjCollider.cs @@ -0,0 +1,95 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjCollider : GameObject + { + private Box _singleCollisionBox; + private Box[] CollisionBoxes { get; } + + private readonly Color _editorColor = Color.DarkRed * 0.65f; + private readonly int _level = -1; + + public ObjCollider(Map.Map map, int posX, int posY, Color editorColor, Values.CollisionTypes type, params Rectangle[] rectangles) : base(map) + { + EditorIconSource = new Rectangle(0, 0, 16, 16); + _editorColor = editorColor; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + CollisionBoxes = new Box[rectangles.Length]; + for (var i = 0; i < rectangles.Length; i++) + CollisionBoxes[i] = new Box( + posX + rectangles[i].X, posY + rectangles[i].Y, 0, + rectangles[i].Width, rectangles[i].Height, 16); + + AddComponent(CollisionComponent.Index, new CollisionComponent(MultiBoxCollision) { CollisionType = type }); + } + + public ObjCollider(Map.Map map, int posX, int posY, int height, Rectangle rectangle, Values.CollisionTypes type, int level) : base(map) + { + EditorIconSource = new Rectangle(0, 0, 16, 16); + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + _level = level; + _singleCollisionBox = new Box( + posX + rectangle.X, posY + rectangle.Y, 0, + rectangle.Width, rectangle.Height, height); + + AddComponent(CollisionComponent.Index, new CollisionComponent(SingeBoxCollision) { CollisionType = type }); + } + + private bool MultiBoxCollision(Box box, int dir, int level, ref Box collidingBox) + { + foreach (var singleBox in CollisionBoxes) + if (singleBox.Intersects(box)) + { + collidingBox = singleBox; + return true; + } + + return false; + } + + private bool SingeBoxCollision(Box box, int dir, int level, ref Box collidingBox) + { + if ((_level != -1 && _level < level) || !_singleCollisionBox.Intersects(box)) + return false; + + collidingBox = _singleCollisionBox; + return true; + } + + public override void DrawEditor(SpriteBatch spriteBatch, Vector2 drawPosition) + { + if (CollisionBoxes != null) + for (var i = 0; i < CollisionBoxes.Length; i++) + { + spriteBatch.Draw(Resources.SprWhite, + new Rectangle( + (int)(drawPosition.X + CollisionBoxes[i].X), + (int)(drawPosition.Y + CollisionBoxes[i].Y), + (int)CollisionBoxes[i].Width, + (int)CollisionBoxes[i].Height), _editorColor); + } + else + { + spriteBatch.Draw(Resources.SprWhite, + new Rectangle( + (int)(drawPosition.X + _singleCollisionBox.X), + (int)(drawPosition.Y + _singleCollisionBox.Y), + (int)_singleCollisionBox.Width, + (int)_singleCollisionBox.Height), _editorColor); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjColliderOneWay.cs b/InGame/GameObjects/Things/ObjColliderOneWay.cs new file mode 100644 index 0000000..4c1a3b0 --- /dev/null +++ b/InGame/GameObjects/Things/ObjColliderOneWay.cs @@ -0,0 +1,39 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjColliderOneWay : GameObject + { + private readonly Box _collisionBox; + private readonly int _direction; + + public ObjColliderOneWay(Map.Map map, int posX, int posY, Rectangle collisionRectangle, Values.CollisionTypes type, int direction) : base(map) + { + SprEditorImage = Resources.SprWhite; + EditorIconSource = new Rectangle(0, 0, collisionRectangle.Width, collisionRectangle.Height); + EditorColor = Color.DeepPink; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = collisionRectangle; + + _collisionBox = new Box(posX + collisionRectangle.X, posY + collisionRectangle.Y, 0, collisionRectangle.Width, collisionRectangle.Height, 8); + _direction = direction; + + AddComponent(CollisionComponent.Index, new CollisionComponent(CollisionCheck) { CollisionType = type }); + } + + private bool CollisionCheck(Box box, int dir, int level, ref Box collidingBox) + { + if (dir != _direction || !_collisionBox.Intersects(box)) + return false; + + collidingBox = _collisionBox; + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjColorShift.cs b/InGame/GameObjects/Things/ObjColorShift.cs new file mode 100644 index 0000000..30e9b06 --- /dev/null +++ b/InGame/GameObjects/Things/ObjColorShift.cs @@ -0,0 +1,35 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjColorShift : GameObject + { + private Rectangle _collisionRectangle; + private readonly int _colorDirection; + + public ObjColorShift() : base("editor color shift") { } + + public ObjColorShift(Map.Map map, int posX, int posY, int colorDirection, int width, int height) : base(map) + { + _collisionRectangle = new Rectangle(posX, posY, width, height); + _colorDirection = colorDirection; + + AddComponent(ObjectCollisionComponent.Index, new ObjectCollisionComponent(_collisionRectangle, OnCollision)); + } + + public void OnCollision(GameObject gameObject) + { + if (_colorDirection == 1) + Game1.GameManager.ForestColorState = 1 - (MapManager.ObjLink.PosX - _collisionRectangle.X) / _collisionRectangle.Width; + else if (_colorDirection == 2) + Game1.GameManager.ForestColorState = 1 - (MapManager.ObjLink.PosY - _collisionRectangle.Y) / _collisionRectangle.Height; + else if (_colorDirection == 3) + Game1.GameManager.ForestColorState = (MapManager.ObjLink.PosY - _collisionRectangle.Y) / _collisionRectangle.Height; + else + Game1.GameManager.ForestColorState = MathHelper.Clamp(Game1.GameManager.ForestColorState, 0, 1) * 0.55f; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjCompassSound.cs b/InGame/GameObjects/Things/ObjCompassSound.cs new file mode 100644 index 0000000..4c37a4a --- /dev/null +++ b/InGame/GameObjects/Things/ObjCompassSound.cs @@ -0,0 +1,70 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjCompassSound : GameObject + { + private Rectangle _roomRectangle; + private Vector2 _position; + private string _key; + private bool _isTriggered; + + public ObjCompassSound() : base("editor compass sound") { } + + public ObjCompassSound(Map.Map map, int posX, int posY, string key) : base(map) + { + _roomRectangle = map.GetField(posX, posY); + var center = _roomRectangle.Center; + _position = new Vector2(center.X, center.Y); + _key = key; + + if (string.IsNullOrEmpty(key) || + Game1.GameManager.SaveManager.GetString(_key, "0") == "1") + { + IsDead = true; + return; + } + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + } + + private void Update() + { + if (!_isTriggered) + { + // player walked into the room? + if (_roomRectangle.Contains(MapManager.ObjLink.EntityPosition.Position)) + { + _isTriggered = true; + + // check if the player has a compass + var hasCompass = Game1.GameManager.GetItem("compass") != null; + if (hasCompass) + Game1.GameManager.PlaySoundEffect("D370-27-1B"); + } + } + // reset when the player is far enough away + else + { + var distance = _position - MapManager.ObjLink.EntityPosition.Position; + if (MathF.Abs(distance.X) > Values.FieldWidth * 0.8f || + MathF.Abs(distance.Y) > 128 * 0.8f) + _isTriggered = false; + } + } + + private void KeyChanged() + { + // delete the object if the item was collected + var keyState = Game1.GameManager.SaveManager.GetString(_key, "0"); + if (keyState == "1") + Map.Objects.DeleteObjects.Add(this); + } + } +} diff --git a/InGame/GameObjects/Things/ObjCrystal.cs b/InGame/GameObjects/Things/ObjCrystal.cs new file mode 100644 index 0000000..cd495fb --- /dev/null +++ b/InGame/GameObjects/Things/ObjCrystal.cs @@ -0,0 +1,103 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjCrystal : GameObject + { + private readonly CBox _hittableBoxSmall; + private readonly Color _lightColor; + private readonly string _dialogPath; + private readonly bool _isHardCrystal; + + public ObjCrystal(Map.Map map, int posX, int posY, string spriteId, int color, bool hardCrystal, string dialogPath) : base(map, spriteId) + { + var sprite = Resources.GetSprite(spriteId); + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-40, -8 - 40, 80, 80); + + if (color == 0) + _lightColor = new Color(240, 100, 255); + else if (color == 1) + _lightColor = new Color(255, 255, 255) * 0.25f; + + _isHardCrystal = hardCrystal; + _dialogPath = dialogPath; + + var box = new CBox(posX, posY + 16 - 12, 0, 16, 12, 16); + var hittableBox = new CBox(EntityPosition, -7, -15, 0, 14, 13, 8); + _hittableBoxSmall = new CBox(EntityPosition, -6, -13, 0, 12, 10, 8, true); + + if (!string.IsNullOrEmpty(_dialogPath)) + AddComponent(PushableComponent.Index, new PushableComponent(box, OnPush) { InertiaTime = 50 }); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(box, Values.CollisionTypes.Normal)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(DrawComponent.Index, new DrawSpriteComponent(spriteId, EntityPosition, new Vector2(-8, -16), Values.LayerPlayer)); + AddComponent(LightDrawComponent.Index, new LightDrawComponent(DrawLight)); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType pushType) + { + if (pushType == PushableComponent.PushType.Impact) + return false; + + Game1.GameManager.StartDialogPath(_dialogPath); + + return false; + } + + private void DrawLight(SpriteBatch spriteBatch) + { + DrawHelper.DrawLight(spriteBatch, new Rectangle((int)EntityPosition.X - 40, (int)EntityPosition.Y - 8 - 40, 80, 80), _lightColor); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if ((_isHardCrystal && damageType != HitType.PegasusBootsSword) || (damageType & HitType.SwordHold) != 0 || damageType == HitType.Hookshot) + return Values.HitCollision.None; + + // this is really stupid + // for the sword attacks a smaller hitbox is used + if ((damageType & HitType.Sword) != 0 && + gameObject is ObjLink player && !player.IsPoking) + { + var collidingRec = player.SwordDamageBox.Rectangle().GetIntersection(_hittableBoxSmall.Box.Rectangle()); + var collidingArea = collidingRec.Width * collidingRec.Height; + + if (collidingArea < 16) + return Values.HitCollision.None; + } + + Game1.GameManager.PlaySoundEffect("D378-09-09"); + + // remove this object from the map + Map.Objects.DeleteObjects.Add(this); + + // spawn small particle stones + var mult = damageType == HitType.PegasusBootsSword ? 1.0f : 0.25f; + var velZ = 0.5f; + var diff = 200f; + var vector0 = new Vector3(-1, -1, 0) * Game1.RandomNumber.Next(50, 75) / diff + new Vector3(direction * mult, velZ); + var vector1 = new Vector3(-1, 0, 0) * Game1.RandomNumber.Next(50, 75) / diff + new Vector3(direction * mult, velZ); + var vector2 = new Vector3(1, -1, 0) * Game1.RandomNumber.Next(50, 75) / diff + new Vector3(direction * mult, velZ); + var vector3 = new Vector3(1, 0, 0) * Game1.RandomNumber.Next(50, 75) / diff + new Vector3(direction * mult, velZ); + + var stone0 = new ObjSmallStone(Map, (int)EntityPosition.X + 2, (int)EntityPosition.Y - 10, Game1.RandomNumber.Next(4, 8), vector0); + var stone1 = new ObjSmallStone(Map, (int)EntityPosition.X + 2, (int)EntityPosition.Y - 6, Game1.RandomNumber.Next(4, 8), vector1); + var stone2 = new ObjSmallStone(Map, (int)EntityPosition.X + 6, (int)EntityPosition.Y - 10, Game1.RandomNumber.Next(4, 8), vector2); + var stone3 = new ObjSmallStone(Map, (int)EntityPosition.X + 6, (int)EntityPosition.Y - 6, Game1.RandomNumber.Next(4, 8), vector3); + + Map.Objects.SpawnObject(stone0); + Map.Objects.SpawnObject(stone1); + Map.Objects.SpawnObject(stone2); + Map.Objects.SpawnObject(stone3); + + return Values.HitCollision.Blocking; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjDestroyableStone.cs b/InGame/GameObjects/Things/ObjDestroyableStone.cs new file mode 100644 index 0000000..3983d01 --- /dev/null +++ b/InGame/GameObjects/Things/ObjDestroyableStone.cs @@ -0,0 +1,79 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjDestroyableStone : GameObject + { + private readonly string _saveKey; + + public ObjDestroyableStone(Map.Map map, int posX, int posY, Rectangle sourceRectangle, string saveKey) : base(map) + { + EditorIconSource = sourceRectangle; + SprEditorImage = Resources.SprObjects; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, sourceRectangle.Width, sourceRectangle.Height); + + // don't spawn the object if it was already destroyed + if (saveKey != null && Game1.GameManager.SaveManager.GetString(saveKey) == "1") + { + IsDead = true; + return; + } + + _saveKey = saveKey; + + var rectangle = new CBox(posX, posY, 0, sourceRectangle.Width, sourceRectangle.Height, 16); + var sprite = new CSprite(Resources.SprObjects, EntityPosition, EditorIconSource, new Vector2(0, 0)); + + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(rectangle, Values.CollisionTypes.Normal)); + AddComponent(HittableComponent.Index, new HittableComponent(rectangle, OnHit)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerBottom)); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + // gets destroyed by a bomb + if (damageType == HitType.Bomb) + { + Game1.GameManager.PlaySoundEffect("D360-02-02"); + + Map.Objects.DeleteObjects.Add(this); + + if (!string.IsNullOrEmpty(_saveKey)) + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + for (var y = 0; y < 2; y++) + { + for (var x = 0; x < 2; x++) + { + const float upVec = 1.5f; + const float spread = 200f; + var vector0 = new Vector3(-1, -1, 0) * Game1.RandomNumber.Next(50, 150) / spread + new Vector3(0, 0, upVec); + var vector1 = new Vector3(-1, 0, 0) * Game1.RandomNumber.Next(50, 150) / spread + new Vector3(0, 0, upVec); + var vector2 = new Vector3(1, -1, 0) * Game1.RandomNumber.Next(50, 150) / spread + new Vector3(0, 0, upVec); + var vector3 = new Vector3(1, 0, 0) * Game1.RandomNumber.Next(50, 150) / spread + new Vector3(0, 0, upVec); + + var stone0 = new ObjSmallStone(Map, (int)EntityPosition.X + 4 + x * 16, (int)EntityPosition.Y + 4 + y * 16, (int)EntityPosition.Z, vector0); + var stone1 = new ObjSmallStone(Map, (int)EntityPosition.X + 4 + x * 16, (int)EntityPosition.Y + 12 + y * 16, (int)EntityPosition.Z, vector1); + var stone2 = new ObjSmallStone(Map, (int)EntityPosition.X + 12 + x * 16, (int)EntityPosition.Y + 4 + y * 16, (int)EntityPosition.Z, vector2); + var stone3 = new ObjSmallStone(Map, (int)EntityPosition.X + 12 + x * 16, (int)EntityPosition.Y + 12 + y * 16, (int)EntityPosition.Z, vector3); + + Map.Objects.SpawnObject(stone0); + Map.Objects.SpawnObject(stone1); + Map.Objects.SpawnObject(stone2); + Map.Objects.SpawnObject(stone3); + } + } + + return Values.HitCollision.Blocking; + } + + return Values.HitCollision.None; + } + } +} diff --git a/InGame/GameObjects/Things/ObjDialogBox.cs b/InGame/GameObjects/Things/ObjDialogBox.cs new file mode 100644 index 0000000..8031b9d --- /dev/null +++ b/InGame/GameObjects/Things/ObjDialogBox.cs @@ -0,0 +1,47 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; + +namespace ProjectZ.InGame.GameObjects.Things +{ + public class ObjDialogBox : GameObject + { + private readonly string _dialogName; + + private bool _wasActive = false; + private bool _isActive = true; + + public override bool IsActive + { + get => _isActive; + set + { + _isActive = value; + Init(); + _wasActive = _isActive; + } + } + + public ObjDialogBox() : base("editor dialog box") + { + EditorColor = Color.GreenYellow; + } + + public ObjDialogBox(Map.Map map, int posX, int posY, string dialogName) : base(map) + { + _dialogName = dialogName; + + if (string.IsNullOrEmpty(_dialogName)) + IsDead = true; + } + + public override void Init() + { + // execute the dialog path + if (_isActive && !_wasActive) + { + Game1.GameManager.StartDialogPath(_dialogName); + _wasActive = true; + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjDoor.cs b/InGame/GameObjects/Things/ObjDoor.cs new file mode 100644 index 0000000..9eb780b --- /dev/null +++ b/InGame/GameObjects/Things/ObjDoor.cs @@ -0,0 +1,251 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameSystems; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + public class ObjDoor : GameObject + { + private Rectangle _collisionRectangle; + + public string _entryId; + public string _nextMap; + private string _exitId; + + private int _direction; + + // 0: normal door + // 1: stairs + // 2: no walk in transition + fall + // 3: swim in transition + // 4: no walk in transition + // 5: final stairs transition + // 6: fall + rotate + // 7: fall + private int _mode; + private int _positionOffset; + + private bool _isColliding; + private bool _wasColliding; + public bool _savePosition; + private bool _isTransitioning; + + public ObjDoor() : base("editor door") + { + EditorColor = Color.Yellow * 0.65f; + } + + public ObjDoor(Map.Map map, int posX, int posY, int width, int height, + string entryId, string nextMapId, string exitId, int direction, int mode, bool savePosition) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, width, height); + + // stairs have a smaller entry + if (Map.Is2dMap || mode != 1) + _collisionRectangle = new Rectangle(posX, posY, width, height); + else + { + _collisionRectangle = new Rectangle(posX + 6, posY + 6, width - 12, height - 12); + _positionOffset = 4; + } + + if (mode == 4) + { + _collisionRectangle.Height = 10; + } + + _entryId = entryId; + _direction = direction; + _mode = mode; + _savePosition = savePosition; + + // has the player just entered this door? + if (_entryId != null && MapManager.ObjLink.NextMapPositionId == _entryId) + PlacePlayer(); + + _nextMap = nextMapId; + _exitId = exitId; + + if (!string.IsNullOrEmpty(_nextMap) && !string.IsNullOrEmpty(_exitId)) + { + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(ObjectCollisionComponent.Index, + new ObjectCollisionComponent(_collisionRectangle, OnCollision)); + } + } + + private void Update() + { + _wasColliding = _isColliding; + _isColliding = false; + } + + private void OnCollision(GameObject gameObject) + { + // can jump over stair entries + if (_mode == 1 && !MapManager.ObjLink.IsGrounded() && !Map.Is2dMap) + return; + + if (_mode == 3 && !MapManager.ObjLink.IsDiving() && !Map.Is2dMap) + return; + + if (MapManager.ObjLink.IsRailJumping()) + return; + + _isColliding = true; + + // first step on the door? + if (MapManager.ObjLink.WasHoleReset || MapManager.ObjLink.CurrentState == ObjLink.State.Dying || _wasColliding || _isTransitioning) + return; + + _isTransitioning = true; + + var transitionEnd = new Vector2( + _collisionRectangle.X + _collisionRectangle.Width / 2f, + _collisionRectangle.Y + _collisionRectangle.Height / 2f + MapManager.ObjLink._body.Height / 2f); + var color = Values.MapTransitionColor; + var colorMode = false; + + if (_mode == 0) + { + if (_direction == 1) + transitionEnd.Y = _collisionRectangle.Y + 8; + else if (_direction == 3) + transitionEnd.Y = _collisionRectangle.Y + 16; + + if (!Map.Is2dMap) + MapManager.ObjLink.Direction = (_direction + 2) % 4; + + // walk on the ground + if (Map.Is2dMap && (_direction % 2) == 0) + transitionEnd.Y = _collisionRectangle.Bottom; + } + else if (_mode == 3) + { + if (Map.Is2dMap) + { + if (_direction == 0) + transitionEnd = MapManager.ObjLink.EntityPosition.Position + new Vector2(8, 0); + else if (_direction == 2) + transitionEnd = MapManager.ObjLink.EntityPosition.Position + new Vector2(-8, 0); + else if (_direction == 3) + transitionEnd = MapManager.ObjLink.EntityPosition.Position + + new Vector2(MapManager.ObjLink.GetSwimVelocity().X * 8, -8); + + // look at the camera + MapManager.ObjLink.Direction = 3; + } + else + // do not move while transitioning out + transitionEnd = MapManager.ObjLink.EntityPosition.Position; + } + else if (_mode == 5) + { + transitionEnd = MapManager.ObjLink.EntityPosition.Position + MapManager.ObjLink._body.VelocityTarget * 60 * (MapTransitionSystem.ChangeMapTime / 1000f); + color = Color.White; + colorMode = true; + } + + Game1.GameManager.PlaySoundEffect("D378-06-06"); + + MapManager.ObjLink.MapTransitionStart = MapManager.ObjLink.EntityPosition.Position; + MapManager.ObjLink.MapTransitionEnd = transitionEnd; + MapManager.ObjLink.TransitionOutWalking = MapManager.ObjLink.EntityPosition.Position != transitionEnd; + + // append a map change + var transitionSystem = (MapTransitionSystem)Game1.GameManager.GameSystems[typeof(MapTransitionSystem)]; + transitionSystem.AppendMapChange(_nextMap, _exitId, false, false, color, colorMode); + } + + private void PlacePlayer() + { + _isColliding = true; + _wasColliding = true; + + var transitionStart = new Vector2( + _collisionRectangle.X + _collisionRectangle.Width / 2f, + _collisionRectangle.Y + _collisionRectangle.Height / 2f + MapManager.ObjLink._body.Height / 2f); + var transitionEnd = transitionStart; + + if (_mode == 0 || _mode == 1) + { + if (_direction == 0) + transitionEnd.X = _collisionRectangle.X - MathF.Ceiling(MapManager.ObjLink._body.Width / 2f) - _positionOffset; + else if (_direction == 1) + transitionEnd.Y = _collisionRectangle.Y - _positionOffset; + else if (_direction == 2) + transitionEnd.X = _collisionRectangle.X + _collisionRectangle.Width + MathF.Ceiling(MapManager.ObjLink._body.Width / 2f) + _positionOffset; + else if (_direction == 3) + transitionEnd.Y = _collisionRectangle.Y + _collisionRectangle.Height + MapManager.ObjLink._body.Height + _positionOffset; + + // walk on the ground + if (Map.Is2dMap && (_direction % 2) == 0) + { + transitionStart.Y = _collisionRectangle.Bottom; + transitionEnd.Y = _collisionRectangle.Bottom; + } + } + else if (_mode == 2) + { + MapManager.ObjLink.NextMapFallStart = true; + } + else if (_mode == 3) + { + if (_direction == 0) + transitionEnd.X = _collisionRectangle.X - MathF.Ceiling(MapManager.ObjLink._body.Width / 2f) - _positionOffset; + else if (_direction == 1) + transitionEnd.Y = _collisionRectangle.Y - _positionOffset; + else if (_direction == 2) + transitionEnd.X = _collisionRectangle.X + _collisionRectangle.Width + MathF.Ceiling(MapManager.ObjLink._body.Width / 2f) + _positionOffset; + else if (_direction == 3) + transitionEnd.Y = _collisionRectangle.Y + _collisionRectangle.Height + MapManager.ObjLink._body.Height + _positionOffset; + } + else if (_mode == 4) + { + // why was this here? + //transitionEnd.Y = _collisionRectangle.Y + _collisionRectangle.Height + MapManager.ObjLink._body.Height - _positionOffset; + } + else if (_mode == 5) + { + transitionEnd = transitionStart + new Vector2(0, -0.5f) * 60 * (MapTransitionSystem.ChangeMapTime / 1000f); + } + else if (_mode == 6) + { + MapManager.ObjLink.NextMapFallRotateStart = true; + } + + if (_savePosition) + { + MapManager.ObjLink.SaveMap = Map.MapName; + MapManager.ObjLink.SavePosition = transitionEnd; + MapManager.ObjLink.SaveDirection = _direction; + + // save settings? + if (GameSettings.Autosave) + { + SaveGameSaveLoad.SaveGame(Game1.GameManager); + Game1.GameManager.InGameOverlay.InGameHud.ShowSaveIcon(); + } + } + + MapManager.ObjLink.NextMapPositionStart = transitionStart; + MapManager.ObjLink.NextMapPositionEnd = transitionEnd; + MapManager.ObjLink.TransitionInWalking = transitionStart != transitionEnd; + MapManager.ObjLink.DirectionEntry = _direction; + + // no transition (eg. fall into a 2d room) + if (_mode == 7) + { + MapManager.ObjLink.Fall2DEntry = true; + MapManager.ObjLink.NextMapPositionEnd = null; + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjDoor2d.cs b/InGame/GameObjects/Things/ObjDoor2d.cs new file mode 100644 index 0000000..44621c6 --- /dev/null +++ b/InGame/GameObjects/Things/ObjDoor2d.cs @@ -0,0 +1,97 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameSystems; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + public class ObjDoor2d : GameObject + { + private Rectangle _collisionRectangle; + private Vector2 _transitionPosition; + + private string _entryId; + private string _nextMap; + private string _exitId; + + private bool _isColliding; + private bool _wasColliding; + private bool _isTransitioning; + + public ObjDoor2d() : base("editor door") + { + EditorColor = Color.Orange * 0.65f; + } + + public ObjDoor2d(Map.Map map, int posX, int posY, int width, int height, string entryId, string nextMapId, string exitId) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, width, height); + + _transitionPosition = new Vector2(posX + 8, posY + 16); + _collisionRectangle = new Rectangle(posX + 6, posY, 4, height); + + _entryId = entryId; + + // has the player just entered this door? + if (_entryId != null && MapManager.ObjLink.NextMapPositionId == _entryId) + PlacePlayer(); + + _nextMap = nextMapId; + _exitId = exitId; + + if (!string.IsNullOrEmpty(_nextMap) && !string.IsNullOrEmpty(_exitId)) + { + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(ObjectCollisionComponent.Index, + new ObjectCollisionComponent(_collisionRectangle, OnCollision)); + } + } + + private void Update() + { + if (_isTransitioning) + return; + + _wasColliding = _isColliding; + _isColliding = false; + + // first step on the door? + if (MapManager.ObjLink.IsGrounded() && !MapManager.ObjLink.IsTransitioning && _wasColliding && ControlHandler.GetMoveVector2().Y < 0) + { + _isTransitioning = true; + + Game1.GameManager.PlaySoundEffect("D378-06-06"); + + MapManager.ObjLink.MapTransitionStart = MapManager.ObjLink.EntityPosition.Position; + MapManager.ObjLink.MapTransitionEnd = _transitionPosition; + MapManager.ObjLink.TransitionOutWalking = true; + MapManager.ObjLink.Direction = 1; + + // append a map change + var transitionSystem = (MapTransitionSystem)Game1.GameManager.GameSystems[typeof(MapTransitionSystem)]; + transitionSystem.AppendMapChange(_nextMap, _exitId, false, false, Values.MapTransitionColor, false); + } + } + + private void OnCollision(GameObject gameObject) + { + _isColliding = true; + } + + private void PlacePlayer() + { + _isColliding = true; + _wasColliding = true; + + MapManager.ObjLink.NextMapPositionStart = _transitionPosition; + MapManager.ObjLink.NextMapPositionEnd = _transitionPosition; + MapManager.ObjLink.TransitionInWalking = false; + MapManager.ObjLink.DirectionEntry = 3; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjDoorEgg.cs b/InGame/GameObjects/Things/ObjDoorEgg.cs new file mode 100644 index 0000000..9590153 --- /dev/null +++ b/InGame/GameObjects/Things/ObjDoorEgg.cs @@ -0,0 +1,193 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + public class ObjDoorEgg : GameObject + { + private readonly DictAtlasEntry _doorSprite; + private readonly Vector2[] _relicOffsets = new Vector2[8]; + private readonly string _saveKey; + + private bool[] _showInstrument = new bool[8]; + private float _instrumentCounter = -500; + private int _shownInstrument; + private int _playerInstrumentCount; + private int _songEnd; + private bool _shakeScreen; + private bool _isRunning; + private bool _linkOcarinaAnimation; + private bool _drawInstruments = true; + + public ObjDoorEgg() : base("egg_entry") { } + + public ObjDoorEgg(Map.Map map, int posX, int posY, string saveId) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _saveKey = saveId; + if (!string.IsNullOrEmpty(_saveKey) && + Game1.GameManager.SaveManager.GetString(_saveKey) == "1") + { + IsDead = true; + return; + } + + _doorSprite = Resources.GetSprite("egg_entry"); + + // -48 -16 16 48 + // -48 -16 16 48 + _relicOffsets[7] = new Vector2(-16, -40); + _relicOffsets[0] = new Vector2(16, -40); + _relicOffsets[6] = new Vector2(-40, -15); + _relicOffsets[1] = new Vector2(40, -15); + _relicOffsets[5] = new Vector2(-40, 16); + _relicOffsets[2] = new Vector2(40, 16); + _relicOffsets[4] = new Vector2(-16, 48); + _relicOffsets[3] = new Vector2(16, 48); + + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(new CBox(EntityPosition, -8, -16, 16, 16, 8), Values.CollisionTypes.Normal)); + AddComponent(OcarinaListenerComponent.Index, new OcarinaListenerComponent(OnSongPlayed)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBottom, EntityPosition)); + } + + private void OnSongPlayed(int songIndex) + { + if (songIndex != 0 || _isRunning) + return; + + _isRunning = true; + _linkOcarinaAnimation = false; + _instrumentCounter = 0; + _playerInstrumentCount = 0; + for (var i = 0; i < 8; i++) + { + var itemName = "instrument" + i; + var item = Game1.GameManager.GetItem(itemName); + if (item != null) + _playerInstrumentCount++; + } + + _songEnd = _playerInstrumentCount <= 2 ? 36000 : 41000; + + // freeze the animation until the song gets played + MapManager.ObjLink.FreezeAnimationState(); + + Game1.GameManager.StopMusic(); + } + + private void Update() + { + if (!_isRunning) + return; + + MapManager.ObjLink.FreezePlayer(); + + _instrumentCounter += Game1.DeltaTime; + + // instrument apearing sounds + if (_instrumentCounter > _shownInstrument * 500 && _shownInstrument < 8) + { + var itemName = "instrument" + _shownInstrument; + var item = Game1.GameManager.GetItem(itemName); + if (item != null) + Game1.GameManager.PlaySoundEffect("D378-43-2B"); + _showInstrument[_shownInstrument] = item != null; + _shownInstrument++; + } + + if (!_linkOcarinaAnimation && _instrumentCounter > 8 * 500) + { + _linkOcarinaAnimation = true; + MapManager.ObjLink.StartOcarinaDuo(); + // @TODO: can we only access this state with at least 2 instruments? + Game1.GameManager.SetMusic(62 + _playerInstrumentCount, 2); + } + + // shake the screen + if (!_shakeScreen && _instrumentCounter > _songEnd) + { + _drawInstruments = false; + + if (_playerInstrumentCount < 8) + { + _isRunning = false; + MapManager.ObjLink.StopOcarinaDuo(); + Game1.GameManager.SetMusic(-1, 2); + return; + } + + _shakeScreen = true; + + Game1.GameManager.ShakeScreen(2500, 1, 0, 5.5f, 0); + MapManager.ObjLink.FreezeAnimationState(); + } + + // spawn the stone particles and delete the object + if (_instrumentCounter > _songEnd + 2500) + { + _linkOcarinaAnimation = false; + MapManager.ObjLink.StopOcarinaDuo(); + + Map.Objects.SpawnObject(new ObjSmallStone(Map, (int)EntityPosition.X - 4, (int)EntityPosition.Y - 20, (int)EntityPosition.Z, new Vector3(-1.05f, 0.25f, 3), true, 650)); + Map.Objects.SpawnObject(new ObjSmallStone(Map, (int)EntityPosition.X - 4, (int)EntityPosition.Y - 16, (int)EntityPosition.Z, new Vector3(-1.25f, 0.75f, 3), true, 650)); + Map.Objects.SpawnObject(new ObjSmallStone(Map, (int)EntityPosition.X - 4, (int)EntityPosition.Y - 12, (int)EntityPosition.Z, new Vector3(-0.85f, 1.25f, 3), true, 650)); + + Map.Objects.SpawnObject(new ObjSmallStone(Map, (int)EntityPosition.X - 0, (int)EntityPosition.Y - 22, (int)EntityPosition.Z, new Vector3(-0.3f, 0.05f, 3), true, 650)); + Map.Objects.SpawnObject(new ObjSmallStone(Map, (int)EntityPosition.X - 0, (int)EntityPosition.Y - 12, (int)EntityPosition.Z, new Vector3(0.35f, 1.45f, 3), true, 650)); + + Map.Objects.SpawnObject(new ObjSmallStone(Map, (int)EntityPosition.X + 4, (int)EntityPosition.Y - 20, (int)EntityPosition.Z, new Vector3(1.0f, 0.25f, 3), true, 650)); + Map.Objects.SpawnObject(new ObjSmallStone(Map, (int)EntityPosition.X + 4, (int)EntityPosition.Y - 16, (int)EntityPosition.Z, new Vector3(1.25f, 0.75f, 3), true, 650)); + Map.Objects.SpawnObject(new ObjSmallStone(Map, (int)EntityPosition.X + 4, (int)EntityPosition.Y - 12, (int)EntityPosition.Z, new Vector3(0.9f, 1.25f, 3), true, 650)); + + if (!string.IsNullOrEmpty(_saveKey)) + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + Game1.GameManager.SaveManager.SetString("owl", "9_0"); + + Game1.GameManager.PlaySoundEffect("D360-35-23"); + Game1.GameManager.PlaySoundEffect("D378-12-0C"); + + Map.Objects.DeleteObjects.Add(this); + } + } + + private void Draw(SpriteBatch spriteBatch) + { + // draw the door + DrawHelper.DrawNormalized(spriteBatch, _doorSprite, EntityPosition.Position, Color.White); + + // draw the instruments + if (_drawInstruments) + for (int i = 0; i < 8; i++) + { + if (!_showInstrument[i]) + continue; + + var length = 8 * 250; + var counterMod = _instrumentCounter % length; + + // blink + if (_instrumentCounter < i * 500 || + (i * 250 < counterMod && counterMod < i * 250 + 200) || + (((length / 2.95f) + i * 250) % length < counterMod && counterMod < ((length / 2.95f) + i * 250 + 200) % length) || + (((length / 2.95f) * 2 + i * 250) % length < counterMod && counterMod < ((length / 2.95f) * 2 + i * 250 + 200) % length)) + continue; + + var itemName = "instrument" + i; + var itemInstrument = Game1.GameManager.ItemManager[itemName]; + var position = new Vector2(EntityPosition.X - 8, EntityPosition.Y - 8) + _relicOffsets[i]; + + ItemDrawHelper.DrawItem(spriteBatch, itemInstrument, position, Color.White, 1, true); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjDoorEnding.cs b/InGame/GameObjects/Things/ObjDoorEnding.cs new file mode 100644 index 0000000..16832a0 --- /dev/null +++ b/InGame/GameObjects/Things/ObjDoorEnding.cs @@ -0,0 +1,36 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameSystems; + +namespace ProjectZ.InGame.GameObjects.Things +{ + public class ObjDoorEnding : GameObject + { + private bool _collided; + + public ObjDoorEnding() : base("editor door") + { + EditorColor = Color.Purple * 0.65f; + } + + public ObjDoorEnding(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + var collisionRectangle = new Rectangle(posX, posY, 16, 16); + AddComponent(ObjectCollisionComponent.Index, new ObjectCollisionComponent(collisionRectangle, OnCollision)); + } + + private void OnCollision(GameObject gameObject) + { + if(_collided) + return; + _collided = true; + + ((EndingSystem)Game1.GameManager.GameSystems[typeof(EndingSystem)]).StartEnding(); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjEggTeleporter.cs b/InGame/GameObjects/Things/ObjEggTeleporter.cs new file mode 100644 index 0000000..6bea9ab --- /dev/null +++ b/InGame/GameObjects/Things/ObjEggTeleporter.cs @@ -0,0 +1,319 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; +using System; +using System.Collections.Generic; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjEggTeleporter : GameObject + { + private readonly List _bodyObjects = new List(); + + struct RoomState + { + public int Direction; + public float Light; + public float LightTarget; + public bool Lit; + } + + private RoomState[,] RoomStates = new RoomState[4, 5]; + private RoomState[,] tempRoomStates = new RoomState[4, 5]; + + private int roomX; + private int roomY; + private int lastRoomX = 1; + private int lastRoomY = 2; + + private float lightSpeed = 0.065f; + private float darknessSpeed = 0.08f; + private float tLit = 0; + private float tDark = 1; + private float tLightBleed = 0.845f; + + private int[] _movedPath = new int[7]; + private int _pathIndex; + + private int[] _targetPath = new int[7]; + + private bool _initLight; + private bool _foundPath; + + public ObjEggTeleporter() : base("editor egg teleport") + { + EditorColor = Color.Green * 0.5f; + } + + public ObjEggTeleporter(Map.Map map, int posX, int posY) : base(map) + { + for (var y = 0; y < RoomStates.GetLength(1); y++) + for (var x = 0; x < RoomStates.GetLength(0); x++) + { + RoomStates[x, y] = new RoomState(); + RoomStates[x, y].Light = tDark; + RoomStates[x, y].LightTarget = tDark; + } + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(LightDrawComponent.Index, new LightDrawComponent(DrawLight)); + + // 0: left; 1: up; 2: right + // load the directions that where set at the start of the game + var eggDirections = Game1.GameManager.SaveManager.GetString("eggDirections", "0"); + if (eggDirections == "0") + _targetPath = new int[] { 0, 0, 1, 2, 2, 1, 0 }; + else if (eggDirections == "1") + _targetPath = new int[] { 2, 1, 1, 2, 1, 1, 2 }; + else if (eggDirections == "2") + _targetPath = new int[] { 0, 1, 2, 1, 0, 1, 2 }; + else + _targetPath = new int[] { 2, 2, 2, 2, 1, 1, 1 }; + } + + private void Update() + { + if (!_initLight) + InitLight(); + + UpdateRoom(); + + var posX = MapManager.ObjLink.EntityPosition.X; + var posY = MapManager.ObjLink.EntityPosition.Y - 4; + roomX = (int)((posX + 80) / Values.FieldWidth); + roomY = (int)(posY / Values.FieldHeight); + + for (int y = 0; y < RoomStates.GetLength(1); y++) + { + for (int x = 0; x < RoomStates.GetLength(0); x++) + { + var center = new Vector2(-80 + (x + 0.5f) * Values.FieldWidth, (y + 0.5f) * Values.FieldHeight) - + new Vector2(MapManager.ObjLink.EntityPosition.X, MapManager.ObjLink.EntityPosition.Y - 4); + if (x == roomX && y == roomY || + Values.FieldWidth / 2 - 8 < Math.Abs(center.X) && Math.Abs(center.X) < Values.FieldWidth / 2 + 8 && Math.Abs(center.Y) < 16 || + Values.FieldHeight / 2 - 8 < Math.Abs(center.Y) && Math.Abs(center.Y) < Values.FieldHeight / 2 + 8 && Math.Abs(center.X) < 16) + { + if (!RoomStates[x, y].Lit) + { + RoomStates[x, y].Lit = true; + RoomStates[x, y].LightTarget = tLit; + RoomStates[x, y].Direction = AnimationHelper.GetDirection(-new Vector2(center.X, center.Y)); + } + } + else + { + if (RoomStates[x, y].Lit) + { + RoomStates[x, y].Lit = false; + RoomStates[x, y].LightTarget = tLightBleed; + RoomStates[x, y].Direction = AnimationHelper.GetDirection(-new Vector2(center.X, center.Y)); + } + } + + var tSpeed = RoomStates[x, y].Light < RoomStates[x, y].LightTarget ? darknessSpeed : lightSpeed; + var newLightValue = AnimationHelper.MoveToTarget(RoomStates[x, y].Light, RoomStates[x, y].LightTarget, tSpeed * Game1.TimeMultiplier); + + if (RoomStates[x, y].Lit) + { + // light up the side rooms + if (RoomStates[x, y].Direction % 2 == 0) + { + if (RoomStates[x, y].Light > 0.45f && newLightValue <= 0.45f) + { + SetRoomState(x, y - 1, tLightBleed, 3); + SetRoomState(x, y + 1, tLightBleed, 1); + } + if (RoomStates[x, y].Light > 0.125f && newLightValue <= 0.125f) + { + SetRoomState(x + (RoomStates[x, y].Direction == 0 ? 1 : -1), y, tLightBleed, RoomStates[x, y].Direction); + } + } + else if (RoomStates[x, y].Direction % 2 == 1) + { + if (RoomStates[x, y].Light > 0.385f && newLightValue <= 0.385f) + { + SetRoomState(x - 1, y, tLightBleed, 2); + SetRoomState(x + 1, y, tLightBleed, 0); + } + if (RoomStates[x, y].Light > 0.175f && newLightValue <= 0.175f) + { + SetRoomState(x, y + (RoomStates[x, y].Direction == 1 ? 1 : -1), tLightBleed, RoomStates[x, y].Direction); + } + } + } + else + { + // darken the side rooms + if (RoomStates[x, y].Direction % 2 == 0) + { + if (RoomStates[x, y].Light < 0.35f && newLightValue >= 0.35f) + { + SetRoomState(x, y - 1, tDark, 3); + SetRoomState(x, y + 1, tDark, 1); + } + if (RoomStates[x, y].Light <= 0.0f && newLightValue > 0.0f) + { + SetRoomState(x + (RoomStates[x, y].Direction == 0 ? 1 : -1), y, tDark, RoomStates[x, y].Direction); + } + } + else if (RoomStates[x, y].Direction % 2 == 1) + { + if (RoomStates[x, y].Light < 0.275f && newLightValue >= 0.275f) + { + SetRoomState(x - 1, y, tDark, 2); + SetRoomState(x + 1, y, tDark, 0); + } + if (RoomStates[x, y].Light < 0.1f && newLightValue >= 0.1f) + { + SetRoomState(x, y + (RoomStates[x, y].Direction == 1 ? 1 : -1), tDark, RoomStates[x, y].Direction); + } + } + } + } + } + + for (int y = 0; y < RoomStates.GetLength(1); y++) + { + for (int x = 0; x < RoomStates.GetLength(0); x++) + { + var tSpeed = RoomStates[x, y].Light < RoomStates[x, y].LightTarget ? darknessSpeed : lightSpeed; + var newLightValue = AnimationHelper.MoveToTarget(RoomStates[x, y].Light, RoomStates[x, y].LightTarget, tSpeed * Game1.TimeMultiplier); + RoomStates[x, y].Light = newLightValue; + } + } + + lastRoomX = roomX; + lastRoomY = roomY; + } + + private void InitLight() + { + _initLight = true; + + var posX = MapManager.ObjLink.EntityPosition.X; + var posY = MapManager.ObjLink.EntityPosition.Y - 4; + roomX = (int)((posX + 80) / Values.FieldWidth); + roomY = (int)(posY / Values.FieldHeight); + + SetRoomState(roomX, roomY, tLit, 0); + SetRoomState(roomX - 1, roomY, tLightBleed, 2); + SetRoomState(roomX + 1, roomY, tLightBleed, 0); + SetRoomState(roomX, roomY - 1, tLightBleed, 3); + SetRoomState(roomX, roomY + 1, tLightBleed, 1); + } + + private void SetRoomState(int xIndex, int yIndex, float light, int direction) + { + if (0 <= xIndex && xIndex < RoomStates.GetLength(0) && + 0 <= yIndex && yIndex < RoomStates.GetLength(1)) + { + RoomStates[xIndex, yIndex].LightTarget = light; + RoomStates[xIndex, yIndex].Direction = direction; + } + } + + private void UpdateRoom() + { + var posX = MapManager.ObjLink.EntityPosition.X; + var posY = MapManager.ObjLink.EntityPosition.Y - 4; + roomX = (int)((posX + 80) / Values.FieldWidth); + roomY = (int)(posY / Values.FieldHeight); + + if (roomX != lastRoomX || roomY != lastRoomY) + { + var direction = new Vector2(roomX, roomY) - new Vector2(lastRoomX, lastRoomY); + var dir = AnimationHelper.GetDirection(direction); + + _movedPath[_pathIndex] = dir; + + // check if the player found the correct path + _foundPath = true; + for (var i = 0; i < _movedPath.Length; i++) + if (_movedPath[(_pathIndex + i + 1) % 7] != _targetPath[i]) + { + _foundPath = false; + break; + } + + _pathIndex = (_pathIndex + 1) % 7; + } + + // offset the player to not move outside + var dist = 16; + // found the path? + if (_foundPath && posY < roomY * Values.FieldHeight + dist && (roomX == 1 || roomX == 2) && roomY == 2) + OffsetPlayer(roomX == 1 ? 0 : -1, -1); + else if (posX < 80 + dist && roomX == 1 && (roomY == 1 || roomY == 2)) + OffsetPlayer(1, 0); + else if (posX > 80 + Values.FieldWidth * 2 - dist && roomX == 2 && (roomY == 1 || roomY == 2)) + OffsetPlayer(-1, 0); + else if (posY > (roomY + 1) * Values.FieldHeight - dist && roomX == 2 && (roomY == 2)) + OffsetPlayer(-1, 0); + // make sure that the room at the bottom is always the exit room + else if (!_foundPath && (roomX == 1 || roomX == 2) && roomY == 1 && + !RoomStates[roomX, roomY - 1].Lit && RoomStates[roomX, roomY - 1].Light == RoomStates[roomX, roomY - 1].LightTarget && + !RoomStates[roomX, roomY + 1].Lit && RoomStates[roomX, roomY + 1].Light == RoomStates[roomX, roomY + 1].LightTarget) + OffsetPlayer(roomX == 2 ? -1 : 0, 1); + } + + private void OffsetPlayer(int offsetX, int offsetY) + { + // offset the ligth map data with the player + for (int y = 0; y < RoomStates.GetLength(1); y++) + for (int x = 0; x < RoomStates.GetLength(0); x++) + tempRoomStates[x, y] = RoomStates[x, y]; + for (int y = 0; y < RoomStates.GetLength(1); y++) + for (int x = 0; x < RoomStates.GetLength(0); x++) + RoomStates[ + (x + offsetX + RoomStates.GetLength(0)) % RoomStates.GetLength(0), + (y + offsetY + RoomStates.GetLength(1)) % RoomStates.GetLength(1)] = tempRoomStates[x, y]; + + var offset = new Vector2(offsetX * Values.FieldWidth, offsetY * Values.FieldHeight); + MapManager.ObjLink.EntityPosition.Set( + new Vector2(MapManager.ObjLink.EntityPosition.X, MapManager.ObjLink.EntityPosition.Y) + offset); + + var goalPosition = Game1.GameManager.MapManager.GetCameraTarget(); + MapManager.Camera.SoftUpdate(goalPosition); + + // offset bodies + _bodyObjects.Clear(); + Map.Objects.GetComponentList(_bodyObjects, + (int)MapManager.ObjLink.EntityPosition.X - 200, (int)MapManager.ObjLink.EntityPosition.Y - 200, 400, 400, BodyComponent.Mask); + + foreach (var gameObject in _bodyObjects) + if (!(gameObject is ObjLink)) + gameObject.EntityPosition.Offset(offset); + } + + private void DrawLight(SpriteBatch spriteBatch) + { + spriteBatch.End(); + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, null, null, Resources.LightFadeShader, MapManager.Camera.TransformMatrix); + + for (int y = 0; y < RoomStates.GetLength(1); y++) + { + for (int x = 0; x < RoomStates.GetLength(0); x++) + { + var lightValue = RoomStates[x, y].Light; + if (RoomStates[x, y].Direction == 0) + spriteBatch.Draw(Resources.SprLightRoomH, new Vector2(-80 + x * Values.FieldWidth, 0 + y * Values.FieldHeight), Color.Black * lightValue); + else if (RoomStates[x, y].Direction == 2) + spriteBatch.Draw(Resources.SprLightRoomH, new Vector2(-80 + x * Values.FieldWidth, 0 + y * Values.FieldHeight), + new Rectangle(0, 0, Resources.SprLightRoomH.Width, Resources.SprLightRoomH.Height), Color.Black * lightValue, 0, Vector2.Zero, 1, SpriteEffects.FlipHorizontally, 0); + else if (RoomStates[x, y].Direction == 1) + spriteBatch.Draw(Resources.SprLightRoomV, new Vector2(-80 + x * Values.FieldWidth, 0 + y * Values.FieldHeight), + new Rectangle(0, 0, Resources.SprLightRoomH.Width, Resources.SprLightRoomH.Height), Color.Black * lightValue, 0, Vector2.Zero, 1, SpriteEffects.FlipVertically, 0); + else + spriteBatch.Draw(Resources.SprLightRoomV, new Vector2(-80 + x * Values.FieldWidth, 0 + y * Values.FieldHeight), Color.Black * lightValue); + } + } + + spriteBatch.End(); + spriteBatch.Begin(SpriteSortMode.Deferred, MapManager.LightBlendState, + MapManager.Camera.Scale >= 1 ? SamplerState.PointWrap : SamplerState.AnisotropicWrap, null, null, null, MapManager.Camera.TransformMatrix); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjEnemyRespawner.cs b/InGame/GameObjects/Things/ObjEnemyRespawner.cs new file mode 100644 index 0000000..b5b1f4c --- /dev/null +++ b/InGame/GameObjects/Things/ObjEnemyRespawner.cs @@ -0,0 +1,75 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjEnemyRespawner : GameObject + { + private GameObject _gameObject; + + private readonly string _strSpawnObjectId; + private readonly object[] _objParameter; + + private int _lastFieldTime; + + public ObjEnemyRespawner() : base("editor object respawner") { } + + public ObjEnemyRespawner(Map.Map map, int posX, int posY, string strSpawnObjectId, string strSpawnParameter) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + string[] parameter = null; + if (strSpawnParameter != null) + { + parameter = strSpawnParameter.Split('.'); + // @HACK: some objects have stings with dots in them... + for (var i = 0; i < parameter.Length; i++) + parameter[i] = parameter[i].Replace("$", "."); + } + + _strSpawnObjectId = strSpawnObjectId; + _objParameter = MapData.GetParameter(strSpawnObjectId, parameter); + if (_objParameter != null) + { + _objParameter[1] = posX; + _objParameter[2] = posY; + } + + _lastFieldTime = Map.GetUpdateState(EntityPosition.Position); + + // add key change listener + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + + SpawnObject(); + } + + private void Update() + { + // field went out of the update range? + var updateState = Map.GetUpdateState(EntityPosition.Position); + + // gameobject was removed from the map? + if (_gameObject == null || _gameObject.Map != null || _lastFieldTime >= updateState) + { + _lastFieldTime = updateState; + return; + } + + SpawnObject(); + + } + + private void SpawnObject() + { + _gameObject = ObjectManager.GetGameObject(Map, _strSpawnObjectId, _objParameter); + + if (_gameObject != null) + Map.Objects.SpawnObject(_gameObject); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjEnemyTrigger.cs b/InGame/GameObjects/Things/ObjEnemyTrigger.cs new file mode 100644 index 0000000..4cd5320 --- /dev/null +++ b/InGame/GameObjects/Things/ObjEnemyTrigger.cs @@ -0,0 +1,61 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjEnemyTrigger : GameObject + { + private readonly List _enemyList = new List(); + private readonly Rectangle _triggerField; + private readonly string _triggerKey; + + private bool _enemiesAlive; + private bool _init; + + public ObjEnemyTrigger() : base("editor enemy trigger") { } + + public ObjEnemyTrigger(Map.Map map, int posX, int posY, string triggerKey) : base(map) + { + if (string.IsNullOrEmpty(triggerKey)) + { + IsDead = true; + return; + } + + _triggerKey = triggerKey; + _triggerField = map.GetField(posX, posY); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + private void Update() + { + // this gets called the first time update is run so it can capture enemies spawned by an ObjObjectSpawner + if (!_init) + { + _init = true; + // get the enemies the object should watch over + Map.Objects.GetGameObjectsWithTag(_enemyList, Values.GameObjectTag.Enemy, + _triggerField.X, _triggerField.Y, _triggerField.Width, _triggerField.Height); + } + + _enemiesAlive = false; + // check if the enemies where deleted from the map + foreach (var gameObject in _enemyList) + if (gameObject.Map != null) + _enemiesAlive = true; + + if (_enemiesAlive) + return; + + Game1.GameManager.SaveManager.SetString(_triggerKey, "1"); + + //RemoveComponent(UpdateComponent.Index); + // remove the object + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjFence.cs b/InGame/GameObjects/Things/ObjFence.cs new file mode 100644 index 0000000..dd1d23b --- /dev/null +++ b/InGame/GameObjects/Things/ObjFence.cs @@ -0,0 +1,53 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + public class ObjFence : GameObject + { + private DictAtlasEntry _sprite; + + private readonly List _positionList = new List(); + + // could be replaced with a ObjSprite + public ObjFence(Map.Map map, int posX, int posY, int placement) : base(map) + { + _sprite = Resources.GetSprite("fence"); + EditorIconSource = new Rectangle(0, 0, 16, 16); + + for (var i = 0; i < 4; i++) + { + if ((placement & 0x08) > 1) + { + var fX = posX + 4 + (i % 2) * 8; + var fY = posY + 5 + (i / 2) * 8; + + var position = new CPosition(fX, fY, 0); + _positionList.Add(position); + + var fencePart = new ObjSprite(Map, (int)position.X, (int)position.Y, + "fence", Vector2.Zero, Values.LayerPlayer, "fence_shadow", new Rectangle(-3, -5, 6, 6), Values.CollisionTypes.Normal); + + map.Objects.SpawnObject(fencePart); + } + + placement <<= 1; + } + + IsDead = true; + } + + public override void DrawEditor(SpriteBatch spriteBatch, Vector2 drawPosition) + { + foreach (var position in _positionList) + spriteBatch.Draw(_sprite.Texture, new Vector2( + position.X + drawPosition.X - _sprite.Origin.X, + position.Y + drawPosition.Y - _sprite.Origin.Y), _sprite.ScaledRectangle, Color.White, 0, Vector2.Zero, _sprite.Scale, SpriteEffects.None, 0); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjFinalBackground.cs b/InGame/GameObjects/Things/ObjFinalBackground.cs new file mode 100644 index 0000000..9a0ed2f --- /dev/null +++ b/InGame/GameObjects/Things/ObjFinalBackground.cs @@ -0,0 +1,310 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using System.Collections.Generic; + +namespace ProjectZ.InGame.GameObjects.Things +{ + public class ObjFinalBackground : GameObject + { + struct CloudPart + { + public Vector2 position; + public Vector4 color0; + public Vector4 color1; + public float offset; + } + + struct StarAnimation + { + public Vector2 position; + public Animator animator; + public Color color; + } + + private List _clouds = new List(); + private List _stars = new List(); + + private DictAtlasEntry _cloudSprite; + private CPosition _spawnPosition; + + private string _moveStarKeys; + private float _moveHeight; + private float _positionTop; + private float _movePosition; + private bool _moveStars; + + public ObjFinalBackground() : base("final_cloud") { } + + public ObjFinalBackground(Map.Map map, int posX, int posY, string moveStarsKey) : base(map) + { + _spawnPosition = new CPosition(posX, posY, 0); + _moveStarKeys = moveStarsKey; + + _cloudSprite = Resources.GetSprite("final_cloud"); + + var colorRed0 = new Vector4(0.518f, 0.192f, 0.353f, 1.0f); + var colorRed1 = new Vector4(0.835f, 0.196f, 0.541f, 1.0f); + var colorBlue0 = new Vector4(0.290f, 0.255f, 0.996f, 1.0f); + var colorBlue1 = new Vector4(0.510f, 0.388f, 0.898f, 1.0f); + var colorBlue2 = new Vector4(0.259f, 0.741f, 0.776f, 1.0f); + var colorBlue3 = new Vector4(0.259f, 0.482f, 0.518f, 1.0f); + var colorWhite = new Vector4(0.969f, 0.990f, 0.910f, 1.0f); + var colorGreen = new Vector4(0.188f, 0.769f, 0.353f, 1.0f); + var colorYellow = new Vector4(0.975f, 0.675f, 0.031f, 1.0f); + var colorLila0 = new Vector4(0.518f, 0.388f, 0.906f, 1.0f); + var colorLila1 = new Vector4(0.710f, 0.322f, 0.808f, 1.0f); + + { + var cloudX = posX - 80; + var cloudY = posY + 56; + var offset0 = 0.8f; + var offset1 = 0.75f; + + _clouds.Add(new CloudPart() { position = new Vector2(cloudX, cloudY + 8), color0 = colorRed0, color1 = colorRed1, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 8, cloudY), color0 = colorRed0, color1 = colorRed1, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 16, cloudY + 8), color0 = colorRed0, color1 = colorRed1, offset = offset0 }); + } + + { + var cloudX = posX + 80; + var cloudY = posY - 32; + var offset0 = 0.8f; + var offset1 = 0.75f; + + _clouds.Add(new CloudPart() { position = new Vector2(cloudX, cloudY + 8), color0 = colorGreen, color1 = colorWhite, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 8, cloudY), color0 = colorGreen, color1 = colorWhite, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 16, cloudY + 8), color0 = colorGreen, color1 = colorWhite, offset = offset0 }); + } + + { + var cloudX = posX + 88; + var cloudY = posY + 40; + var offset0 = 0.8f; + var offset1 = 0.75f; + + _clouds.Add(new CloudPart() { position = new Vector2(cloudX, cloudY + 8), color0 = colorLila0, color1 = colorWhite, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 8, cloudY), color0 = colorLila0, color1 = colorWhite, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 16, cloudY + 8), color0 = colorLila0, color1 = colorWhite, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 24, cloudY), color0 = colorLila0, color1 = colorWhite, offset = offset0 }); + } + + { + var cloudX = posX - 40; + var cloudY = posY - 0; + var offset0 = 0.8f; + var offset1 = 0.75f; + + _clouds.Add(new CloudPart() { position = new Vector2(cloudX, cloudY + 16), color0 = colorRed0, color1 = colorRed1, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 8, cloudY + 8), color0 = colorRed0, color1 = colorRed1, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 16, cloudY + 16), color0 = colorRed0, color1 = colorRed1, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 16, cloudY + 8), color0 = colorRed0, color1 = colorRed1, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 16, cloudY), color0 = colorRed0, color1 = colorRed1, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 24, cloudY + 8), color0 = colorRed0, color1 = colorRed1, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 32, cloudY), color0 = colorRed0, color1 = colorRed1, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 40, cloudY + 8), color0 = colorRed0, color1 = colorRed1, offset = offset1 }); + } + + { + var cloudX = posX + 32; + var cloudY = posY; + var offset0 = 1; + var offset1 = 0.925f; + + _clouds.Add(new CloudPart() { position = new Vector2(cloudX, cloudY + 16), color0 = colorGreen, color1 = colorWhite, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 8, cloudY + 8), color0 = colorGreen, color1 = colorWhite, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 16, cloudY + 16), color0 = colorGreen, color1 = colorWhite, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 24, cloudY + 8), color0 = colorBlue2, color1 = colorBlue3, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 24, cloudY + 16), color0 = colorBlue2, color1 = colorBlue3, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 32, cloudY + 16), color0 = colorBlue2, color1 = colorBlue3, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 24, cloudY + 24), color0 = colorBlue2, color1 = colorBlue3, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 40, cloudY + 8), color0 = colorBlue2, color1 = colorWhite, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 48, cloudY + 8), color0 = colorBlue2, color1 = colorWhite, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 56, cloudY + 16), color0 = colorBlue2, color1 = colorWhite, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 32, cloudY), color0 = colorBlue2, color1 = colorBlue3, offset = offset1 }); + } + + { + var cloudX = posX - 32; + var cloudY = posY + 32; + var offset0 = 0.65f; + var offset1 = 0.7f; + + _clouds.Add(new CloudPart() { position = new Vector2(cloudX, cloudY + 16), color0 = colorBlue2, color1 = colorBlue3, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 8, cloudY + 8), color0 = colorBlue2, color1 = colorBlue3, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 16, cloudY + 16), color0 = colorBlue2, color1 = colorBlue3, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 16, cloudY), color0 = colorBlue2, color1 = colorBlue3, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 24, cloudY + 8), color0 = colorWhite, color1 = colorYellow, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 32, cloudY), color0 = colorWhite, color1 = colorYellow, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 40, cloudY + 8), color0 = colorWhite, color1 = colorYellow, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 16, cloudY + 32), color0 = colorGreen, color1 = colorWhite, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 24, cloudY + 24), color0 = colorGreen, color1 = colorWhite, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 32, cloudY + 32), color0 = colorGreen, color1 = colorWhite, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 32, cloudY + 16), color0 = colorGreen, color1 = colorWhite, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 40, cloudY + 24), color0 = colorWhite, color1 = colorYellow, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 48, cloudY + 16), color0 = colorWhite, color1 = colorYellow, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 56, cloudY + 24), color0 = colorWhite, color1 = colorYellow, offset = offset1 }); + } + + { + var cloudX = posX - 136; + var cloudY = posY + 8; + var offset = 0.9f; + var offset1 = 0.925f; + + _clouds.Add(new CloudPart() { position = new Vector2(cloudX, cloudY + 16), color0 = colorBlue2, color1 = colorBlue3, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 8, cloudY + 8), color0 = colorBlue2, color1 = colorBlue3, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 16, cloudY + 16), color0 = colorBlue2, color1 = colorBlue3, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 16, cloudY), color0 = colorBlue2, color1 = colorBlue3, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 24, cloudY + 8), color0 = colorWhite, color1 = colorLila0, offset = offset }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 40, cloudY + 8), color0 = colorWhite, color1 = colorLila0, offset = offset }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 32, cloudY + 16), color0 = colorBlue2, color1 = colorWhite, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 40, cloudY + 24), color0 = colorBlue2, color1 = colorWhite, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 48, cloudY + 16), color0 = colorBlue2, color1 = colorWhite, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 56, cloudY + 24), color0 = colorBlue2, color1 = colorWhite, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 24, cloudY + 24), color0 = colorWhite, color1 = colorLila1, offset = offset }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 32, cloudY + 32), color0 = colorWhite, color1 = colorLila1, offset = offset }); + } + + { + var cloudX = posX + 16; + var cloudY = posY - 24; + var offset0 = 0.85f; + var offset1 = 0.825f; + var offset2 = 0.8f; + + _clouds.Add(new CloudPart() { position = new Vector2(cloudX, cloudY), color0 = colorRed0, color1 = colorRed1, offset = offset2 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 16, cloudY), color0 = colorGreen, color1 = colorWhite, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 16, cloudY - 16), color0 = colorBlue0, color1 = colorBlue1, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 24, cloudY - 8), color0 = colorGreen, color1 = colorWhite, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 8, cloudY - 8), color0 = colorRed0, color1 = colorRed1, offset = offset2 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 32, cloudY), color0 = colorBlue2, color1 = colorBlue3, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 32, cloudY - 16), color0 = colorBlue2, color1 = colorBlue3, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 40, cloudY - 8), color0 = colorBlue2, color1 = colorBlue3, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 48, cloudY - 16), color0 = colorBlue2, color1 = colorBlue3, offset = offset1 }); + } + + { + var cloudX = posX - 88; + var cloudY = posY - 24; + var offset0 = 0.85f; + var offset1 = 0.8f; + + _clouds.Add(new CloudPart() { position = new Vector2(cloudX, cloudY), color0 = colorBlue0, color1 = colorBlue1, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 8, cloudY - 8), color0 = colorBlue0, color1 = colorBlue1, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 8, cloudY + 24), color0 = colorBlue0, color1 = colorBlue1, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 32, cloudY), color0 = colorRed0, color1 = colorRed1, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 16, cloudY + 16), color0 = colorBlue0, color1 = colorBlue1, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 24, cloudY - 8), color0 = colorRed0, color1 = colorRed1, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 40, cloudY), color0 = colorYellow, color1 = colorWhite, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 24, cloudY + 8), color0 = colorRed0, color1 = colorRed1, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 24, cloudY + 24), color0 = colorRed0, color1 = colorRed1, offset = offset1 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 16, cloudY), color0 = colorBlue0, color1 = colorBlue1, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 32, cloudY + 16), color0 = colorGreen, color1 = colorWhite, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 36, cloudY + 8), color0 = colorGreen, color1 = colorWhite, offset = offset0 }); + _clouds.Add(new CloudPart() { position = new Vector2(cloudX + 40, cloudY + 16), color0 = colorYellow, color1 = colorWhite, offset = offset0 }); + } + + var randomDist = 16; + var halfOffset = 24; + _moveHeight = halfOffset * 2 * 20; + _positionTop = posY - halfOffset * 2 * 10; + + for (int x = 0; x < 20; x++) + { + for (int y = 0; y < 20; y++) + { + if (Game1.RandomNumber.Next(0, 6) == 0) + continue; + + var position = new Vector2(posX + (x - 10) * halfOffset * 2 + (y % 2) * halfOffset, posY + (y - 10) * halfOffset * 2); + + _stars.Add(new StarAnimation() + { + position = position + new Vector2( + Game1.RandomNumber.Next(0, randomDist * 2) - randomDist, + Game1.RandomNumber.Next(0, randomDist * 2) - randomDist), + animator = AnimatorSaveLoad.LoadAnimator("Sequences/final star"), + color = Color.White * (Game1.RandomNumber.Next(50, 75) / 100f) + }); + } + } + + foreach (var star in _stars) + { + star.animator.Play("idle"); + star.animator.SetFrame(Game1.RandomNumber.Next(0, 4)); + } + + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBackground, new CPosition(posX, posY - 512, 0))); + } + + private void OnKeyChange() + { + if (!_moveStars && Game1.GameManager.SaveManager.GetString(_moveStarKeys) == "1") + _moveStars = true; + } + + private void Update() + { + foreach (var star in _stars) + { + star.animator.Update(); + } + + if (_moveStars) + { + _movePosition += Game1.TimeMultiplier * 8; + } + } + + private void Draw(SpriteBatch spriteBatch) + { + // we offset the background objects in relation to the camera so that the move slower than the actuall objects + // draw the start + var starOffset = -(_spawnPosition.Position - (new Vector2(MapManager.Camera.X, MapManager.Camera.Y) / MapManager.Camera.Scale)) * new Vector2(1.0f, 0.75f); + foreach (var star in _stars) + { + var offsetPosition = star.position; + offsetPosition.Y += _movePosition; + offsetPosition.Y = (offsetPosition.Y - _positionTop) % _moveHeight + _positionTop; + star.animator.Draw(spriteBatch, offsetPosition + starOffset, star.color); + } + + // draw the clouds + // this is all way too complicated but I dont know how this can be done simpler + // looking right on resize makes hard + // not so sure how the position value in the shader works + var shaderOffset = (new Vector2(MapManager.Camera.Location.X + 4000, MapManager.Camera.Location.Y) * 0.85f - new Vector2(Game1.RenderWidth, Game1.RenderHeight) / 2); + Resources.CloudShader.Effect.Parameters["offset"].SetValue(shaderOffset); + Resources.CloudShader.FloatParameter["scale"] = MapManager.Camera.Scale; + Resources.CloudShader.FloatParameter["scaleX"] = MapManager.Camera.Scale; + Resources.CloudShader.FloatParameter["scaleY"] = MapManager.Camera.Scale; + + foreach (var cloud in _clouds) + { + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, Resources.CloudShader); + Resources.CloudShader.Effect.Parameters["color0"].SetValue(cloud.color0); + Resources.CloudShader.Effect.Parameters["color1"].SetValue(cloud.color1); + + var offset = -(_spawnPosition.Position - (new Vector2(MapManager.Camera.X, MapManager.Camera.Y) / MapManager.Camera.Scale)) * new Vector2(1.0f, 0.35f) * cloud.offset; + var position = cloud.position + offset; + position.Y += _movePosition; + var cameraView = MapManager.Camera.GetGameView(); + if (position.Y < cameraView.Bottom) + DrawHelper.DrawNormalized(spriteBatch, _cloudSprite, position, Color.White); + + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, null); + } + } + } +} diff --git a/InGame/GameObjects/Things/ObjFinalBackgroundStairs.cs b/InGame/GameObjects/Things/ObjFinalBackgroundStairs.cs new file mode 100644 index 0000000..28715ad --- /dev/null +++ b/InGame/GameObjects/Things/ObjFinalBackgroundStairs.cs @@ -0,0 +1,54 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + public class ObjFinalBackgroundStairs : GameObject + { + private readonly string _despawnKey; + + private const int DespawnTime = 500; + private double _despawnCounter; + private bool _despawning; + + public ObjFinalBackgroundStairs() : base("editor_final_platform") { } + + public ObjFinalBackgroundStairs(Map.Map map, int posX, int posY, string despawnKey) : base(map) + { + _despawnKey = despawnKey; + + var sprite = new CSprite("final_background_stairs", new CPosition(posX, posY + 1, 0), new Vector2(0, -1)) { SpriteShader = Resources.ThanosSpriteShader0 }; + Resources.ThanosSpriteShader0.FloatParameter["Percentage"] = 0; + + if (!string.IsNullOrEmpty(_despawnKey)) + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerBackground)); + } + + private void OnKeyChange() + { + if (!_despawning && Game1.GameManager.SaveManager.GetString(_despawnKey) == "1") + _despawning = true; + } + + private void Update() + { + if (!_despawning) + return; + + _despawnCounter += Game1.DeltaTime; + if (_despawnCounter > DespawnTime) + { + Map.Objects.DeleteObjects.Add(this); + return; + } + + var percentage = (float)_despawnCounter / DespawnTime; + Resources.ThanosSpriteShader0.FloatParameter["Percentage"] = percentage; + } + } +} diff --git a/InGame/GameObjects/Things/ObjFinalFountain.cs b/InGame/GameObjects/Things/ObjFinalFountain.cs new file mode 100644 index 0000000..9512abe --- /dev/null +++ b/InGame/GameObjects/Things/ObjFinalFountain.cs @@ -0,0 +1,141 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjFinalFountain : GameObject + { + private readonly Animator _animatorTop; + private readonly Animator _animatorBottom; + + private Vector2 _position; + private Vector2 _startPosition; + private Vector2 _targetPosition; + + private string _activationKey; + private bool _isActive; + + private const int WobbleTime = 2500; + private double _counter; + + private bool _moving; + private bool _despawnStairs; + + public ObjFinalFountain() : base("final_fountain") { } + + public ObjFinalFountain(Map.Map map, int posX, int posY, string activationKey) : base(map) + { + _activationKey = activationKey; + + _animatorTop = AnimatorSaveLoad.LoadAnimator("Sequences/final fountain"); + _animatorTop.Play("top"); + _animatorBottom = AnimatorSaveLoad.LoadAnimator("Sequences/final fountain"); + _animatorBottom.Play("bottom"); + + _startPosition = new Vector2(posX + 8, posY + 128); + _targetPosition = new Vector2(posX + 8, posY + 8); + _position = _startPosition; + + if (!string.IsNullOrEmpty(_activationKey)) + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBackground, new CPosition(0, 0, 0))); + } + + private void OnKeyChange() + { + if (!_isActive && Game1.GameManager.SaveManager.GetString(_activationKey) == "1") + Activate(); + } + + private void Activate() + { + _isActive = true; + Game1.GameManager.PlaySoundEffect("D378-52-34"); + Game1.GameManager.ShakeScreen(WobbleTime, 1, 0, 6, 0); + Map.CameraTarget = new Vector2(MapManager.ObjLink.PosX, MapManager.ObjLink.PosY); + } + + private void Update() + { + if (!_isActive) + return; + + _counter += Game1.DeltaTime; + if (_counter > WobbleTime) + { + if (!_despawnStairs && _counter - WobbleTime > 150) + { + _despawnStairs = true; + Game1.GameManager.SaveManager.SetString("despawn_stairs", "1"); + } + + // move up to the player + if (_counter - WobbleTime < 250) + { + var percentage = Math.Clamp(((float)_counter - WobbleTime) / 250, 0, 1); + _position = Vector2.Lerp(_startPosition, _targetPosition, percentage); + } + // go up and down a little bit + else if (_counter - WobbleTime < 5000 - 250) + { + var percentage = (float)((_counter - WobbleTime - 250) / 2000) * MathF.PI * 2; + _position = new Vector2(_targetPosition.X, _targetPosition.Y - MathF.Sin(percentage) * 3); + } + // leave the screen + else + { + _position.Y -= Game1.TimeMultiplier * MathHelper.Clamp((float)(_counter - WobbleTime - 250 - 4000) / 150, 0.125f, 16f); + } + + if (_counter - WobbleTime - 5000 - 250 > 1500) + { + Game1.GameManager.InGameOverlay.StartSequence("final"); + } + + // move the player ontop of the fountain + if (_moving || _position.Y < MapManager.ObjLink.PosY + 36) + { + MapManager.ObjLink.SetPosition(new Vector2(_position.X, _position.Y - 36)); + + if (!_moving) + { + _moving = true; + Game1.GameManager.SaveManager.SetString("final_move_background", "1"); + Game1.GameManager.SaveManager.SetString("link_animation", "fountain"); + } + } + } + + _animatorTop.Update(); + _animatorBottom.Update(); + } + + private void Draw(SpriteBatch spriteBatch) + { + if (!_isActive) + return; + + var fadePercentage = MathHelper.Clamp((float)(_counter - WobbleTime) / 100, 0, 1); + + _animatorTop.Draw(spriteBatch, _position, Color.White * fadePercentage); + + // draw the bottom part up to the screen end + var cameraView = MapManager.Camera.GetGameView(); + var top = Math.Max(_position.Y, cameraView.Top); + var bottomCount = (int)Math.Ceiling((cameraView.Bottom - top) / 16); + for (var i = 0; i < bottomCount; i++) + { + var pos = new Vector2(_position.X, top + (bottomCount - i - 1) * 16); + _animatorBottom.Draw(spriteBatch, pos, Color.White * fadePercentage); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjFinalStairs.cs b/InGame/GameObjects/Things/ObjFinalStairs.cs new file mode 100644 index 0000000..68d0a1c --- /dev/null +++ b/InGame/GameObjects/Things/ObjFinalStairs.cs @@ -0,0 +1,77 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjFinalStairs : GameObject + { + private DrawSpriteComponent _drawComponent; + private CBox _collisionBox; + + private const string spriteId = "final_stairs"; + private string _spawnKey; + private bool _collided; + private bool _spawned; + + private float _spawnTime = 8 / 60f * 1000; + private float _spawnCounter; + private int _spawnIndex; + + public ObjFinalStairs() : base(spriteId) { } + + public ObjFinalStairs(Map.Map map, int posX, int posY, string spawnKey) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + _spawnKey = spawnKey; + _collisionBox = new CBox(posX + 7, posY + 5, 0, 2, 2, 2); + + if (!string.IsNullOrEmpty(_spawnKey)) + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, _drawComponent = new DrawSpriteComponent(spriteId, EntityPosition, Values.LayerBottom) { IsActive = false }); + } + + private void OnKeyChange() + { + if (!_spawned && Game1.GameManager.SaveManager.GetString(_spawnKey) == "1") + { + _spawned = true; + _drawComponent.IsActive = true; + Game1.GameManager.PlaySoundEffect("D360-47-2F"); + } + } + + private void Update() + { + if (!_spawned) + return; + + if (_collided && _spawnIndex < 2) + { + _spawnCounter += Game1.DeltaTime; + if(_spawnCounter > _spawnTime) + { + _spawnCounter -= _spawnTime; + _spawnIndex++; + + var objSprite = new ObjSprite(Map, (int)EntityPosition.X, (int)EntityPosition.Y - _spawnIndex * 16, spriteId, Vector2.Zero, Values.LayerBottom, null); + Map.Objects.SpawnObject(objSprite); + } + } + + // collision with the player? + if (!_collided && MapManager.ObjLink._body.BodyBox.Box.Contains(_collisionBox.Box)) + { + _collided = true; + Game1.GameManager.StartDialogPath("final_stairs"); + MapManager.ObjLink.SetPosition(new Vector2(EntityPosition.X + 8, EntityPosition.Y + 12)); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjFloor.cs b/InGame/GameObjects/Things/ObjFloor.cs new file mode 100644 index 0000000..4c4486a --- /dev/null +++ b/InGame/GameObjects/Things/ObjFloor.cs @@ -0,0 +1,25 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjFloor : GameObject + { + public ObjFloor() : base("editor floor") + { + EditorColor = Color.YellowGreen * 0.65f; + } + + public ObjFloor(Map.Map map, int posX, int posY, int depth) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + AddComponent(CollisionComponent.Index, + new BoxCollisionComponent(new CBox(posX, posY, -10 + depth, 16, 16, 10), Values.CollisionTypes.Normal)); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjFog.cs b/InGame/GameObjects/Things/ObjFog.cs new file mode 100644 index 0000000..b2b0ce6 --- /dev/null +++ b/InGame/GameObjects/Things/ObjFog.cs @@ -0,0 +1,60 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjFog : GameObject + { + private Vector2 _offset0; + private Vector2 _offset1; + + private readonly Vector2 _position; + + private readonly float _scale; + private readonly float _transparency; + + private readonly int _timeOffset; + + public ObjFog(Map.Map map, int posX, int posY, float scale, float transparency) : base(map) + { + SprEditorImage = Resources.SprItem; + EditorIconSource = new Rectangle(64, 168, 16, 16); + + var height = (int)(Resources.SprFog.Height * scale); + EntityPosition = new CPosition(posX, posY + height, 0); + EntitySize = new Rectangle(0, -height, (int)(Resources.SprFog.Width * scale), height); + + _position = new Vector2(posX, posY); + + _scale = scale; + _transparency = transparency; + + _timeOffset = Game1.RandomNumber.Next(0, 5000); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerTop, EntityPosition)); + } + + private void Update() + { + _offset0 = new Vector2(MathF.Sin((float)((Game1.TotalGameTime + _timeOffset) / 2000)) * 16, MathF.Sin((float)((Game1.TotalGameTime + _timeOffset) / 6000)) * 2); + _offset1 = new Vector2(MathF.Sin((float)((Game1.TotalGameTime + _timeOffset) / 3250)) * 16, MathF.Sin((float)((Game1.TotalGameTime + _timeOffset) / 7500)) * 2); + } + + private void Draw(SpriteBatch spriteBatch) + { + // the fog would break the shock effect + if (Game1.GameManager.UseShockEffect) + return; + + var sourceRectangle = new Rectangle(0, 0, Resources.SprFog.Width, Resources.SprFog.Height); + spriteBatch.Draw(Resources.SprFog, _position + _offset0, sourceRectangle, Color.White * _transparency, 0, Vector2.Zero, _scale, SpriteEffects.None, 0); + spriteBatch.Draw(Resources.SprFog, _position + _offset1, sourceRectangle, Color.White * _transparency, 0, Vector2.Zero, _scale, SpriteEffects.FlipHorizontally | SpriteEffects.FlipVertically, 0); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjHitTrigger.cs b/InGame/GameObjects/Things/ObjHitTrigger.cs new file mode 100644 index 0000000..d47f863 --- /dev/null +++ b/InGame/GameObjects/Things/ObjHitTrigger.cs @@ -0,0 +1,86 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjHitTrigger : GameObject + { + private readonly HitType _hitType; + private readonly string _strKey; + private readonly int _activationTime; + + private float _activationCounter; + private bool _wasActivated; + + private readonly bool _delete; + private readonly bool _soundEffect; + + public ObjHitTrigger() : base("editor hit trigger") { } + + public ObjHitTrigger(Map.Map map, int posX, int posY, int hitType, string strKey, int width, int height, int activationTime, bool delete, bool soundEffect) : base(map) + { + EntitySize = new Rectangle(0, 0, width, height); + + _hitType = (HitType)hitType; + _strKey = strKey; + + _activationTime = activationTime; + + _delete = delete; + _soundEffect = soundEffect; + + _activationCounter = _activationTime; + + if (_activationCounter > 0) + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + + var hitBox = new CBox(posX, posY, 0, width, height, 16); + AddComponent(HittableComponent.Index, new HittableComponent(hitBox, OnHit)); + } + + private void Update() + { + if (!_wasActivated) + return; + + _activationCounter -= Game1.DeltaTime; + if (_activationCounter <= 0) + Activate(); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (_wasActivated) + return Values.HitCollision.None; + + if (damageType == _hitType) + { + if (_activationCounter > 0) + _wasActivated = true; + else + Activate(); + } + + return Values.HitCollision.None; + } + + private void Activate() + { + Game1.GameManager.SaveManager.SetString(_strKey, "1"); + + if (_soundEffect) + Game1.GameManager.PlaySoundEffect("D378-04-04"); + + if (_delete) + Map.Objects.DeleteObjects.Add(this); + else + { + _wasActivated = false; + _activationCounter = _activationTime; + } + } + } +} diff --git a/InGame/GameObjects/Things/ObjHole.cs b/InGame/GameObjects/Things/ObjHole.cs new file mode 100644 index 0000000..b6931a9 --- /dev/null +++ b/InGame/GameObjects/Things/ObjHole.cs @@ -0,0 +1,55 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjHole : GameObject + { + private readonly DrawSpriteComponent _drawComponent; + private readonly BoxCollisionComponent _collisionComponent; + + public readonly Vector2 Center; + public readonly int Color; + + public ObjHole() : base("hole_0") { } + + public ObjHole(Map.Map map, int posX, int posY, int width, int height, Rectangle sourceRectangle, int offsetX, int offsetY, int color) : base(map) + { + Tags = Values.GameObjectTag.Hole; + + Center = new Vector2(posX + offsetX + width / 2, posY + offsetY + height / 2); + Color = color; + + if (sourceRectangle == Rectangle.Empty) + { + EntityPosition = new CPosition(posX + offsetX, posY + offsetY, 0); + EntitySize = new Rectangle(0, 0, width, height); + } + else + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, sourceRectangle.Width, sourceRectangle.Height); + } + + _collisionComponent = new BoxCollisionComponent(new CBox(posX + offsetX, posY + offsetY, 0, width, height, 16), Values.CollisionTypes.Hole); + AddComponent(CollisionComponent.Index, _collisionComponent); + + // visible hole? + if (sourceRectangle != Rectangle.Empty) + { + _drawComponent = new DrawSpriteComponent(Resources.SprObjects, EntityPosition, sourceRectangle, new Vector2(0, 0), Values.LayerBottom); + AddComponent(DrawComponent.Index, _drawComponent); + } + } + + public void SetActive(bool state) + { + if (_drawComponent != null) + _drawComponent.IsActive = state; + _collisionComponent.IsActive = state; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjHoleResetPoint.cs b/InGame/GameObjects/Things/ObjHoleResetPoint.cs new file mode 100644 index 0000000..e1f10eb --- /dev/null +++ b/InGame/GameObjects/Things/ObjHoleResetPoint.cs @@ -0,0 +1,34 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjHoleResetPoint : GameObject + { + private readonly int _direction; + + public ObjHoleResetPoint(Map.Map map, int posX, int posY, int direction) : base(map) + { + SprEditorImage = Resources.SprWhite; + EditorIconSource = new Rectangle(0, 0, 16, 16); + EditorColor = Color.Yellow * 0.75f; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + _direction = direction; + + var collisionRectangle = new Rectangle(posX, posY, 16, 16); + AddComponent(ObjectCollisionComponent.Index, new ObjectCollisionComponent(collisionRectangle, OnCollision)); + } + + private void OnCollision(GameObject gameObject) + { + MapManager.ObjLink.SetHoleResetPosition(EntityPosition.Position, _direction); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjHoleTeleporter.cs b/InGame/GameObjects/Things/ObjHoleTeleporter.cs new file mode 100644 index 0000000..56ba13c --- /dev/null +++ b/InGame/GameObjects/Things/ObjHoleTeleporter.cs @@ -0,0 +1,40 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjHoleTeleporter : GameObject + { + private readonly string _roomName; + private readonly string _entryId; + + public ObjHoleTeleporter(Map.Map map, int posX, int posY, string roomName, string entryId) : base(map) + { + SprEditorImage = Resources.SprWhite; + EditorIconSource = new Rectangle(0, 0, 16, 16); + EditorColor = Color.HotPink * 0.75f; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + _roomName = roomName; + _entryId = entryId; + + var collisionRectangle = new Rectangle(posX, posY, 16, 16); + AddComponent(ObjectCollisionComponent.Index, new ObjectCollisionComponent(collisionRectangle, OnCollision)); + } + + private void OnCollision(GameObject gameObject) + { + MapManager.ObjLink.HoleResetRoom = _roomName; + MapManager.ObjLink.HoleResetEntryId = _entryId; + + MapManager.ObjLink.MapTransitionStart = null; + MapManager.ObjLink.MapTransitionEnd = null; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjHookshot.cs b/InGame/GameObjects/Things/ObjHookshot.cs new file mode 100644 index 0000000..3c1039b --- /dev/null +++ b/InGame/GameObjects/Things/ObjHookshot.cs @@ -0,0 +1,248 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + public class ObjHookshot : GameObject + { + public CPosition HookshotPosition => _hookshotPosition; + + public bool IsMoving; + + private readonly List _itemList = new List(); + private readonly CPosition _hookshotPosition; + private ObjItem _item; + + private readonly DictAtlasEntry _spriteChain; + private readonly DictAtlasEntry _spriteHook; + + private readonly BodyComponent _body; + private readonly CBox _damageBox; + + private Vector2 _direction; + private Vector2 _startPositionOffset; + + private const float Speed = 3; + + private bool _comingBack; + private bool _pullingPlayer; + private bool _pokeParticleSpawned; + + private float _soundCounter; + + public ObjHookshot() + { + _hookshotPosition = new CPosition(0, 0, 0); + _hookshotPosition.AddPositionListener(typeof(ObjHookshot), UpdateItemPosition); + + EntitySize = new Rectangle(-10, -10, 20, 20); + + _damageBox = new CBox(_hookshotPosition, -5, -5, 0, 10, 10, 8, true); + + _body = new BodyComponent(_hookshotPosition, -1, -1, 2, 2, 8) + { + IgnoresZ = true, + IgnoreHoles = true, + IgnoreInsideCollision = false, + MoveCollision = OnCollision, + }; + + _spriteChain = Resources.GetSprite("hookshot_chain"); + _spriteHook = Resources.GetSprite("hookshot_hook"); + + AddComponent(BodyComponent.Index, _body); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, _hookshotPosition)); + } + + public void Reset() + { + IsMoving = false; + } + + public void Start(Map.Map map, Vector3 position, Vector2 direction) + { + Map = map; + + _hookshotPosition.Set(position); + _startPositionOffset = new Vector2(position.X, position.Y) - MapManager.ObjLink.EntityPosition.Position; + + _body.VelocityTarget = direction * Speed; + _body.CollisionTypes = Values.CollisionTypes.Normal | Values.CollisionTypes.Hookshot; + // if the player is on an upper level he can shoot down through walls that are blocking if the is not on the upper level + _body.Level = MapStates.GetLevel(MapManager.ObjLink._body.CurrentFieldState); + + _direction = direction; + + _comingBack = false; + _pullingPlayer = false; + _item = null; + + IsMoving = true; + _pokeParticleSpawned = false; + } + + private void Update() + { + _soundCounter += Game1.DeltaTime; + if (_soundCounter > 65) + { + _soundCounter -= 65; + Game1.GameManager.PlaySoundEffect("D378-11-0B", true); + } + + if (_pullingPlayer) + { + if (!MapManager.ObjLink.UpdateHookshotPull()) + Despawn(); + + return; + } + + var direction = MapManager.ObjLink.EntityPosition.Position + _startPositionOffset - _hookshotPosition.Position; + var distance = direction.Length(); + + _hookshotPosition.Z = MapManager.ObjLink.EntityPosition.Z; + + if (!_comingBack) + { + if (distance > 120) + ComeBack(); + } + else + { + if (direction != Vector2.Zero) + direction.Normalize(); + + _body.VelocityTarget = direction * Speed; + + if (distance < 2) + Despawn(); + } + + CollectItem(); + + // do not hit stuff while coming back + if (!_comingBack) + { + // damage: 2 + var collision = Map.Objects.Hit(this, _hookshotPosition.Position, _damageBox.Box, HitType.Hookshot, 2, false, false); + if ((collision & ( + Values.HitCollision.Enemy | Values.HitCollision.Blocking | + Values.HitCollision.Repelling | Values.HitCollision.RepellingParticle)) != 0) + { + if ((collision & Values.HitCollision.RepellingParticle) != 0 && !_pokeParticleSpawned) + Repell(); + + ComeBack(); + } + } + } + + private void Draw(SpriteBatch spriteBatch) + { + // draw the chain + var handPosition = MapManager.ObjLink.EntityPosition.ToVector3(); + handPosition.X += _startPositionOffset.X; + handPosition.Y += _startPositionOffset.Y; + var direction = _hookshotPosition.ToVector3() - handPosition; + for (var i = 0; i < 3; i++) + spriteBatch.Draw(_spriteChain.Texture, new Vector2(handPosition.X - 2, handPosition.Y - 2 - MapManager.ObjLink.EntityPosition.Z) + + new Vector2(direction.X, direction.Y) * ((i + 0.75f) / 4f) + + new Vector2(0, -direction.Z * ((i + 0.75f) / 4f)), _spriteChain.SourceRectangle, Color.White); + + // draw the hook + spriteBatch.Draw(_spriteHook.Texture, new Vector2(_hookshotPosition.X - 7, + _hookshotPosition.Y - 7 - _hookshotPosition.Z), _spriteHook.SourceRectangle, Color.White); + } + + private void Despawn() + { + IsMoving = false; + Map.Objects.DeleteObjects.Add(this); + } + + private void CollectItem() + { + if (_item != null && !_item.Collected) + return; + + _item = null; + _itemList.Clear(); + + Map.Objects.GetComponentList(_itemList, (int)_damageBox.Box.X, (int)_damageBox.Box.Y, + (int)_damageBox.Box.Width, (int)_damageBox.Box.Height, CollisionComponent.Mask); + + // check if an item was found + foreach (var gameObject in _itemList) + { + var collidingBox = Box.Empty; + var collisionObject = gameObject.Components[CollisionComponent.Index] as CollisionComponent; + if ((collisionObject.CollisionType & Values.CollisionTypes.Item) != 0 && + collisionObject.Collision(_damageBox.Box, 0, 0, ref collidingBox)) + { + var newItem = (ObjItem)collisionObject.Owner; + if (newItem.IsActive && !newItem.Collected) + { + _item = newItem; + _item.InitCollection(); + ComeBack(); + } + } + } + } + + private void UpdateItemPosition(CPosition position) + { + _item?.EntityPosition.Set(new Vector3(position.X, position.Y + 4, position.Z)); + } + + private void ComeBack() + { + _comingBack = true; + _body.CollisionTypes = Values.CollisionTypes.None; + } + + private void OnCollision(Values.BodyCollision collision) + { + var collidingBox = Box.Empty; + var box = _body.BodyBox.Box; + box.X += _direction.X; + box.Y += _direction.Y; + + if (Map.Objects.Collision(box, Box.Empty, Values.CollisionTypes.Hookshot, 0, _body.Level, ref collidingBox)) + { + // gets pulled towards the colliding box + _body.VelocityTarget = Vector2.Zero; + _pullingPlayer = true; + MapManager.ObjLink.StartHookshotPull(); + } + else + { + Repell(); + + ComeBack(); + } + } + + private void Repell() + { + _pokeParticleSpawned = true; + + // hookshot repels from the colliding box + Game1.GameManager.PlaySoundEffect("D360-07-07"); + + var animation = new ObjAnimator(Map, 0, 0, Values.LayerTop, "Particles/swordPoke", "run", true); + animation.EntityPosition.Set(_hookshotPosition.Position); + Map.Objects.SpawnObject(animation); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjIceBlock.cs b/InGame/GameObjects/Things/ObjIceBlock.cs new file mode 100644 index 0000000..5495d14 --- /dev/null +++ b/InGame/GameObjects/Things/ObjIceBlock.cs @@ -0,0 +1,112 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjIceBlock : GameObject + { + private readonly BoxCollisionComponent _collisionComponent; + private readonly Animator _animator; + private readonly CSprite _sprite; + private readonly Rectangle _field; + private readonly int _animationLength; + + private const int RespawnTime = 1000; + private float _respawnCounter; + private bool _isActive = true; + + public ObjIceBlock() : base("ice block") { } + + public ObjIceBlock(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 8, 0); + EntitySize = new Rectangle(-8, -8, 16, 16); + + _field = map.GetField(posX, posY); + + _animator = AnimatorSaveLoad.LoadAnimator("Objects/ice block"); + _animator.Play("idle"); + + _animationLength = _animator.GetAnimationTime(0, _animator.CurrentAnimation.Frames.Length); + + _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-8, -8)); + + var hittableBox = new CBox(EntityPosition, -5, -5, 0, 10, 10, 8, true); + var collisionBox = new CBox(EntityPosition, -8, -8, 0, 16, 16, 16, true); + + AddComponent(CollisionComponent.Index, _collisionComponent = + new BoxCollisionComponent(collisionBox, Values.CollisionTypes.Normal | Values.CollisionTypes.ThrowWeaponIgnore)); + AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(PushableComponent.Index, new PushableComponent(collisionBox, OnPush)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerBottom)); + } + + private void Update() + { + // @HACK: this is used to sync all the animations with the same length + // otherwise they would not be in sync if they did not get updated at the same time + _animator.SetFrame(0); + _animator.SetTime(Game1.TotalGameTime % _animationLength); + _animator.Update(); + + // respawn when the player leaves the room + if (!_isActive && !_field.Contains(MapManager.ObjLink.EntityPosition.Position)) + { + _respawnCounter -= Game1.DeltaTime; + + if (_respawnCounter <= 0) + { + // spawn explosion effect + Map.Objects.SpawnObject(new ObjAnimator(Map, (int)EntityPosition.X - 8, (int)EntityPosition.Y - 7, Values.LayerTop, "Particles/spawn", "run", true)); + + SetActive(true); + } + } + } + + private void SetActive(bool state) + { + _isActive = state; + + _collisionComponent.IsActive = state; + _sprite.IsVisible = state; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType pushType) + { + if (!_isActive) + return false; + + Game1.GameManager.StartDialogPath("ice_block"); + return false; + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (!_isActive || (damageType & (HitType.Sword | HitType.PegasusBootsSword)) != 0) + return Values.HitCollision.None; + if (damageType != HitType.MagicRod) + return Values.HitCollision.Repelling; + + Game1.GameManager.PlaySoundEffect("D378-19-13"); + + var animation = new ObjAnimator(Map, + (int)EntityPosition.X, (int)EntityPosition.Y, 0, 0, Values.LayerPlayer, "Particles/ice block despawn", "run", true); + Map.Objects.SpawnObject(animation); + + _respawnCounter = RespawnTime; + + SetActive(false); + + return Values.HitCollision.None; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjIntroStarter.cs b/InGame/GameObjects/Things/ObjIntroStarter.cs new file mode 100644 index 0000000..37e082b --- /dev/null +++ b/InGame/GameObjects/Things/ObjIntroStarter.cs @@ -0,0 +1,47 @@ +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; + +namespace ProjectZ.InGame.GameObjects.Things +{ + public class ObjIntroStarter : GameObject + { + private bool _init; + + public ObjIntroStarter() : base("editor intro") { } + + public ObjIntroStarter(Map.Map map, int posX, int posY) : base(map) + { + if (Game1.GameManager.SaveManager.GetString("played_intro") == "1") + { + IsDead = true; + return; + } + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + public void Update() + { + if (!_init && MapManager.ObjLink.Map != null) + { + _init = true; + // start the intro + MapManager.ObjLink.StartIntro(); + // create a save state + SaveGameSaveLoad.SaveGame(Game1.GameManager); + } + + if (MapManager.ObjLink.Animation.IsPlaying) + return; + + // start sitting animation + MapManager.ObjLink.Animation.Play("intro_sit"); + + Game1.GameManager.StartDialogPath("marin_intro"); + + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjIslandBackground.cs b/InGame/GameObjects/Things/ObjIslandBackground.cs new file mode 100644 index 0000000..dc9ff29 --- /dev/null +++ b/InGame/GameObjects/Things/ObjIslandBackground.cs @@ -0,0 +1,184 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjIslandBackground : GameObject + { + class Cloud + { + public int Index; + public float LiveCounter; + public float Transparency = 1; + public Vector2 Position; + + public Cloud(int index, Vector2 position) + { + Index = index; + Position = position; + LiveCounter = Game1.RandomNumber.Next(5000, 50000); + } + } + + private Rectangle[] cloudSourceRectangles = new Rectangle[3]; + + private Cloud[] _clouds; + + private const int GradientHeight = 120; + + private readonly Rectangle _waveSource; + private readonly Rectangle _topWaveSource; + + private readonly Color _colorSky = new Color(65, 90, 255); + private readonly Color _colorOceanBright = new Color(66, 89, 255); + + private readonly DictAtlasEntry _oceanGradient; + + private const int LeftCloudPosition = -1300; + + private int _topWaveFrame; + private int _topWaveSpeed = 250; + + public ObjIslandBackground() : base("water_3") { } + + public ObjIslandBackground(Map.Map map, int posX, int posY) : base(map) + { + _waveSource = Resources.SourceRectangle("water_3"); + _waveSource.Width = 16; + _topWaveSource = Resources.SourceRectangle("water_12"); + _topWaveSource.Width = 16; + + cloudSourceRectangles[0] = Resources.SourceRectangle("cloud_0"); + cloudSourceRectangles[1] = Resources.SourceRectangle("cloud_1"); + cloudSourceRectangles[2] = Resources.SourceRectangle("cloud_2"); + + _clouds = new Cloud[50]; + + _oceanGradient = Resources.GetSprite("overworld_gradient"); + + // spawn the clouds + var positionX = LeftCloudPosition; + for (var i = 0; i < _clouds.Length; i++) + { + var index = Game1.RandomNumber.Next(0, cloudSourceRectangles.Length); + _clouds[i] = new Cloud(index, new Vector2(positionX, 32 - cloudSourceRectangles[index].Height)); + positionX += cloudSourceRectangles[index].Width + Game1.RandomNumber.Next(1, 7) * 16; + } + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBackground, new CPosition(posX, posY, 0))); + } + + public void Update() + { + // all the animations are in sync + _topWaveFrame = ((int)(Game1.TotalGameTime) % (4 * _topWaveSpeed)) / _topWaveSpeed; + + // move the clouds + foreach (var cloud in _clouds) + { + var cloudSpeed = (Math.Sin(cloud.Position.X / 100) * 0.125 + 1) * 0.015 * Game1.TimeMultiplier; + cloud.Position.X -= (float)cloudSpeed; + + // set the cloud to the right position + if (cloud.Position.X < LeftCloudPosition) + { + float rightPosition = 0; + foreach (var cloud1 in _clouds) + { + if (cloud1.Position.X > rightPosition) + rightPosition = cloud1.Position.X + cloudSourceRectangles[cloud1.Index].Width; + } + cloud.Position.X = rightPosition + Game1.RandomNumber.Next(1, 7) * 16; + } + } + } + + public void Draw(SpriteBatch spriteBatch) + { + if (MapManager.Camera.Scale <= 0) + return; + + var cameraRectangle = MapManager.Camera.GetCameraRectangle(); + + var left = (int)(cameraRectangle.X / _waveSource.Width / MapManager.Camera.Scale) - 1; + var right = (int)(cameraRectangle.Right / _waveSource.Width / MapManager.Camera.Scale) + 1; + var top = (int)(cameraRectangle.Y / _waveSource.Height / MapManager.Camera.Scale); + var bottom = (int)(cameraRectangle.Bottom / _waveSource.Height / MapManager.Camera.Scale) + 1; + + if (cameraRectangle.X < 0) + { + left--; + right++; + } + if (cameraRectangle.Y < 0) + { + top--; + bottom++; + } + + // draw the top waves + if (top <= 2 && bottom > 2) + for (var x = left; x < right + 1; x++) + { + spriteBatch.Draw(Resources.SprObjects, new Rectangle( + x * _topWaveSource.Width, 2 * _topWaveSource.Height, _topWaveSource.Width, _topWaveSource.Height), + new Rectangle( + _topWaveSource.X + _topWaveSource.Width * _topWaveFrame, _topWaveSource.Y, + _topWaveSource.Width, _topWaveSource.Height), Color.White); + } + + // change context to have smooth gradient transition + spriteBatch.End(); + ObjectManager.SpriteBatchBeginAnisotropic(spriteBatch, null); + + if (top <= 10 && bottom >= 4) + DrawGradient(spriteBatch, left, right, 3, 10); + if (left < 1) + DrawGradient(spriteBatch, left, 2, Math.Max(3, top), Math.Min(bottom, GradientHeight + 3)); + if (right > 16 * 10) + DrawGradient(spriteBatch, 16 * 10, right, Math.Max(3, top), Math.Min(bottom, GradientHeight + 3)); + + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, null); + + var oceanBottomTop = Math.Max(3 + GradientHeight, top); + var oceanBottomBottom = Math.Max(3 + GradientHeight, bottom); + + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + left * Values.TileSize, oceanBottomTop * Values.TileSize, (right - left + 1) * Values.TileSize, (oceanBottomBottom - oceanBottomTop + 1) * Values.TileSize), _colorOceanBright); + + // draw the sky + if (top < 2) + { + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + left * 16, (top - 1) * 16, + (right - left + 1) * 16, (-top + 3) * 16), _colorSky); + } + + // draw the clouds + foreach (var cloud in _clouds) + { + DrawHelper.DrawNormalized(spriteBatch, Resources.SprObjects, cloud.Position, cloudSourceRectangles[cloud.Index], Color.White * cloud.Transparency); + } + } + + private void DrawGradient(SpriteBatch spriteBatch, int left, int right, int top, int bottom) + { + spriteBatch.Draw(_oceanGradient.Texture, new Rectangle( + left * Values.TileSize, top * Values.TileSize, (right - left) * Values.TileSize, (bottom - top) * Values.TileSize), + new Rectangle( + _oceanGradient.ScaledRectangle.X, + _oceanGradient.ScaledRectangle.Y + (int)(_oceanGradient.ScaledRectangle.Height * ((top + 0) / (float)GradientHeight)), + _oceanGradient.ScaledRectangle.Width, + (int)(_oceanGradient.ScaledRectangle.Height * ((bottom - (top + 3)) / (float)GradientHeight))), Color.White); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjItem.cs b/InGame/GameObjects/Things/ObjItem.cs new file mode 100644 index 0000000..4ae5670 --- /dev/null +++ b/InGame/GameObjects/Things/ObjItem.cs @@ -0,0 +1,462 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Base.Systems; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjItem : GameObject + { + public bool IsJumping; + public bool Collectable; + public bool Collected; + + public string SaveKey; + + private GameItem _item; + private string _itemName; + private string _locationBound; + + private AiComponent _aiComponent; + private DrawShadowSpriteComponent _shadowComponent; + private BodyComponent _body; + private AiTriggerCountdown _delayCountdown; + private BodyDrawComponent _bodyDrawComponent; + private CRectangle _collectionRectangle; + + private Rectangle _sourceRectangle; + private Rectangle _sourceRectangleWing = new Rectangle(2, 250, 8, 15); + + private Color _color = Color.White; + private Rectangle _shadowSourceRectangle = new Rectangle(0, 0, 65, 66); + + private float _fadeOffset; + + private double _deepWaterCounter; + private float _despawnCount; + private int _despawnTime = 350; + private int _fadeStart = 250; + private int _moveStopTime = 250; + private int _lastFieldTime; + + private bool _isFlying; + private bool _isSwimming; + private bool _isVisible = true; + private bool _despawn; + + public ObjItem() : base("item") { } + + public ObjItem(Map.Map map, int posX, int posY, string strType, string saveKey, string itemName, string locationBound, bool despawn = false) : base(map) + { + if (!string.IsNullOrEmpty(saveKey)) + { + SaveKey = saveKey; + + // item has already been collected + if (Game1.GameManager.SaveManager.GetString(SaveKey) == "1") + { + IsDead = true; + return; + } + } + + _item = Game1.GameManager.ItemManager[itemName]; + _itemName = itemName; + _locationBound = locationBound; + _despawn = despawn; + + if (_item == null) + { + IsDead = true; + return; + } + + var baseItem = _item.SourceRectangle.HasValue ? _item : Game1.GameManager.ItemManager[_item.Name]; + if (baseItem.MapSprite != null) + _sourceRectangle = baseItem.MapSprite.SourceRectangle; + else + _sourceRectangle = baseItem.SourceRectangle.Value; + + EntityPosition = new CPosition(posX + 8, posY + 8 + 3, 0); + EntitySize = new Rectangle(-9, -16, 18, 18); + + // add sound for the bounces + _body = new BodyComponent(EntityPosition, -4, -8, 8, 8, 8) + { + RestAdditionalMovement = false, + Gravity = -0.1f, + Bounciness = 0.7f, + IgnoreHeight = true, + CollisionTypes = Values.CollisionTypes.Normal | + Values.CollisionTypes.LadderTop, + HoleAbsorb = OnHoleAbsorb, + MoveCollision = OnMoveCollision + }; + + if (!string.IsNullOrEmpty(strType)) + { + // jumping item + if (strType == "j") + { + IsJumping = true; + if (!Map.Is2dMap) + _body.Velocity.Z = 1f; + else + { + Collectable = true; + _body.Velocity.Y = -1f; + } + + // needed because at the first frame the value is still true + _body.IsGrounded = false; + } + // fall from the sky + else if (strType == "d") + { + IsJumping = true; + EntityPosition.Z = 60; + + // needed because at the first frame the value is still true + _body.IsGrounded = false; + _body.RestAdditionalMovement = true; + } + // fly + else if (strType == "w") + { + _body.IsActive = false; + EntityPosition.Z = 10; + Collectable = true; + _isFlying = true; + } + // item is in the water + else if (strType == "s") + { + _isSwimming = true; + } + } + else + { + Collectable = true; + } + + var stateIdle = new AiState(UpdateIdle); + // despawn after 15sec, but only if it was jumping or fall from the sky + if (string.IsNullOrEmpty(saveKey) && !_isFlying && !Collectable) + stateIdle.Trigger.Add(new AiTriggerCountdown(15000, null, ToFading)); + + var stateDelay = new AiState(); + var stateHoleFall = new AiState(); + stateHoleFall.Trigger.Add(new AiTriggerCountdown(125, null, HoleDespawn)); + stateDelay.Trigger.Add(_delayCountdown = new AiTriggerCountdown(0, null, () => + { + _aiComponent.ChangeState("idle"); + _isVisible = true; + if (!Map.Is2dMap) + _body.Velocity.Z = 1f; + else + _body.Velocity.Y = -1f; + EntityPosition.Set(new Vector3(EntityPosition.X, EntityPosition.Y, 0)); + })); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("boomerang", new AiState()); + _aiComponent.States.Add("fading", new AiState(UpdateFading)); + _aiComponent.States.Add("delay", stateDelay); + _aiComponent.States.Add("holeFall", stateHoleFall); + _aiComponent.ChangeState("idle"); + + // we make the collision box a little bit bigger; this is used for the genie where the heart can technically spawn inside the lamp + // with the little extra size the heart will still be collectable + var height = Math.Min(_sourceRectangle.Width, 8); + _collectionRectangle = new CRectangle(EntityPosition, + new Rectangle( + -_sourceRectangle.Width / 2 - 1, -height, + _sourceRectangle.Width + 2, height)); + var box = new CBox(EntityPosition, + -_sourceRectangle.Width / 2, -height, + _sourceRectangle.Width, height, 16); + + AddComponent(BodyComponent.Index, _body); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(ObjectCollisionComponent.Index, new ObjectCollisionComponent(_collectionRectangle, OnCollision)); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(box, Values.CollisionTypes.Item)); + + // item can be collected by hitting it + if (_item.ShowAnimation == 0) + AddComponent(HittableComponent.Index, new HittableComponent(box, OnHit)); + + _shadowComponent = new DrawShadowSpriteComponent( + Resources.SprShadow, EntityPosition, _shadowSourceRectangle, + new Vector2(-_sourceRectangle.Width / 2 - 1, -_sourceRectangle.Width / 4 - 2), 1.0f, 0.0f); + _shadowComponent.Width = _sourceRectangle.Width + 2; + _shadowComponent.Height = _sourceRectangle.Width / 2 + 2; + + _bodyDrawComponent = new BodyDrawComponent(_body, Draw, Values.LayerPlayer); + + if (!_isSwimming) + { + AddComponent(DrawComponent.Index, _bodyDrawComponent); + AddComponent(DrawShadowComponent.Index, _shadowComponent); + } + + if (_itemName == "shellPresent") + { + _shadowComponent.IsActive = false; + _bodyDrawComponent.Layer = Values.LayerBottom; + _collectionRectangle.OffsetSize.X = -4; + _collectionRectangle.OffsetSize.Y = -8; + _collectionRectangle.OffsetSize.Width = 8; + _collectionRectangle.OffsetSize.Height = 8; + _collectionRectangle.UpdateRectangle(EntityPosition); + } + if (_itemName == "shell") + { + // dont spawn additional shells if the player already found 20 + var state = Game1.GameManager.SaveManager.GetString("shellsFound", "0"); + if (state == "1") + IsDead = true; + } + if (_itemName == "sword2") + { + _bodyDrawComponent.Layer = Values.LayerBottom; + } + } + + public override void Init() + { + _lastFieldTime = Map.GetUpdateState(EntityPosition.Position); + } + + public MapStates.FieldStates GetBodyFieldState() + { + return SystemBody.GetFieldState(_body); + } + + public void SpawnBoatSequence() + { + // shrink the collection rectangle + _collectionRectangle.OffsetSize.X = (int)(_collectionRectangle.OffsetSize.X * 0.25f); + _collectionRectangle.OffsetSize.Width = (int)(_collectionRectangle.OffsetSize.Width * 0.25f); + _bodyDrawComponent.Layer = Values.LayerTop; + + _body.Velocity = new Vector3(1, -2.25f, 0); + _body.DragAir = 1.0f; + } + + public void SetVelocity(Vector3 velocity) + { + _body.Velocity = velocity; + } + + public void InitCollection() + { + _body.IgnoresZ = true; + Collectable = true; + _aiComponent.ChangeState("boomerang"); + } + + public void SetSpawnDelay(int delay) + { + _isVisible = false; + _delayCountdown.StartTime = delay; + _aiComponent.ChangeState("delay"); + } + + private void UpdateIdle() + { + if (_body.IsGrounded) + Collectable = true; + + // field went out of the update range? + var updateState = Map.GetUpdateState(EntityPosition.Position); + if (_lastFieldTime < updateState && _despawn) + ToFading(); + + if (!_body.IsActive) + EntityPosition.Z = 20 - _sourceRectangle.Height / 2 + (float)Math.Sin((Game1.TotalGameTime / 1050) * Math.PI * 2) * 1.5f; + + // fall into the water + if (!_isSwimming && !Map.Is2dMap) + { + if (_body.IsGrounded && _body.CurrentFieldState.HasFlag(MapStates.FieldStates.DeepWater)) + { + _deepWaterCounter -= Game1.DeltaTime; + + if (_deepWaterCounter <= 0) + { + // spawn splash effect + var fallAnimation = new ObjAnimator(Map, + (int)(_body.Position.X + _body.OffsetX + _body.Width / 2.0f), + (int)(_body.Position.Y + _body.OffsetY + _body.Height / 2.0f), + Values.LayerPlayer, "Particles/fishingSplash", "idle", true); + Map.Objects.SpawnObject(fallAnimation); + + Map.Objects.DeleteObjects.Add(this); + } + } + else + { + _deepWaterCounter = 125; + } + } + + if (!Map.Is2dMap) + _shadowComponent.Color = Color.White * ((128 + EntityPosition.Z) / 128f); + else + _shadowComponent.Color = _body.IsGrounded ? Color.White : Color.Transparent; + } + + private void ToFading() + { + _body.IgnoresZ = true; + _aiComponent.ChangeState("fading"); + } + + private void UpdateFading() + { + _despawnCount += Game1.DeltaTime; + + // move item up if it was collected + if (Collected && _despawnCount < _moveStopTime) + _fadeOffset = -(float)Math.Sin(_despawnCount / _moveStopTime * Math.PI / 1.5f) * 10; + + // fade the item after fadestart + if (_fadeStart <= _despawnCount) + _color = Color.White * (1 - ((_despawnCount - _fadeStart) / (_despawnTime - _fadeStart))); + + _shadowComponent.Color = _color; + + // remove the object + if (_despawnCount > _despawnTime) + Map.Objects.DeleteObjects.Add(this); + } + + public void Draw(SpriteBatch spriteBatch) + { + if (!_isVisible) + return; + + ItemDrawHelper.DrawItem(spriteBatch, _item, + new Vector2(EntityPosition.X - _sourceRectangle.Width / 2.0f, EntityPosition.Y - EntityPosition.Z - _sourceRectangle.Height + _fadeOffset), _color, 1, true); + + if (!_isFlying) + return; + + var wingFlap = (Game1.TotalGameTime % (16 / 60f * 1000)) < (8 / 60f * 1000) ? SpriteEffects.FlipVertically : SpriteEffects.None; + // left wing + spriteBatch.Draw(Resources.SprItem, new Vector2( + EntityPosition.X - _sourceRectangleWing.Width - 4f, + EntityPosition.Y - EntityPosition.Z - _sourceRectangle.Height / 2 - 10 + _fadeOffset), + _sourceRectangleWing, _color, 0, Vector2.Zero, Vector2.One, SpriteEffects.None | wingFlap, 0); + + // right wing + spriteBatch.Draw(Resources.SprItem, new Vector2( + EntityPosition.X + 4f, + EntityPosition.Y - EntityPosition.Z - _sourceRectangle.Height / 2 - 10 + _fadeOffset), + _sourceRectangleWing, _color, 0, Vector2.Zero, Vector2.One, + SpriteEffects.FlipHorizontally | wingFlap, 0); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + // item can be collected with the sword + if ((damageType & HitType.Sword) != 0 && + (damageType & HitType.SwordHold) == 0) + Collect(); + + return Values.HitCollision.NoneBlocking; + } + + private void OnMoveCollision(Values.BodyCollision collision) + { + // sound should play but only for the trendy game? maybe add a extra item type? + if ((collision & Values.BodyCollision.Floor) != 0 && _body.Velocity.Z > 0.55f || + ((collision & Values.BodyCollision.Bottom) != 0 && _body.Velocity.Y < 0f && Map.Is2dMap)) + { + // metalic bounce sound + if (_item.Name == "smallkey" || _item.Name == "sword2") + Game1.GameManager.PlaySoundEffect("D378-23-17"); + else + Game1.GameManager.PlaySoundEffect("D360-09-09"); + } + } + + private void OnHoleAbsorb() + { + if (Collected) + return; + + _body.IsActive = false; + if (_aiComponent.CurrentStateId != "holeFall") + _aiComponent.ChangeState("holeFall"); + } + + private void HoleDespawn() + { + // play sound effect + Game1.GameManager.PlaySoundEffect("D360-24-18"); + + var fallAnimation = new ObjAnimator(Map, (int)EntityPosition.X - 5, (int)EntityPosition.Y - 8, Values.LayerBottom, "Particles/fall", "idle", true); + Map.Objects.SpawnObject(fallAnimation); + + Map.Objects.DeleteObjects.Add(this); + } + + private void OnCollision(GameObject gameObject) + { + // only collect the item when the player is near it in the z dimension + // maybe the collision component should have used Boxes instead of Rectangles + if (Math.Abs(EntityPosition.Z - MapManager.ObjLink.EntityPosition.Z) < 8 && + (!_isSwimming || MapManager.ObjLink.IsDiving())) + Collect(); + } + + private void Collect() + { + if (!Collectable || Collected) + return; + + if (_isFlying && MapManager.ObjLink.EntityPosition.Z < 7) + return; + + // do not collect the item while the player is not grounded + if (_item.ShowAnimation != 0 && + (!Map.Is2dMap && !MapManager.ObjLink._body.IsGrounded || + Map.Is2dMap && !MapManager.ObjLink._body.IsGrounded && !MapManager.ObjLink.IsInWater2D())) + return; + + Collected = true; + _body.IsActive = false; + _bodyDrawComponent.WaterOutline = false; + + if (Map.Is2dMap) + _body.Velocity.Y = 0f; + else + _body.Velocity.Z = 0f; + + // gets picked up + var cItem = new GameItemCollected(_itemName) + { + Count = _item.Count, + LocationBounding = _locationBound + }; + MapManager.ObjLink.PickUpItem(cItem, true); + + // do not fade away the item if it the player shows it + if (_item.ShowAnimation != 0) + Map.Objects.DeleteObjects.Add(this); + else + ToFading(); + + if (SaveKey != null) + Game1.GameManager.SaveManager.SetString(SaveKey, "1"); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjItemDisabler.cs b/InGame/GameObjects/Things/ObjItemDisabler.cs new file mode 100644 index 0000000..2f84be8 --- /dev/null +++ b/InGame/GameObjects/Things/ObjItemDisabler.cs @@ -0,0 +1,25 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; + +namespace ProjectZ.InGame.GameObjects.Things +{ + public class ObjItemDisabler : GameObject + { + public ObjItemDisabler() : base("editor item disabler") + { + EditorColor = Color.Red; + } + + public ObjItemDisabler(Map.Map map, int posX, int posY) : base(map) + { + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + private void Update() + { + MapManager.ObjLink.DisableItems = true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjItemTester.cs b/InGame/GameObjects/Things/ObjItemTester.cs new file mode 100644 index 0000000..0870dcc --- /dev/null +++ b/InGame/GameObjects/Things/ObjItemTester.cs @@ -0,0 +1,24 @@ +using ProjectZ.InGame.GameObjects.Base; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjItemTester : GameObject + { + public ObjItemTester() : base("item") { } + + public ObjItemTester(Map.Map map, int posX, int posY, int width) : base(map) + { + IsDead = true; + + var index = 0; + foreach (var items in Game1.GameManager.ItemManager.Items) + { + var objPosX = posX + (index % width) * 32; + var objPosY = posY + (index / width) * 32; + var objItem = new ObjItem(map, objPosX, objPosY, "", "", items.Key, ""); + Map.Objects.SpawnObject(objItem); + index++; + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjJump.cs b/InGame/GameObjects/Things/ObjJump.cs new file mode 100644 index 0000000..996174f --- /dev/null +++ b/InGame/GameObjects/Things/ObjJump.cs @@ -0,0 +1,129 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjJump : GameObject + { + private readonly PushableComponent _pushComponent; + private readonly Vector2 _offset; + + private readonly float _inertiaTime; + private readonly float _height; + private readonly float _speed; + private readonly int _direction; + private readonly bool _ignoreCollision; + private readonly bool _moveOnTop; + + public ObjJump() : base("editor jump") + { + EditorColor = Color.Pink * 0.5f; + } + + public ObjJump(Map.Map map, int posX, int posY, int offsetX, int offsetY, int fieldWidth, int fieldHeight, + float height, float speed, int inertiaTime, bool ignoreCollision, bool moveOnTop) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, fieldWidth, fieldHeight); + + _offset = new Vector2(offsetX, offsetY); + _height = height; + _speed = speed; + _inertiaTime = inertiaTime; + _ignoreCollision = ignoreCollision; + _moveOnTop = moveOnTop; + + _direction = AnimationHelper.GetDirection(_offset); + + var box = new CBox(EntityPosition, 0, 0, fieldWidth, fieldHeight, 16); + AddComponent(PushableComponent.Index, _pushComponent = new PushableComponent(box, OnPush)); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + return false; + + // we do the inertia counter stuff in the object because we ignore it while the player is running at the ObjJump + // otherwise we would collide with the object and bounce off + // the object was pushed the last frame? + if (_pushComponent.LastWaitTime >= Game1.TotalGameTimeLast) + { + _pushComponent.InertiaCounter -= Game1.DeltaTime; + _pushComponent.LastWaitTime = Game1.TotalGameTime; + } + else + { + // reset inertia counter if pushing has just begone + _pushComponent.InertiaCounter = _inertiaTime; + _pushComponent.LastWaitTime = Game1.TotalGameTime; + } + + if (_pushComponent.InertiaCounter > 0 && !MapManager.ObjLink.IsDashing()) + return false; + + // calculate the goal position based on the offset, object position and the player position + var playerBody = MapManager.ObjLink._body; + var pushDir = AnimationHelper.GetDirection(direction); + var goalPosition = MapManager.ObjLink.EntityPosition.Position; + + if (pushDir != _direction) + return false; + + if (pushDir == 0) + goalPosition.X = EntityPosition.Position.X + EntitySize.Width + _offset.X - playerBody.Width / 2; + else if (pushDir == 2) + goalPosition.X = EntityPosition.Position.X + _offset.X + playerBody.Width / 2; + else if (pushDir == 1) + goalPosition.Y = EntityPosition.Position.Y + EntitySize.Height + _offset.Y; + else if (pushDir == 3) + goalPosition.Y = EntityPosition.Position.Y + _offset.Y + playerBody.Height; + + if (pushDir % 2 != 0) + goalPosition.X += _offset.X; + if (pushDir % 2 == 0) + goalPosition.Y += _offset.Y; + + var goalPositionZ = 0f; + + // do not initiate a jump if there is something in the way + if (!_ignoreCollision || _moveOnTop) + { + var collidingBox = Box.Empty; + if (Map.Objects.Collision( + new Box(goalPosition.X + playerBody.OffsetX, goalPosition.Y + playerBody.OffsetY, 0, + playerBody.Width, playerBody.Height, 8), + Box.Empty, Values.CollisionTypes.Normal, 0, 0, ref collidingBox)) + { + if (!_moveOnTop || collidingBox.Z + collidingBox.Depth > 8) + return true; + + // jump on top of the colliding box + // this does only work if we only colliding with one box or all the boxes we are colliding with have the same height + goalPositionZ = collidingBox.Top; + } + } + + var offsetLength = _offset.Length(); + + var jumpMult = 1.0f; + if (offsetLength > 16) + jumpMult += (offsetLength - 16) / 32; + if (_offset.Y < -4) + jumpMult *= 0.75f; + + var speedMult = 1.0f; + if (offsetLength > 16) + speedMult = 1 - (offsetLength - 16) / 80; + + MapManager.ObjLink.StartRailJump(goalPosition, jumpMult * _height, speedMult * _speed, goalPositionZ); + + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjJumpRaft.cs b/InGame/GameObjects/Things/ObjJumpRaft.cs new file mode 100644 index 0000000..2645a74 --- /dev/null +++ b/InGame/GameObjects/Things/ObjJumpRaft.cs @@ -0,0 +1,40 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjJumpRaft : GameObject + { + private readonly RectangleF _collisionRectangle; + private readonly int _offsetY; + + public ObjJumpRaft() : base("editor jump") + { + EditorColor = Color.Blue * 0.5f; + } + + public ObjJumpRaft(Map.Map map, int posX, int posY, int width, int offsetY) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, width, 16); + + _collisionRectangle = new RectangleF(posX, posY, width, 16); + _offsetY = offsetY; + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + private void Update() + { + if (_collisionRectangle.Intersects(MapManager.ObjLink.BodyRectangle)) + { + var goalPosition = new Vector2(MapManager.ObjLink.EntityPosition.X, EntityPosition.Y + _offsetY); + MapManager.ObjLink.RaftJump(goalPosition); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjKeyConditionSetter.cs b/InGame/GameObjects/Things/ObjKeyConditionSetter.cs new file mode 100644 index 0000000..6510af4 --- /dev/null +++ b/InGame/GameObjects/Things/ObjKeyConditionSetter.cs @@ -0,0 +1,58 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjKeyConditionSetter : GameObject + { + private readonly SaveLoad.ConditionNode _condition; + private readonly string _strKey; + + private bool _init; + private bool _state; + // key will be set and reset or just set + private bool _reset; + + public ObjKeyConditionSetter() : base("editor key condition setter") + { + EditorColor = Color.Green; + } + + public ObjKeyConditionSetter(Map.Map map, int posX, int posY, string strKey, string strCondition, bool reset) : base(map) + { + // set the key and delete the object + if (string.IsNullOrEmpty(strKey) || string.IsNullOrEmpty(strCondition)) + { + IsDead = true; + return; + } + + _strKey = strKey; + _condition = SaveLoad.SaveCondition.GetConditionNode(strCondition); + _reset = reset; + + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + } + + public void KeyChanged() + { + var active = _condition.Check(); + + if (_init && active == _state) + return; + + _init = true; + + if (active || _reset) + { + // update the state + _state = active; + + Game1.GameManager.SaveManager.SetString(_strKey, active ? "1" : "0"); + // trigger event on the right map + Map.Objects.TriggerKeyChange(); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjKeySetter.cs b/InGame/GameObjects/Things/ObjKeySetter.cs new file mode 100644 index 0000000..942bdba --- /dev/null +++ b/InGame/GameObjects/Things/ObjKeySetter.cs @@ -0,0 +1,22 @@ +using ProjectZ.InGame.GameObjects.Base; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjKeySetter : GameObject + { + public ObjKeySetter() : base("editor key setter") { } + + public ObjKeySetter(Map.Map map, int posX, int posY, string key, string value) : base(map) + { + // set the key and delete the object + if (!string.IsNullOrEmpty(key)) + { + Game1.GameManager.SaveManager.SetString(key, value); + // trigger event on the right map + Map.Objects.TriggerKeyChange(); + } + + IsDead = true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjKeyhole.cs b/InGame/GameObjects/Things/ObjKeyhole.cs new file mode 100644 index 0000000..6fd2138 --- /dev/null +++ b/InGame/GameObjects/Things/ObjKeyhole.cs @@ -0,0 +1,111 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjKeyhole : GameObject + { + private readonly string _itemName; + private readonly string _outputKey; + private readonly string _strDialog; + + private readonly int _shakeTime = 2250; + private readonly int _openTime = 2800; + + private float _counter; + private bool _isOpening; + private bool _isPushed; + private bool _wasPushed; + private bool _rumbling; + + public ObjKeyhole() : base("keyhole_block") { } + + public ObjKeyhole(Map.Map map, int posX, int posY, string itemName, string outputKey, string strDialog) : base(map) + { + _itemName = itemName; + _outputKey = outputKey; + _strDialog = strDialog; + + // check if the lock was already activated + if (_itemName == null || string.IsNullOrEmpty(_outputKey) || + Game1.GameManager.SaveManager.GetString(_outputKey) == "1") + IsDead = true; + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(PushableComponent.Index, new PushableComponent(new CBox(posX + 3, posY + 8, 0, 10, 8, 8), OnPush) { InertiaTime = 75 }); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType pushType) + { + // check if the player has the key to open the door + if (pushType == PushableComponent.PushType.Impact || _isOpening || direction.Y >= 0) + return false; + + _isPushed = true; + + if (Game1.GameManager.GetItem(_itemName) == null) + { + // make sure to only show the dialog the first time while being pushed and after stopping to push + if (!_wasPushed) + Game1.GameManager.StartDialogPath(_strDialog); + + return false; + } + + Open(); + + return true; + } + + private void Open() + { + _isOpening = true; + + Game1.GbsPlayer.Pause(); + + // key sound + Game1.GameManager.PlaySoundEffect("D378-04-04"); + } + + private void Update() + { + _wasPushed = _isPushed; + _isPushed = false; + + if (!_isOpening) + return; + + MapManager.ObjLink.FreezePlayer(); + + _counter += Game1.DeltaTime; + + if (!_rumbling && _counter > 500) + { + _rumbling = true; + + // dungeon one sound + Game1.GameManager.PlaySoundEffect("D378-42-2A"); + + // rumble sound; maybe used for other dungeons? + //Game1.GameManager.PlaySoundEffect("D378-29-1D"); + //Game1.GameManager.PlaySoundEffect("D378-46-2E"); + + // shake the screen + Game1.GameManager.ShakeScreen(_shakeTime, 2, 1, 5.0f, 2.25f); + } + + if (_counter <= _openTime) + return; + + // set the key and open the gate + Game1.GameManager.SaveManager.SetString(_outputKey, "1"); + + Map.Objects.DeleteObjects.Add(this); + + Game1.GbsPlayer.Resume(); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjKeyholeBlock.cs b/InGame/GameObjects/Things/ObjKeyholeBlock.cs new file mode 100644 index 0000000..88c5abb --- /dev/null +++ b/InGame/GameObjects/Things/ObjKeyholeBlock.cs @@ -0,0 +1,61 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjKeyholeBlock : GameObject + { + private readonly string _saveKey; + + public ObjKeyholeBlock() : base("keyhole_block") { } + + public ObjKeyholeBlock(Map.Map map, int posX, int posY, string saveKey) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + _saveKey = saveKey; + + if (!string.IsNullOrEmpty(_saveKey) && Game1.GameManager.SaveManager.GetString(_saveKey, "0") == "1") + { + IsDead = true; + return; + } + + var box = new CBox(EntityPosition, 0, 0, 16, 16, 8); + AddComponent(PushableComponent.Index, new PushableComponent(box, OnPush) { InertiaTime = 175 }); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(box, Values.CollisionTypes.Normal)); + AddComponent(DrawComponent.Index, new DrawSpriteComponent("keyhole_block", EntityPosition, Vector2.Zero, Values.LayerBottom)); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + return false; + + // does the player even have a small key? + var keyItems = Game1.GameManager.GetItem("smallkey"); + if (keyItems == null || Game1.GameManager.GetItem("smallkey").Count <= 0) + { + Game1.GameManager.StartDialogPath("dungeon_keyhole_block"); + return true; + } + + Game1.GameManager.RemoveItem("smallkey", 1); + + if (!string.IsNullOrEmpty(_saveKey)) + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + + // spawn explosion effect + Map.Objects.SpawnObject(new ObjAnimator(Map, (int)EntityPosition.X, (int)EntityPosition.Y, Values.LayerBottom, "Particles/spawn", "run", true)); + + Game1.GameManager.PlaySoundEffect("D378-04-04"); + + // remove the blockade + Map.Objects.DeleteObjects.Add(this); + + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjLadder.cs b/InGame/GameObjects/Things/ObjLadder.cs new file mode 100644 index 0000000..d209e09 --- /dev/null +++ b/InGame/GameObjects/Things/ObjLadder.cs @@ -0,0 +1,50 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + public class ObjLadder : GameObject + { + private readonly Box _collisionRectangle; + private readonly bool _isTop; + + public ObjLadder(Map.Map map, int posX, int posY, bool isTop) : base(map) + { + var sprite = Resources.GetSprite(isTop ? "editor ladder top" : "editor ladder"); + SprEditorImage = sprite.Texture; + EditorIconSource = sprite.ScaledRectangle; + EditorIconScale = sprite.Scale; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(5, 0, 6, 16); + _isTop = isTop; + + if (isTop) + _collisionRectangle = new Box(posX, posY, 0, 16, 16, 8); + else + _collisionRectangle = new Box(posX + 4, posY, 0, 8, 16, 8); + + AddComponent(CollisionComponent.Index, new CollisionComponent(Collision) + { + CollisionType = !isTop ? Values.CollisionTypes.Ladder : + Values.CollisionTypes.Ladder | Values.CollisionTypes.LadderTop + }); + } + + private bool Collision(Box box, int dir, int level, ref Box collidingBox) + { + // only collide if the entity was on top of the ladder the frame before + if ((!_isTop || dir == 3) && _collisionRectangle.Intersects(box)) + { + collidingBox = _collisionRectangle; + return true; + } + + return false; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjLamp.cs b/InGame/GameObjects/Things/ObjLamp.cs new file mode 100644 index 0000000..e5d7e0f --- /dev/null +++ b/InGame/GameObjects/Things/ObjLamp.cs @@ -0,0 +1,192 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjLamp : GameObject + { + private readonly Animator _animator; + + private readonly Color _lightColor = new Color(255, 200, 200); + private readonly Rectangle _lightRectangle; + + private readonly int _animationLength; + + private readonly string _lampKey; + private readonly bool _powderLamp; + + private float _lampState = 1.0f; + private float _liveTime; + + private const int PowderTime = 9000; + + private bool _lampKeyState = true; + + public ObjLamp(Map.Map map, int posX, int posY, string animationName, int rotation, bool hasCollision, bool powderLamp, string lampKey) : base(map) + { + EntityPosition = new CPosition(posX, posY + 8, 0); + + Tags = Values.GameObjectTag.Lamp; + + var lightSize = 160; + EntitySize = new Rectangle(8 - lightSize / 2, -8 - lightSize / 2, lightSize, lightSize); + _lightRectangle = new Rectangle(posX + 8 - lightSize / 2, posY + 8 - lightSize / 2, lightSize, lightSize); + + _animator = AnimatorSaveLoad.LoadAnimator(animationName); + if (_animator == null) + { + Console.WriteLine("Object-ObjLamp: could not find animation name: {0}", animationName); + IsDead = true; + return; + } + _animator.Play("idle"); + + SprEditorImage = _animator.SprTexture; + EditorIconSource = _animator.CurrentFrame.SourceRectangle; + + foreach (var frame in _animator.CurrentAnimation.Frames) + _animationLength += frame.FrameTime; + + EditorIconSource = _animator.CurrentFrame.SourceRectangle; + + var sprite = new CSprite(EntityPosition) + { + Rotation = (float)Math.PI / 2 * rotation, + Center = new Vector2(8, 8) + }; + + // connect animation to sprite + new AnimationComponent(_animator, sprite, new Vector2(8, 0)); + + if (hasCollision) + { + var collisionBox = new CBox(posX, posY, 0, 16, 16, 16); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(collisionBox, Values.CollisionTypes.Normal | Values.CollisionTypes.ThrowWeaponIgnore)); + } + + _powderLamp = powderLamp; + if (_powderLamp) + { + // the collision box is a little bit smaller so that we cant light up two lamps at the same time + var collisionBox = new CBox(posX + 1, posY + 2, 0, 14, 14, 16); + AddComponent(HittableComponent.Index, new HittableComponent(collisionBox, OnHit)); + if (!string.IsNullOrEmpty(lampKey)) + { + _lampKey = lampKey; + Game1.GameManager.SaveManager.SetString(_lampKey, "0"); + } + } + else + { + // lamp can be turned on/off by setting the lamp key + if (!string.IsNullOrEmpty(lampKey)) + { + _lampKey = lampKey; + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + } + } + + // start with the light off + if (powderLamp) + _lampState = 0; + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, hasCollision ? Values.LayerPlayer : Values.LayerBottom)); + AddComponent(LightDrawComponent.Index, new LightDrawComponent(DrawLight)); + } + + public bool IsOn() + { + return _liveTime > 0; + } + + private void OnKeyChange() + { + var keyState = Game1.GameManager.SaveManager.GetString(_lampKey); + var newKeyState = keyState == "1"; + + if (!_lampKeyState && newKeyState) + { + // play sound effect + Game1.GameManager.PlaySoundEffect("D378-18-12"); + } + + _lampKeyState = newKeyState; + _animator.Play(_lampKeyState ? "idle" : "dead"); + } + + private void Update() + { + // @HACK: this is used to sync all the animations with the same length + // otherwise they would not be in sync if they did not get updated at the same time + _animator.SetFrame(0); + _animator.SetTime(Game1.TotalGameTime % _animationLength); + _animator.Update(); + + if (_powderLamp) + UpdatePowderedLamp(); + else + UpdateKeyLamp(); + } + + private void UpdatePowderedLamp() + { + _liveTime -= Game1.DeltaTime; + if (_liveTime < 0) + { + if (_lampKeyState) + { + _lampKeyState = false; + if (!string.IsNullOrEmpty(_lampKey)) + Game1.GameManager.SaveManager.SetString(_lampKey, "0"); + } + + _animator.Play("dead"); + } + else + { + _animator.Play("idle"); + } + + _lampState = AnimationHelper.MoveToTarget(_lampState, _lampKeyState ? 1 : 0, 0.1f * Game1.TimeMultiplier); + } + + private void UpdateKeyLamp() + { + _lampState = AnimationHelper.MoveToTarget(_lampState, _lampKeyState ? 1 : 0, 0.075f * Game1.TimeMultiplier); + } + + private void DrawLight(SpriteBatch spriteBatch) + { + spriteBatch.Draw(Resources.SprLight, _lightRectangle, _lightColor * _lampState); + } + + private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower) + { + if (damageType == HitType.MagicPowder || damageType == HitType.MagicRod) + { + _liveTime = PowderTime; + + // play sound effect + Game1.GameManager.PlaySoundEffect("D378-18-12"); + + _lampKeyState = true; + if (!string.IsNullOrEmpty(_lampKey)) + Game1.GameManager.SaveManager.SetString(_lampKey, "1"); + + return Values.HitCollision.Blocking; + } + + if ((damageType & HitType.Sword) != 0) + return Values.HitCollision.None; + + return Values.HitCollision.NoneBlocking; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjLava.cs b/InGame/GameObjects/Things/ObjLava.cs new file mode 100644 index 0000000..fc55b9f --- /dev/null +++ b/InGame/GameObjects/Things/ObjLava.cs @@ -0,0 +1,65 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjLava : GameObject + { + private readonly Animator _animator; + private readonly int _animationLength; + + private int _fieldX; + private int _fieldY; + + public ObjLava() : base("lava") { } + + public ObjLava(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + Tags = Values.GameObjectTag.Trap; + + _fieldX = posX / 16; + _fieldY = posY / 16; + SetActive(true); + + _animator = AnimatorSaveLoad.LoadAnimator("Objects/lava"); + _animator.Play("idle"); + + _animationLength = _animator.GetAnimationTime(0, _animator.CurrentAnimation.Frames.Length); + + var sprite = new CSprite(EntityPosition); + new AnimationComponent(_animator, sprite, Vector2.Zero); + + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(new CBox(posX, posY, -4, 16, 16, 8), Values.CollisionTypes.DeepWater)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerBackground)); + } + + private void Update() + { + // @HACK: this is used to sync all the animations with the same length + // otherwise they would not be in sync if they did not get updated at the same time + _animator.SetFrame(0); + _animator.SetTime(Game1.TotalGameTime % _animationLength); + _animator.Update(); + } + + public void SetActive(bool active) + { + IsActive = active; + + if (active) + Map.AddFieldState(_fieldX, _fieldY, + MapStates.FieldStates.DeepWater | MapStates.FieldStates.Lava); + else + Map.SetFieldState(_fieldX, _fieldY, MapStates.FieldStates.None); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjLavaField.cs b/InGame/GameObjects/Things/ObjLavaField.cs new file mode 100644 index 0000000..21932fa --- /dev/null +++ b/InGame/GameObjects/Things/ObjLavaField.cs @@ -0,0 +1,13 @@ +using ProjectZ.InGame.Map; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjLavaField : ObjAnimatedTile + { + public ObjLavaField(Map.Map map, int posX, int posY, string spriteId, int frames, int animationSpeed, bool sync, int spriteEffects, int drawLayer) + : base(map, posX, posY, spriteId, frames, animationSpeed, sync, spriteEffects, drawLayer) + { + Map.AddFieldState(posX / 16, posY / 16, MapStates.FieldStates.Lava); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjLeaf.cs b/InGame/GameObjects/Things/ObjLeaf.cs new file mode 100644 index 0000000..d84263d --- /dev/null +++ b/InGame/GameObjects/Things/ObjLeaf.cs @@ -0,0 +1,112 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjLeaf : GameObject + { + private readonly AiComponent _aiComponent; + private readonly CSprite _sprite; + private readonly DrawShadowSpriteComponent _shadowSprite; + + private Vector2 _velocity; + + private double _objTimer; + + private readonly float _direction; + private readonly float _fallSpeed = 0.075f; + + private readonly int _despawnTime = 250; + + public ObjLeaf(Map.Map map, int posX, int posY, float posZ, Vector2 velocity) : base(map) + { + _velocity = velocity; + + _objTimer = (int)(Game1.RandomNumber.Next(0, 250) * velocity.X); + _direction = velocity.X / 2f; + + EntityPosition = new CPosition(posX, posY, posZ); + EntitySize = new Rectangle(-2, -9, 12, 10); + + _aiComponent = new AiComponent(); + + var stateFalling = new AiState(StateFalling); + + var stateLieing = new AiState(StateLie); + stateLieing.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("fading"), 250, 750)); + + var stateDespawning = new AiState(StateFading); + stateDespawning.Trigger.Add(new AiTriggerCountdown(_despawnTime, FadeTick, FadeEnd)); + + _aiComponent.States.Add("falling", stateFalling); + _aiComponent.States.Add("lie", stateLieing); + _aiComponent.States.Add("fading", stateDespawning); + + _aiComponent.ChangeState("falling"); + + + _shadowSprite = new DrawShadowSpriteComponent(Resources.SprShadow, + EntityPosition, new Rectangle(0, 0, 65, 66), new Vector2(-1, -3), 1.0f, 0.0f); + _shadowSprite.Width = 10; + _shadowSprite.Height = 4; + + var sourceRectangle = Resources.SourceRectangle("leaf"); + _sprite = new CSprite(Resources.SprObjects, EntityPosition, sourceRectangle, new Vector2(0, -6)); + _sprite.Color = Color.White * 0.8f; + + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, _shadowSprite); + } + + public void StateFalling() + { + _objTimer += Game1.DeltaTime; + + // fall down + EntityPosition.Z -= Game1.TimeMultiplier * _fallSpeed; + + // fall state + _sprite.DrawOffset.X = (float)Math.Sin(_objTimer / 150f * _direction) * 3; + _shadowSprite.DrawOffset.X = _sprite.DrawOffset.X - 1; + EntityPosition.Move(_velocity); + + // flip the leaf depending on the direction it is moving + if (Math.Cos(_objTimer / 150f) + _velocity.X < 0) + _sprite.SpriteEffect = SpriteEffects.None; + else + _sprite.SpriteEffect = SpriteEffects.FlipHorizontally; + + _velocity *= (float)Math.Pow(0.85, Game1.TimeMultiplier); + + if (EntityPosition.Z <= 0) + { + EntityPosition.Z = 0; + _aiComponent.ChangeState("lie"); + } + } + + public void StateLie() { } + + public void StateFading() { } + + // fade away + public void FadeTick(double currentState) + { + _sprite.Color = Color.White * (float)(currentState / _despawnTime) * 0.9f; + _shadowSprite.Color = _sprite.Color; + } + + // remove the leaf + public void FadeEnd() + { + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjLeverStone.cs b/InGame/GameObjects/Things/ObjLeverStone.cs new file mode 100644 index 0000000..35f07ad --- /dev/null +++ b/InGame/GameObjects/Things/ObjLeverStone.cs @@ -0,0 +1,83 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Systems; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjLeverStone : GameObject + { + private readonly List _collidingObjects = new List(); + private readonly CBox _box; + + private readonly Vector2 _startPosition; + private readonly Vector2 _endPosition; + + private readonly int _direction; + + public ObjLeverStone() : base("movestone_0") { } + + public ObjLeverStone(Map.Map map, int posX, int posY, int direction) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + _direction = direction; + + _startPosition = new Vector2(posX, posY); + _endPosition = new Vector2(posX, posY) + AnimationHelper.DirectionOffset[direction] * 16; + + _box = new CBox(EntityPosition, 0, 0, 0, 16, 16, 8); + + // does not deal damage in the real game + var damageBox = new CBox(EntityPosition, 1, 1, 0, 14, 14, 8); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Object, 2)); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(_box, Values.CollisionTypes.Normal)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawSpriteComponent("movestone_0", EntityPosition, Vector2.Zero, Values.LayerBottom)); + } + + private void Update() + { + UpdatePosition(ObjPullLever.LeverState); + } + + private void UpdatePosition(float amount) + { + var lastBox = _box.Box; + + EntityPosition.Set(Vector2.Lerp(_startPosition, _endPosition, amount)); + + // @HACK: this kind of stuff should be inside the movement system + + // check for colliding bodies and push them forward + _collidingObjects.Clear(); + Map.Objects.GetComponentList(_collidingObjects, + (int)EntityPosition.Position.X - 1, (int)EntityPosition.Position.Y - 1, 18, 18, BodyComponent.Mask); + + foreach (var collidingObject in _collidingObjects) + { + var body = (BodyComponent)collidingObject.Components[BodyComponent.Index]; + + if (body.BodyBox.Box.Intersects(_box.Box) && !body.BodyBox.Box.Intersects(lastBox)) + { + var offset = Vector2.Zero; + if (_direction == 2) + offset.X = _box.Box.Left - body.BodyBox.Box.Right - 0.05f; + else if (_direction == 0) + offset.X = _box.Box.Right - body.BodyBox.Box.Left + 0.05f; + else if (_direction == 3) + offset.Y = _box.Box.Back - body.BodyBox.Box.Front - 0.05f; + else if (_direction == 1) + offset.Y = _box.Box.Front - body.BodyBox.Box.Back + 0.05f; + + SystemBody.MoveBody(body, offset, body.CollisionTypes, false, false, false); + body.Position.NotifyListeners(); + } + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjLight.cs b/InGame/GameObjects/Things/ObjLight.cs new file mode 100644 index 0000000..aee464f --- /dev/null +++ b/InGame/GameObjects/Things/ObjLight.cs @@ -0,0 +1,34 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjLight : GameObject + { + private readonly Rectangle _drawRectangle; + private readonly Color _lightColor; + + public ObjLight() : base("editor light") { } + + public ObjLight(Map.Map map, int posX, int posY, int size, int colorR, int colorG, int colorB, int colorA, int layer) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 8, 0); + EntitySize = new Rectangle(-size / 2, -size / 2, size, size); + + _drawRectangle = new Rectangle(posX + 8 - size / 2, posY + 8 - size / 2, size, size); + + _lightColor = new Color(colorR, colorG, colorB) * (colorA / 255f); + + AddComponent(LightDrawComponent.Index, new LightDrawComponent(DrawLight) { Layer = layer }); + } + + public void DrawLight(SpriteBatch spriteBatch) + { + spriteBatch.Draw(Resources.SprLight, _drawRectangle, _lightColor); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjLightSprite.cs b/InGame/GameObjects/Things/ObjLightSprite.cs new file mode 100644 index 0000000..f51135d --- /dev/null +++ b/InGame/GameObjects/Things/ObjLightSprite.cs @@ -0,0 +1,53 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjLightSprite : GameObject + { + private readonly DictAtlasEntry _sprite; + private readonly Color _lightColor; + + private readonly Vector2 _position; + + private readonly float _rotation; + + public ObjLightSprite() : base("editor light") { } + + public ObjLightSprite(Map.Map map, int posX, int posY, string spriteId, int colorR, int colorG, int colorB, int colorA, int layer, int rotation) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + + if (!string.IsNullOrEmpty(spriteId)) + _sprite = Resources.GetSprite(spriteId); + + if (_sprite == null) + { + Console.WriteLine("Could not find spriteId: " + spriteId); + IsDead = true; + return; + } + + EntitySize = new Rectangle(0, 0, _sprite.SourceRectangle.Width, _sprite.SourceRectangle.Height); + + _position = new Vector2(EntityPosition.X + _sprite.Origin.X, EntityPosition.Y + _sprite.Origin.Y); + + _lightColor = new Color(colorR, colorG, colorB) * (colorA / 255f); + _rotation = rotation * MathF.PI / 2; + + AddComponent(LightDrawComponent.Index, new LightDrawComponent(DrawLight) { Layer = layer }); + } + + public void DrawLight(SpriteBatch spriteBatch) + { + spriteBatch.Draw(_sprite.Texture, _position, _sprite.ScaledRectangle, + _lightColor, _rotation, _sprite.ScaledOrigin, _sprite.Scale, SpriteEffects.None, 0); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjMagicRodShot.cs b/InGame/GameObjects/Things/ObjMagicRodShot.cs new file mode 100644 index 0000000..d8220ef --- /dev/null +++ b/InGame/GameObjects/Things/ObjMagicRodShot.cs @@ -0,0 +1,98 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjMagicRodShot : GameObject + { + private readonly CSprite _sprite; + private readonly CBox _damageBox; + + private const int SpawnTime = 25; + // ~ time to move from the left side of a room to the right + private const int DespawnTime = 500; + private const int FadeInTime = 25; + private const int FadeOutTime = 50; + + private float _spawnCounter; + private bool _dead; + + public ObjMagicRodShot(Map.Map map, Vector3 position, Vector2 direction, int dir) : base(map) + { + EntityPosition = new CPosition(position.X, position.Y, position.Z); + EntitySize = new Rectangle(-8, -8, 16, 16); + + _damageBox = new CBox(EntityPosition, -3, -3, 0, 6, 6, 8); + + _sprite = new CSprite("magicRodShot", EntityPosition) + { + Color = Color.Transparent + }; + + var body = new BodyComponent(EntityPosition, -2 + (dir == 1 ? 2 : (dir == 3 ? -2 : 0)), -2, 4, 4, 8) + { + VelocityTarget = direction, + CollisionTypesIgnore = Values.CollisionTypes.ThrowWeaponIgnore, + MoveCollision = OnCollision, + IgnoreHoles = true, + IgnoresZ = true, + IgnoreInsideCollision = false, + Level = MapStates.GetLevel(MapManager.ObjLink._body.CurrentFieldState) + }; + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(BodyComponent.Index, body); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerPlayer)); + } + + private void Update() + { + _spawnCounter += Game1.DeltaTime; + + // only start showing the sprite after the spawn time + if (_spawnCounter > SpawnTime) + { + if (_spawnCounter > DespawnTime) + // fade out + _sprite.Color = Color.White * (1 - Math.Clamp((_spawnCounter - DespawnTime) / FadeOutTime, 0, 1)); + else + // fade in + _sprite.Color = Color.White * Math.Clamp((_spawnCounter - SpawnTime) / FadeInTime, 0, 1); + + if (_spawnCounter > DespawnTime + FadeOutTime) + { + _dead = true; + Map.Objects.DeleteObjects.Add(this); + return; + } + + } + + var collision = Map.Objects.Hit(this, EntityPosition.Position, _damageBox.Box, HitType.MagicRod, 2, false); + if ((collision & (Values.HitCollision.Blocking | Values.HitCollision.Repelling | Values.HitCollision.Enemy)) != 0) + { + _dead = true; + Map.Objects.DeleteObjects.Add(this); + } + } + + private void OnCollision(Values.BodyCollision collision) + { + if (_dead) + return; + + Game1.GameManager.PlaySoundEffect("D378-18-12"); + + var animation = new ObjAnimator(Map, (int)EntityPosition.X, (int)EntityPosition.Y - (int)EntityPosition.Z, + 0, 0, Values.LayerPlayer, "Particles/flame", "idle", true); + Map.Objects.SpawnObject(animation); + + Map.Objects.DeleteObjects.Add(this); + } + } +} diff --git a/InGame/GameObjects/Things/ObjMarinDisabler.cs b/InGame/GameObjects/Things/ObjMarinDisabler.cs new file mode 100644 index 0000000..dee16b4 --- /dev/null +++ b/InGame/GameObjects/Things/ObjMarinDisabler.cs @@ -0,0 +1,22 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.Map; + +namespace ProjectZ.InGame.GameObjects.Things +{ + public class ObjMarinDisabler : GameObject + { + public ObjMarinDisabler() : base("marin") { } + + public ObjMarinDisabler(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + var marin = MapManager.ObjLink.GetMarin(); + if (marin != null) + marin.IsHidden = true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjMarinDungeonEntry.cs b/InGame/GameObjects/Things/ObjMarinDungeonEntry.cs new file mode 100644 index 0000000..3a607a2 --- /dev/null +++ b/InGame/GameObjects/Things/ObjMarinDungeonEntry.cs @@ -0,0 +1,43 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjMarinDungeonEntry : GameObject + { + private Rectangle _rectangle; + + public ObjMarinDungeonEntry(Map.Map map, int posX, int posY, int offsetX, int offsetY) : base(map) + { + EditorIconSource = new Rectangle(0, 0, 16, 16); + EditorColor = Color.Blue; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + _rectangle = new Rectangle(posX, posY, 16, 16); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + public override void Init() + { + if (MapManager.ObjLink.NextMapPositionStart == null) + return; + + var linkPosition = MapManager.ObjLink.NextMapPositionStart.Value; + if (_rectangle.Contains(new Point((int)linkPosition.X, (int)linkPosition.Y))) + { + MapManager.ObjLink.GetMarin().LeaveDungeonSequence(EntityPosition.Position); + } + } + + private void Update() + { + if (MapManager.ObjLink.BodyRectangle.Intersects(_rectangle)) + MapManager.ObjLink.GetMarin().EnterDungeonMessage = true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjMermaidStatue.cs b/InGame/GameObjects/Things/ObjMermaidStatue.cs new file mode 100644 index 0000000..86c96c2 --- /dev/null +++ b/InGame/GameObjects/Things/ObjMermaidStatue.cs @@ -0,0 +1,117 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjMermaidStatue : GameObject + { + private readonly AiComponent _aiComponent; + private readonly BodyComponent _body; + private readonly CBox _box; + + private Vector2 _startPosition; + private Vector2 _endPosition; + + private readonly string _strKey; + private readonly int _moveTime = 650; + + private bool _moved; + + public ObjMermaidStatue() : base("mermaid_statue") { } + + public ObjMermaidStatue(Map.Map map, int posX, int posY, string strKey) : base(map) + { + int offset = -4; + + EntityPosition = new CPosition(posX + 8, posY + 32 + offset, 0); + EntitySize = new Rectangle(-8, -32 - offset, 16, 32); + + _startPosition = EntityPosition.Position; + _endPosition = _startPosition - new Vector2(16, 0); + + _strKey = strKey; + + _body = new BodyComponent(EntityPosition, -8, -16 - offset, 16, 16, 8); + + var stateIdle = new AiState(); + var statePreMoving = new AiState(UpdateFreezePlayer); + statePreMoving.Trigger.Add(new AiTriggerCountdown(250, null, () => _aiComponent.ChangeState("moving"))); + var stateMoving = new AiState(UpdateFreezePlayer) { Init = InitMoving }; + stateMoving.Trigger.Add(new AiTriggerCountdown(_moveTime, MoveTick, MoveEnd)); + var stateMoved = new AiState(); + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", stateIdle); + _aiComponent.States.Add("preMoving", statePreMoving); + _aiComponent.States.Add("moving", stateMoving); + _aiComponent.States.Add("moved", stateMoved); + _aiComponent.ChangeState("idle"); + + _box = new CBox(EntityPosition, -8, -16 - offset, 16, 16, 16); + + AddComponent(InteractComponent.Index, new InteractComponent(_box, OnInteract)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, _body); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(_box, Values.CollisionTypes.Normal | Values.CollisionTypes.Hookshot)); + AddComponent(DrawComponent.Index, new DrawSpriteComponent("mermaid_statue", EntityPosition, Values.LayerPlayer)); + + // already moved? + if (!string.IsNullOrEmpty(_strKey) && Game1.GameManager.SaveManager.GetString(_strKey) == "1") + { + MoveTick(0); + _aiComponent.ChangeState("moved"); + } + } + + private bool OnInteract() + { + var itemScale = Game1.GameManager.GetItem("trade12"); + if (itemScale != null && itemScale.Count >= 1) + { + Game1.GameManager.RemoveItem("trade12", 1); + Game1.GameManager.StartDialogPath("mermaid_statue_1"); + Game1.GameManager.PlaySoundEffect("D378-04-04"); + _aiComponent.ChangeState("preMoving"); + } + else if (!_moved) + { + Game1.GameManager.StartDialogPath("mermaid_statue_0"); + } + + return true; + } + + private void UpdateFreezePlayer() + { + MapManager.ObjLink.FreezePlayer(); + } + + private void InitMoving() + { + Game1.GameManager.PlaySoundEffect("D378-17-11"); + } + + private void MoveTick(double time) + { + // the movement is fast in the beginning and slows down at the end + var amount = (float)Math.Sin((_moveTime - time) / _moveTime * (Math.PI / 2f)); + var newPosition = Vector2.Lerp(_startPosition, _endPosition, amount); + EntityPosition.Set(newPosition); + } + + private void MoveEnd() + { + MoveTick(0); + Game1.GameManager.SaveManager.SetString(_strKey, "1"); + _aiComponent.ChangeState("moved"); + + Game1.GameManager.PlaySoundEffect("D360-02-02"); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjMoveStone - Copy.cs b/InGame/GameObjects/Things/ObjMoveStone - Copy.cs new file mode 100644 index 0000000..affd53c --- /dev/null +++ b/InGame/GameObjects/Things/ObjMoveStone - Copy.cs @@ -0,0 +1,295 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Base.Systems; +using ProjectZ.InGame.GameSystems; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjMoveStoneBlackBar : GameObject + { + private readonly List _collidingObjects = new List(); + + private readonly AiComponent _aiComponent; + private readonly BodyComponent _body; + private readonly CBox _box; + + private Vector2 _startPosition; + private Vector2 _goalPosition; + + private readonly string _strKey; + private readonly string _strKeyDir; + private readonly string _strResetKey; + private readonly int _allowedDirections; + private readonly int _moveTime = 750; + + private int _moveDirection; + private bool _freezePlayer; + private bool _isResetting; + + // type 1 sets the key directly on push and resets it on spawn + // used for the gravestone + private int _type; + + public ObjMoveStoneBlackBar(Map.Map map, int posX, int posY, int moveDirections, string strKey, + string spriteId, Rectangle collisionRectangle, int layer, int type, bool freezePlayer, string resetKey) : base(map, spriteId) + { + EntityPosition = new CPosition(posX, posY + 16, 0); + EntitySize = new Rectangle(0, -22, 22, 22); + + _allowedDirections = moveDirections; + _strKey = strKey; + _strKeyDir = strKey + "_dir"; + _type = type; + _freezePlayer = freezePlayer; + _strResetKey = resetKey; + + _body = new BodyComponent(EntityPosition, 3, -13, 10, 10, 8) + { + IgnoreHeight = true, + IgnoreHoles = true, + }; + + _startPosition = new Vector2(posX, posY + 16); + + // moves the stone + var movingTrigger = new AiTriggerCountdown(_moveTime, MoveTick, MoveEnd); + var movedState = new AiState { Init = InitMoved }; + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", new AiState()); + _aiComponent.States.Add("moving", new AiState { Trigger = { movingTrigger } }); + _aiComponent.States.Add("moved", movedState); + new AiFallState(_aiComponent, _body, null, null, 200); + _aiComponent.ChangeState("idle"); + + _box = new CBox(EntityPosition, collisionRectangle.X, collisionRectangle.Y, + collisionRectangle.Width, collisionRectangle.Height, 16); + + var sprite = Resources.GetSprite(spriteId); + + if (_type == 16) + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + + AddComponent(AiComponent.Index, _aiComponent); + if (moveDirections != 0) + AddComponent(BodyComponent.Index, _body); + AddComponent(PushableComponent.Index, new PushableComponent(_box, OnPush) { InertiaTime = 450 }); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(_box, Values.CollisionTypes.Normal | Values.CollisionTypes.Hookshot)); + + if (_type != 16 && _type != 17) + AddComponent(DrawComponent.Index, new DrawSpriteComponent(spriteId, EntityPosition, new Vector2(0, -sprite.SourceRectangle.Height), layer)); + if (_type == 16 || _type == 17) + AddComponent(DrawComponent.Index, new DrawComponent(Draw, 3, EntityPosition)); + + if (!string.IsNullOrEmpty(_strResetKey)) + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + + // set the key + if (_type == 1 && _strKey != null) + Game1.GameManager.SaveManager.SetString(_strKey, "0"); + if (!string.IsNullOrEmpty(_strKeyDir)) + Game1.GameManager.SaveManager.SetString(_strKeyDir, "-1"); + } + + private void OnKeyChange() + { + // check if the block should be moved back to the start position + var keyState = Game1.GameManager.SaveManager.GetString(_strResetKey); + if (keyState == "1" && _aiComponent.CurrentStateId == "moved") + ResetToStart(); + } + + private void ResetToStart() + { + _isResetting = true; + _goalPosition = _startPosition; + _startPosition = EntityPosition.Position; + + _moveDirection = (_moveDirection + 2) % 4; + + if (!string.IsNullOrEmpty(_strKeyDir)) + Game1.GameManager.SaveManager.SetString(_strKeyDir, "-1"); + + ToMoving(); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact || + _aiComponent.CurrentStateId != "idle") + return false; + + if (_type == 1 && Game1.GameManager.StoneGrabberLevel <= 0) + return false; + + _moveDirection = AnimationHelper.GetDirection(direction); + + if (_allowedDirections != -1 && (_allowedDirections & (0x01 << _moveDirection)) == 0) + return false; + + // only move if there is nothing blocking the way + var pushVector = AnimationHelper.DirectionOffset[_moveDirection]; + var collidingRectangle = Box.Empty; + if (Map.Objects.Collision(new Box( + EntityPosition.X + pushVector.X * 16, + EntityPosition.Y + pushVector.Y * 16 - 16, 0, 16, 16, 16), + Box.Empty, Values.CollisionTypes.Normal, 0, 0, ref collidingRectangle)) + return true; + + _startPosition = EntityPosition.Position; + + _goalPosition = new Vector2( + _startPosition.X + pushVector.X * 16, + _startPosition.Y + pushVector.Y * 16); + + ToMoving(); + + if (!string.IsNullOrEmpty(_strResetKey)) + Game1.GameManager.SaveManager.SetString(_strResetKey, "0"); + + // set the key + if (_type == 1 && !string.IsNullOrEmpty(_strKey)) + Game1.GameManager.SaveManager.SetString(_strKey, "1"); + + if (_type == 1 && !string.IsNullOrEmpty(_strKeyDir)) + Game1.GameManager.SaveManager.SetString(_strKeyDir, _moveDirection.ToString()); + + return true; + } + + private void Update() + { + //if (EntityPosition.Position == _goalPosition || ((MapTransitionSystem)Game1.GameManager.GameSystems[typeof(MapTransitionSystem)]).IsTransitioning()) + // return; + + //Game1.GameManager.MapManager.UpdateCameraX = false; + //Game1.GameManager.MapManager.UpdateCameraY = false; + } + + private void Draw(SpriteBatch spriteBatch) + { + if (_type == 16) + { + spriteBatch.Draw(Resources.SprWhite, new Rectangle((int)_startPosition.X - 320 + 16 - (int)(_moveAmount * 240), (int)_startPosition.Y - 300, 320, 900), Color.Black); + spriteBatch.Draw(Resources.SprWhite, new Rectangle((int)_startPosition.X + 160 + 16 + (int)(_moveAmount * 240), (int)_startPosition.Y - 300, 320, 900), Color.Black); + } + + if (_type == 17) + { + spriteBatch.Draw(Resources.SprWhite, new Rectangle((int)_startPosition.X - 300, (int)_startPosition.Y - 16 + (int)(_moveAmount * 160), 900, 240), Color.Black); + spriteBatch.Draw(Resources.SprWhite, new Rectangle((int)_startPosition.X - 300, (int)_startPosition.Y - 128 - 16 - 240 - (int)(_moveAmount * 160), 900, 240), Color.Black); + } + } + + private void ToMoving() + { + Game1.GameManager.PlaySoundEffect("D378-17-11"); + _aiComponent.ChangeState("moving"); + } + + float _moveAmount; + + private void MoveTick(double time) + { + // the movement is fast in the beginning and slows down at the end + var amount = (float)Math.Sin((_moveTime - time) / _moveTime * (Math.PI / 2f)); + _moveAmount = amount; + + Move(amount); + + if (!_isResetting && _freezePlayer) + MapManager.ObjLink.FreezePlayer(); + } + + private void MoveEnd() + { + // finished moving + Move(1); + + Map.Objects.RemoveObject(this); + + // set the key + if (_type == 0 && !string.IsNullOrEmpty(_strKey)) + Game1.GameManager.SaveManager.SetString(_strKey, "1"); + // set the direction key + if (_type == 0 && !string.IsNullOrEmpty(_strKeyDir)) + Game1.GameManager.SaveManager.SetString(_strKeyDir, _moveDirection.ToString()); + + if (_isResetting) + { + _isResetting = false; + _aiComponent.ChangeState("idle"); + } + else + _aiComponent.ChangeState("moved"); + + // can fall into holes after finishing the movement animation + _body.IgnoreHoles = false; + } + + private void InitMoved() + { + // fall into the water + if (_body.CurrentFieldState.HasFlag(MapStates.FieldStates.DeepWater)) + { + Game1.GameManager.PlaySoundEffect("D360-14-0E"); + + // spawn splash effect + var fallAnimation = new ObjAnimator(Map, + (int)(_body.Position.X + _body.OffsetX + _body.Width / 2.0f), + (int)(_body.Position.Y + _body.OffsetY + _body.Height - 2), + Values.LayerPlayer, "Particles/fishingSplash", "idle", true); + Map.Objects.SpawnObject(fallAnimation); + + Map.Objects.DeleteObjects.Add(this); + } + } + + private void Move(float amount) + { + var lastBox = _box.Box; + + EntityPosition.Set(Vector2.Lerp(_startPosition, _goalPosition, amount)); + + // @HACK: this kind of stuff should be inside the movement system + + // check for colliding bodies and push them forward + _collidingObjects.Clear(); + Map.Objects.GetComponentList(_collidingObjects, + (int)EntityPosition.Position.X, (int)EntityPosition.Position.Y - 16, 17, 17, BodyComponent.Mask); + + foreach (var collidingObject in _collidingObjects) + { + if (collidingObject is ObjMoveStone) + continue; + + var body = (BodyComponent)collidingObject.Components[BodyComponent.Index]; + + if (body.BodyBox.Box.Intersects(_box.Box) && !body.BodyBox.Box.Intersects(lastBox)) + { + var offset = Vector2.Zero; + if (_moveDirection == 0) + offset.X = _box.Box.Left - body.BodyBox.Box.Right - 0.05f; + else if (_moveDirection == 2) + offset.X = _box.Box.Right - body.BodyBox.Box.Left + 0.05f; + else if (_moveDirection == 1) + offset.Y = _box.Box.Back - body.BodyBox.Box.Front - 0.05f; + else if (_moveDirection == 3) + offset.Y = _box.Box.Front - body.BodyBox.Box.Back + 0.05f; + + SystemBody.MoveBody(body, offset, body.CollisionTypes, false, false, false); + body.Position.NotifyListeners(); + } + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjMoveStone.cs b/InGame/GameObjects/Things/ObjMoveStone.cs new file mode 100644 index 0000000..f6f5d4f --- /dev/null +++ b/InGame/GameObjects/Things/ObjMoveStone.cs @@ -0,0 +1,255 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.GameObjects.Base.Systems; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjMoveStone : GameObject + { + private readonly List _collidingObjects = new List(); + + private readonly AiComponent _aiComponent; + private readonly BodyComponent _body; + private readonly CBox _box; + + private Vector2 _startPosition; + private Vector2 _goalPosition; + + private readonly string _strKey; + private readonly string _strKeyDir; + private readonly string _strResetKey; + private readonly int _allowedDirections; + private readonly int _moveTime = 450; + + private int _moveDirection; + private bool _freezePlayer; + private bool _isResetting; + + // type 1 sets the key directly on push and resets it on spawn + // used for the gravestone + private int _type; + + public ObjMoveStone(Map.Map map, int posX, int posY, int moveDirections, string strKey, + string spriteId, Rectangle collisionRectangle, int layer, int type, bool freezePlayer, string resetKey) : base(map, spriteId) + { + EntityPosition = new CPosition(posX, posY + 16, 0); + EntitySize = new Rectangle(0, -16, 16, 16); + + _allowedDirections = moveDirections; + _strKey = strKey; + _strKeyDir = strKey + "_dir"; + _type = type; + _freezePlayer = freezePlayer; + _strResetKey = resetKey; + + _body = new BodyComponent(EntityPosition, 3, -13, 10, 10, 8) + { + IgnoreHeight = true, + IgnoreHoles = true, + }; + + // moves the stone + var movingTrigger = new AiTriggerCountdown(_moveTime, MoveTick, MoveEnd); + var movedState = new AiState { Init = InitMoved }; + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", new AiState()); + _aiComponent.States.Add("moving", new AiState { Trigger = { movingTrigger } }); + _aiComponent.States.Add("moved", movedState); + new AiFallState(_aiComponent, _body, null, null, 200); + _aiComponent.ChangeState("idle"); + + _box = new CBox(EntityPosition, collisionRectangle.X, collisionRectangle.Y, + collisionRectangle.Width, collisionRectangle.Height, 16); + + var sprite = Resources.GetSprite(spriteId); + + AddComponent(AiComponent.Index, _aiComponent); + if (moveDirections != 0) + AddComponent(BodyComponent.Index, _body); + AddComponent(PushableComponent.Index, new PushableComponent(_box, OnPush) { InertiaTime = 450 }); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(_box, Values.CollisionTypes.Normal | Values.CollisionTypes.Hookshot)); + AddComponent(DrawComponent.Index, new DrawSpriteComponent(spriteId, EntityPosition, new Vector2(0, -sprite.SourceRectangle.Height), layer)); + + if (!string.IsNullOrEmpty(_strResetKey)) + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + + // set the key + if (_type == 1 && _strKey != null) + Game1.GameManager.SaveManager.SetString(_strKey, "0"); + if (!string.IsNullOrEmpty(_strKeyDir)) + Game1.GameManager.SaveManager.SetString(_strKeyDir, "-1"); + } + + private void OnKeyChange() + { + // check if the block should be moved back to the start position + var keyState = Game1.GameManager.SaveManager.GetString(_strResetKey); + if (keyState == "1" && _aiComponent.CurrentStateId == "moved") + ResetToStart(); + } + + private void ResetToStart() + { + _isResetting = true; + _goalPosition = _startPosition; + _startPosition = EntityPosition.Position; + + _moveDirection = (_moveDirection + 2) % 4; + + if (!string.IsNullOrEmpty(_strKeyDir)) + Game1.GameManager.SaveManager.SetString(_strKeyDir, "-1"); + + ToMoving(); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact || + _aiComponent.CurrentStateId != "idle") + return false; + + if (_type == 1 && Game1.GameManager.StoneGrabberLevel <= 0) + return false; + + _moveDirection = AnimationHelper.GetDirection(direction); + + if (_allowedDirections != -1 && (_allowedDirections & (0x01 << _moveDirection)) == 0) + return false; + + // only move if there is nothing blocking the way + var pushVector = AnimationHelper.DirectionOffset[_moveDirection]; + var collidingRectangle = Box.Empty; + if (Map.Objects.Collision(new Box( + EntityPosition.X + pushVector.X * 16, + EntityPosition.Y + pushVector.Y * 16 - 16, 0, 16, 16, 16), + Box.Empty, Values.CollisionTypes.Normal, 0, 0, ref collidingRectangle)) + return true; + + _startPosition = EntityPosition.Position; + + _goalPosition = new Vector2( + _startPosition.X + pushVector.X * 16, + _startPosition.Y + pushVector.Y * 16); + + ToMoving(); + + if (!string.IsNullOrEmpty(_strResetKey)) + Game1.GameManager.SaveManager.SetString(_strResetKey, "0"); + + // set the key + if (_type == 1 && !string.IsNullOrEmpty(_strKey)) + Game1.GameManager.SaveManager.SetString(_strKey, "1"); + + if (_type == 1 && !string.IsNullOrEmpty(_strKeyDir)) + Game1.GameManager.SaveManager.SetString(_strKeyDir, _moveDirection.ToString()); + + return true; + } + + private void ToMoving() + { + Game1.GameManager.PlaySoundEffect("D378-17-11"); + _aiComponent.ChangeState("moving"); + } + + private void MoveTick(double time) + { + // the movement is fast in the beginning and slows down at the end + var amount = (float)Math.Sin((_moveTime - time) / _moveTime * (Math.PI / 2f)); + + Move(amount); + + if (!_isResetting && _freezePlayer) + MapManager.ObjLink.FreezePlayer(); + } + + private void MoveEnd() + { + // finished moving + Move(1); + + // set the key + if (_type == 0 && !string.IsNullOrEmpty(_strKey)) + Game1.GameManager.SaveManager.SetString(_strKey, "1"); + // set the direction key + if (_type == 0 && !string.IsNullOrEmpty(_strKeyDir)) + Game1.GameManager.SaveManager.SetString(_strKeyDir, _moveDirection.ToString()); + + if (_isResetting) + { + _isResetting = false; + _aiComponent.ChangeState("idle"); + } + else + _aiComponent.ChangeState("moved"); + + // can fall into holes after finishing the movement animation + _body.IgnoreHoles = false; + } + + private void InitMoved() + { + // fall into the water + if (_body.CurrentFieldState.HasFlag(MapStates.FieldStates.DeepWater)) + { + Game1.GameManager.PlaySoundEffect("D360-14-0E"); + + // spawn splash effect + var fallAnimation = new ObjAnimator(Map, + (int)(_body.Position.X + _body.OffsetX + _body.Width / 2.0f), + (int)(_body.Position.Y + _body.OffsetY + _body.Height - 2), + Values.LayerPlayer, "Particles/fishingSplash", "idle", true); + Map.Objects.SpawnObject(fallAnimation); + + Map.Objects.DeleteObjects.Add(this); + } + } + + private void Move(float amount) + { + var lastBox = _box.Box; + + EntityPosition.Set(Vector2.Lerp(_startPosition, _goalPosition, amount)); + + // @HACK: this kind of stuff should be inside the movement system + + // check for colliding bodies and push them forward + _collidingObjects.Clear(); + Map.Objects.GetComponentList(_collidingObjects, + (int)EntityPosition.Position.X, (int)EntityPosition.Position.Y - 16, 17, 17, BodyComponent.Mask); + + foreach (var collidingObject in _collidingObjects) + { + if (collidingObject is ObjMoveStone) + continue; + + var body = (BodyComponent)collidingObject.Components[BodyComponent.Index]; + + if (body.BodyBox.Box.Intersects(_box.Box) && !body.BodyBox.Box.Intersects(lastBox)) + { + var offset = Vector2.Zero; + if (_moveDirection == 0) + offset.X = _box.Box.Left - body.BodyBox.Box.Right - 0.05f; + else if (_moveDirection == 2) + offset.X = _box.Box.Right - body.BodyBox.Box.Left + 0.05f; + else if (_moveDirection == 1) + offset.Y = _box.Box.Back - body.BodyBox.Box.Front - 0.05f; + else if (_moveDirection == 3) + offset.Y = _box.Box.Front - body.BodyBox.Box.Back + 0.05f; + + SystemBody.MoveBody(body, offset, body.CollisionTypes, false, false, false); + body.Position.NotifyListeners(); + } + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjMovingPlatform.cs b/InGame/GameObjects/Things/ObjMovingPlatform.cs new file mode 100644 index 0000000..c8d828c --- /dev/null +++ b/InGame/GameObjects/Things/ObjMovingPlatform.cs @@ -0,0 +1,258 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Systems; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjMovingPlatform : GameObject + { + private readonly DrawSpriteComponent _spriteComponent; + private readonly List _collidingObjects = new List(); + + private readonly DictAtlasEntry _sprite; + + private readonly CBox _moveBox; + private Box _lastBox; + + private readonly CBox _collisionBox; + private Box _lastCollisionBox; + + private readonly Vector2 _startPosition; + private readonly Vector2 _endPosition; + + private Vector2 _newPosition; + + private float _waitCounter; + private float _state; + private float _dir; + private readonly int _time; + + private readonly int _mode; + + private bool _isStandingOnTop; + private bool _wasStandingOnTop; + private bool _isMoving; + + public ObjMovingPlatform() : base("moving_platform") { } + + public ObjMovingPlatform(Map.Map map, int posX, int posY, int offsetX, int offsetY, float state, int time, int mode) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 32, 16); + + _sprite = Resources.GetSprite("moving_platform"); + + _startPosition = new Vector2(posX, posY); + _endPosition = _startPosition + new Vector2(offsetX, offsetY); + + _state = (state / 2) * time; + _dir = state > time ? -1 : 1; + _time = time; + + _mode = mode; + + _moveBox = new CBox(EntityPosition, 0, -8, 0, 32, 16, 16); + _collisionBox = new CBox(EntityPosition, 0, 0, 32, 16, 16); + + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(_collisionBox, Values.CollisionTypes.Normal | Values.CollisionTypes.MovingPlatform)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, _spriteComponent = new DrawSpriteComponent( + Resources.SprObjects, EntityPosition, _sprite.SourceRectangle, Vector2.Zero, Values.LayerBottom)); + } + + private void Update() + { + _lastBox = _moveBox.Box; + _lastCollisionBox = _collisionBox.Box; + + if (_mode == 0) + UpdateMove0(); + else if (_mode == 1) + UpdateMode1(); + else if (_mode == 2) + UpdateMode2(); + + var bodyDirection = _newPosition - EntityPosition.Position; + + EntityPosition.Set(_newPosition); + + MoveBodies(bodyDirection); + } + + // normal moving platform + private void UpdateMove0() + { + // update the move or the wait counter + if (_waitCounter <= 0) + { + _state += (Game1.DeltaTime - _waitCounter) * _dir; + _waitCounter = 0; + } + else + _waitCounter -= Game1.DeltaTime; + + // finished moving to the start/end + if (_state < 0) + { + _dir = -_dir; + _state = 0; + _waitCounter = 175; + } + else if (_state > _time) + { + _dir = -_dir; + _state = _time; + _waitCounter = 175; + } + + var percentage = (float)(-Math.Cos((_state / _time) * Math.PI) + 1) * 0.5f; + _newPosition = Vector2.Lerp(_startPosition, _endPosition, percentage); + } + + // move to target if the player is standing on top of the plaform + private void UpdateMode1() + { + // is the player standing on the platform? + _isStandingOnTop = (_state == _time || (MapManager.ObjLink._body.BodyBox.Box.Left >= _moveBox.Box.Left && + MapManager.ObjLink._body.BodyBox.Box.Right < _moveBox.Box.Right)) && + MapManager.ObjLink._body.IsGrounded && + MapManager.ObjLink._body.BodyBox.Box.Intersects(_moveBox.Box); + + if (!_isMoving && _isStandingOnTop) + _isMoving = true; + + if (_isStandingOnTop) + { + _waitCounter = 500; + _dir = 1; + + if (!_wasStandingOnTop && _state < _time - 250) + Game1.GameManager.PlaySoundEffect("D378-17-11"); + } + + if (_isMoving) + { + if (_waitCounter <= 0 || _dir == 1) + _state += Game1.DeltaTime * _dir; + else + // wait a little bit and not move up directly after the player left the platform + _waitCounter -= Game1.DeltaTime; + } + + if (_state < 0) + { + _dir = -_dir; + _state = 0; + _isMoving = false; + } + else if (_state > _time) + { + _dir = -_dir; + _state = _time; + } + + var percentage = (float)(-Math.Cos((_state / _time) * Math.PI) + 1) * 0.5f; + _newPosition = Vector2.Lerp(_startPosition, _endPosition, percentage); + + _wasStandingOnTop = _isStandingOnTop; + } + + // only move if the player is standing on top and holding an object + private void UpdateMode2() + { + // is the player standing on the platform? + var intersection = MapManager.ObjLink._body.BodyBox.Box.Intersects(_moveBox.Box) && + MapManager.ObjLink._body.IsGrounded; + _isStandingOnTop = MapManager.ObjLink._body.BodyBox.Box.Left >= _moveBox.Box.Left && + MapManager.ObjLink._body.BodyBox.Box.Right < _moveBox.Box.Right && intersection; + + // set/unset the face + _spriteComponent.Sprite.SourceRectangle.Y = _sprite.SourceRectangle.Y + (intersection ? 16 : 0); + + // start moving if the player is standing on the platform and is carrying something + if (!_isMoving && _isStandingOnTop && MapManager.ObjLink.CurrentState == ObjLink.State.Carrying) + { + if (_state < _time) + Game1.GameManager.PlaySoundEffect("D378-17-11"); + _isMoving = true; + } + + if (_isMoving) + _state += Game1.DeltaTime; + + // finished moving down? + if (_state > _time) + { + _isMoving = false; + _state = _time; + } + + var percentage = (float)(-Math.Cos((_state / _time) * Math.PI) + 1) * 0.5f; + _newPosition = Vector2.Lerp(_startPosition, _endPosition, percentage); + } + + private void MoveBodies(Vector2 direction) + { + // check for colliding bodies and push them forward + _collidingObjects.Clear(); + Map.Objects.GetComponentList(_collidingObjects, + (int)_lastBox.Left, (int)_lastBox.Back - 8, (int)_lastBox.Width, (int)_lastBox.Height, BodyComponent.Mask); + + foreach (var collidingObject in _collidingObjects) + { + var body = (BodyComponent)collidingObject.Components[BodyComponent.Index]; + + if (body.BodyBox.Box.Front <= _lastCollisionBox.Back && body.BodyBox.Box.Intersects(_lastBox)) + { + var offset = Vector2.Zero; + + // body standing on the platform + if (body.IsGrounded) + { + var add = Vector2.Zero; + + // align the body with the platform so that the body is not wobbling around + if (Math.Abs(body.VelocityTarget.X) < 0.1f && Math.Abs(body.Velocity.X) < 0.1f) + { + var distance = (body.Position.X + direction.X) - EntityPosition.X; + var distanceNormal = (int)Math.Round(distance * MapManager.Camera.Scale, MidpointRounding.AwayFromZero) / MapManager.Camera.Scale; + + var dir = distanceNormal - distance; + if (Math.Abs(dir) > 0.005) + add.X += dir; + } + + offset = direction + add; + + // put the body on top of the platform + if (direction.Y != 0) + offset.Y = _collisionBox.Box.Back - body.BodyBox.Box.Front; + } + // did the platform already move into the body? + else if (body.BodyBox.Box.Intersects(_collisionBox.Box)) + { + // move the body up/down + if (direction.Y < 0) + offset.Y = _collisionBox.Box.Back - body.BodyBox.Box.Front - 0.05f; + else if (direction.Y > 0) + offset.Y = _collisionBox.Box.Back - body.BodyBox.Box.Front + 0.05f; + } + + if (offset != Vector2.Zero) + { + SystemBody.MoveBody(body, offset, body.CollisionTypes, false, false, false); + body.Position.NotifyListeners(); + } + } + } + } + } +} diff --git a/InGame/GameObjects/Things/ObjMusic.cs b/InGame/GameObjects/Things/ObjMusic.cs new file mode 100644 index 0000000..83421bd --- /dev/null +++ b/InGame/GameObjects/Things/ObjMusic.cs @@ -0,0 +1,21 @@ +using ProjectZ.InGame.GameObjects.Base; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjMusic : GameObject + { + private string _title; + + public ObjMusic() : base("editor music") { } + + public ObjMusic(Map.Map map, int posX, int posY, string title) : base(map) + { + _title = title; + + if (int.TryParse(_title, out var songNr)) + Map.MapMusic[0] = songNr; + + IsDead = true; + } + } +} diff --git a/InGame/GameObjects/Things/ObjMusicTile.cs b/InGame/GameObjects/Things/ObjMusicTile.cs new file mode 100644 index 0000000..f74e0e0 --- /dev/null +++ b/InGame/GameObjects/Things/ObjMusicTile.cs @@ -0,0 +1,46 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjMusicTile : GameObject + { + private string[,] _musicData; + private string _lastTrack; + + // @TODO: fade in/out + public ObjMusicTile() : base("editor music") { } + + public ObjMusicTile(Map.Map map, int posX, int posY) : base(map) + { + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + + _musicData = DataMapSerializer.LoadData(Values.PathContentFolder + "musicOverworld.data"); + } + + private void Update() + { + var position = new Point( + (int)(MapManager.ObjLink.PosX - Map.MapOffsetX * Values.TileSize) / 16, + (int)(MapManager.ObjLink.PosY - Map.MapOffsetY * Values.TileSize) / 16); + + if (0 <= position.X && position.X < _musicData.GetLength(0) && + 0 <= position.Y && position.Y < _musicData.GetLength(1)) + { + var track = _musicData[position.X, position.Y]; + + if (_lastTrack != track) + { + _lastTrack = track; + + if (int.TryParse(track, out var songNr)) + Game1.GameManager.SetMusic(songNr, 0, false); + } + } + } + } +} diff --git a/InGame/GameObjects/Things/ObjNote.cs b/InGame/GameObjects/Things/ObjNote.cs new file mode 100644 index 0000000..b961426 --- /dev/null +++ b/InGame/GameObjects/Things/ObjNote.cs @@ -0,0 +1,64 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.GameObjects.Things +{ + public class ObjNote : GameObject + { + private readonly CSprite _sprite; + private readonly Vector3 _startPosition; + private readonly Vector3 _endPosition; + private readonly Vector2 _moveDir; + + private float _counter; + private const int LiveTime = 1000; + + public ObjNote(Map.Map map, Vector2 position, int direction) : base(map) + { + EntityPosition = new CPosition(position.X, position.Y, 8); + EntitySize = new Rectangle(-4, -32, 8, 32); + + _startPosition = new Vector3(EntityPosition.X, EntityPosition.Y, EntityPosition.Z); + _endPosition = _startPosition + new Vector3(15 * direction, 0, 17); + + _moveDir = new Vector2(_endPosition.X, _endPosition.Y + _endPosition.Z) - + new Vector2(_startPosition.X, _startPosition.Y + _startPosition.Z); + _moveDir.Normalize(); + + _sprite = new CSprite("note", EntityPosition, Vector2.Zero); + _sprite.Color = Color.Transparent; + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerPlayer)); + } + + private void Update() + { + _counter += Game1.DeltaTime; + + // fade in/out + var transparency = 1.0f; + if (_counter > LiveTime - 100) + transparency = (LiveTime - _counter) / 100f; + else if (_counter < 100) + transparency = _counter / 100; + _sprite.Color = Color.White * transparency; + + // update the position + var percentage = _counter / LiveTime; + var newPosition = Vector3.Lerp(_startPosition, _endPosition, percentage); + EntityPosition.Set(newPosition); + + // offset to the sides + _sprite.DrawOffset = new Vector2(-3, -12) + _moveDir * (float)MathF.Sin(_counter * 0.015f) * 1.25f; + + // despawn + if (_counter > LiveTime) + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjObjectHider.cs b/InGame/GameObjects/Things/ObjObjectHider.cs new file mode 100644 index 0000000..50b54af --- /dev/null +++ b/InGame/GameObjects/Things/ObjObjectHider.cs @@ -0,0 +1,72 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.NPCs; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjObjectHider : GameObject + { + private readonly List _objectList = new List(); + private readonly Rectangle _hiddenField; + private bool _init; + + public ObjObjectHider() : base("editor object hider") { } + + public ObjObjectHider(Map.Map map, int posX, int posY) : base(map) + { + if (Game1.GameManager.HasMagnifyingLens) + { + IsDead = true; + return; + } + + _hiddenField = map.GetField(posX, posY); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + private void Update() + { + if (!_init) + { + _init = true; + + // if it was possible to edit the tags of gameobjects we could have a "hiden" tag and only get those objects + Map.Objects.GetComponentList(_objectList, _hiddenField.X, _hiddenField.Y, _hiddenField.Width, _hiddenField.Height, DrawComponent.Mask); + + SetVisibility(false); + } + + if (Game1.GameManager.HasMagnifyingLens) + { + SetVisibility(true); + Map.Objects.DeleteObjects.Add(this); + } + } + + private void SetVisibility(bool visibility) + { + foreach (GameObject gameObject in _objectList) + { + if (gameObject.Tags != Values.GameObjectTag.Enemy && + !(gameObject is ObjSprite) && + !(gameObject is ObjPersonNew)) + continue; + + // deactivate the person and the sprites + if (gameObject is ObjPersonNew || gameObject is ObjSprite) + { + gameObject.IsActive = visibility; + continue; + } + + if (gameObject.Components[DrawComponent.Index] != null) + ((DrawComponent)gameObject.Components[DrawComponent.Index]).IsActive = visibility; + if (gameObject.Components[DrawShadowComponent.Index] != null) + ((DrawShadowComponent)gameObject.Components[DrawShadowComponent.Index]).IsActive = visibility; + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjObjectRespawner.cs b/InGame/GameObjects/Things/ObjObjectRespawner.cs new file mode 100644 index 0000000..a2ab897 --- /dev/null +++ b/InGame/GameObjects/Things/ObjObjectRespawner.cs @@ -0,0 +1,111 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjObjectRespawner : GameObject + { + private GameObject _spawnedObject; + + private Box _spawnBox; + + private readonly string _strDisableKey; + private readonly string _strSpawnObjectId; + private readonly object[] _objParameter; + + private const int SpawnTime = 250; + private float _spawnCounter; + private bool _isActive = true; + + public ObjObjectRespawner() : base("editor object respawner") { } + + public ObjObjectRespawner(Map.Map map, int posX, int posY, string strDisableKey, string strSpawnObjectId, string strSpawnParameter) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + _spawnBox = new Box(posX, posY, 0, 16, 16, 8); + + _strDisableKey = strDisableKey; + _strSpawnObjectId = strSpawnObjectId; + string[] parameter = null; + if (strSpawnParameter != null) + { + parameter = strSpawnParameter.Split('.'); + // @HACK: some objects have stings with dots in them... + for (var i = 0; i < parameter.Length; i++) + parameter[i] = parameter[i].Replace("$", "."); + } + + _objParameter = MapData.GetParameter(strSpawnObjectId, parameter); + if (_objParameter != null) + { + _objParameter[1] = posX; + _objParameter[2] = posY; + } + + if (_strSpawnObjectId == null) + { + IsDead = true; + return; + } + + // add key change listener + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + if (!string.IsNullOrEmpty(_strDisableKey)) + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + + OnKeyChange(); + SpawnObject(); + } + + private void OnKeyChange() + { + if (string.IsNullOrEmpty(_strDisableKey)) + return; + + var state = Game1.GameManager.SaveManager.GetString(_strDisableKey, "0"); + _isActive = state != "1"; + } + + private void Update() + { + if (!_isActive || (_spawnedObject != null && _spawnedObject.Map != null)) + { + _spawnCounter = SpawnTime; + return; + } + + _spawnCounter -= Game1.DeltaTime; + if (_spawnCounter > 0) + return; + + // return if there is something there + var outBox = Box.Empty; + if (Map.Objects.Collision(_spawnBox, Box.Empty, Values.CollisionTypes.Normal | Values.CollisionTypes.Player, 0, 0, ref outBox)) + { + _spawnCounter = SpawnTime * 0.25f; + return; + } + + SpawnObject(); + + Game1.GameManager.PlaySoundEffect("D360-15-0F"); + + // spawn explosion effect + Map.Objects.SpawnObject(new ObjAnimator(Map, (int)EntityPosition.X, (int)EntityPosition.Y, Values.LayerTop, "Particles/spawn", "run", true)); + } + + private void SpawnObject() + { + _spawnedObject = ObjectManager.GetGameObject(Map, _strSpawnObjectId, _objParameter); + Map.Objects.SpawnObject(_spawnedObject); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjObjectSpawner.cs b/InGame/GameObjects/Things/ObjObjectSpawner.cs new file mode 100644 index 0000000..98d2b64 --- /dev/null +++ b/InGame/GameObjects/Things/ObjObjectSpawner.cs @@ -0,0 +1,95 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjObjectSpawner : GameObject + { + private readonly GameObject _spawnObject; + + private readonly string _strKey; + private readonly string _strValue; + private readonly string _strSpawnObjectId; + private readonly object[] _objParameter; + + private readonly bool _canDespawn; + private bool _isSpawned; + + public ObjObjectSpawner() : base("editor object spawner") { } + + public ObjObjectSpawner(Map.Map map, int posX, int posY, string strKey, string strValue, string strSpawnObjectId, string strSpawnParameter, bool canDespawn = true) : base(map) + { + _strKey = strKey; + _strValue = string.IsNullOrEmpty(strValue) ? "0" : strValue; + + _strSpawnObjectId = strSpawnObjectId; + string[] parameter = null; + if (strSpawnParameter != null) + { + parameter = strSpawnParameter.Split('.'); + // @HACK: some objects have stings with dots in them... + for (var i = 0; i < parameter.Length; i++) + parameter[i] = parameter[i].Replace("$", "."); + } + + _canDespawn = canDespawn; + + _objParameter = MapData.GetParameter(strSpawnObjectId, parameter); + if (_objParameter != null) + { + _objParameter[1] = posX; + _objParameter[2] = posY; + } + + if (_strSpawnObjectId != null) + _spawnObject = ObjectManager.GetGameObject(map, _strSpawnObjectId, _objParameter); + + if (_spawnObject == null) + { + IsDead = true; + return; + } + + // spawn object deactivated + Map.Objects.SpawnObject(_spawnObject); + + // add key change listener + if (!string.IsNullOrEmpty(_strKey)) + { + _spawnObject.IsActive = false; + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + } + } + + private void KeyChanged() + { + var value = Game1.GameManager.SaveManager.GetString(_strKey, "0"); + + if (!_isSpawned && value == _strValue) + { + // activate the object + _spawnObject.IsActive = true; + + _isSpawned = true; + + // remove the spawner if it does not despawn the object + if (!_canDespawn) + Map.Objects.DeleteObjects.Add(this); + } + else if (_isSpawned && value != _strValue) + { + // despawn the object + if (_canDespawn) + _spawnObject.IsActive = false; + else + Map.Objects.DeleteObjects.Add(_spawnObject); + + _isSpawned = false; + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjOnHitKeySetter.cs b/InGame/GameObjects/Things/ObjOnHitKeySetter.cs new file mode 100644 index 0000000..2934a96 --- /dev/null +++ b/InGame/GameObjects/Things/ObjOnHitKeySetter.cs @@ -0,0 +1,48 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjOnHitKeySetter : GameObject + { + private readonly string _strKey; + private readonly HitType _weaponType; + + public ObjOnHitKeySetter() : base("signpost_0") { } + + public ObjOnHitKeySetter(Map.Map map, int posX, int posY, string strKey, int weaponType, bool reset, int width, int height) : base(map) + { + if (string.IsNullOrEmpty(strKey)) + { + IsDead = true; + return; + } + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, width, height); + + _strKey = strKey; + _weaponType = (HitType)weaponType; + + if (reset) + Game1.GameManager.SaveManager.SetString(_strKey, "0"); + + var box = new CBox(EntityPosition, 0, 0, width, height, 16); + AddComponent(HittableComponent.Index, new HittableComponent(box, OnHit)); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + if((type & _weaponType) != 0) + { + Game1.GameManager.SaveManager.SetString(_strKey, "1"); + Map.Objects.DeleteObjects.Add(this); + } + + return Values.HitCollision.None; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjOnHitShellSpawner.cs b/InGame/GameObjects/Things/ObjOnHitShellSpawner.cs new file mode 100644 index 0000000..d6bb356 --- /dev/null +++ b/InGame/GameObjects/Things/ObjOnHitShellSpawner.cs @@ -0,0 +1,69 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Dungeon; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjOnDashSpawner : GameObject + { + private readonly string _saveKey; + private readonly string _itemName; + + public ObjOnDashSpawner() : base("signpost_0") { } + + public ObjOnDashSpawner(Map.Map map, int posX, int posY, string strKey, string itemName) : base(map) + { + _saveKey = strKey; + + if (!string.IsNullOrEmpty(_saveKey) && + Game1.GameManager.SaveManager.GetString(_saveKey) == "1") + { + IsDead = true; + return; + } + + _itemName = itemName; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 32, 32); + + var box = new CBox(EntityPosition, 0, 0, 32, 32, 16); + AddComponent(HittableComponent.Index, new HittableComponent(box, OnHit)); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + if ((type & HitType.PegasusBootsPush) != 0) + { + SpawnItem(direction); + Map.Objects.DeleteObjects.Add(this); + } + + return Values.HitCollision.None; + } + + private void SpawnItem(Vector2 direction) + { + if(_itemName == "fairy") + { + var objFairy = new ObjDungeonFairy(Map, (int)EntityPosition.X + 16, (int)EntityPosition.Y + 12, 0); + Map.Objects.SpawnObject(objFairy); + return; + } + + // spawn the shell + var objItem = new ObjItem(Map, (int)EntityPosition.X + 8, (int)EntityPosition.Y + 12, null, _saveKey, _itemName, null); + if (objItem.IsDead) + return; + + objItem.EntityPosition.Z = 16; + var itemBody = (BodyComponent)objItem.Components[BodyComponent.Index]; + itemBody.Velocity = new Vector3(direction.X * 1.25f, direction.Y * 1.25f, 1.0f); + itemBody.DragAir = 0.95f; + Map.Objects.SpawnObject(objItem); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjOnPushDialog.cs b/InGame/GameObjects/Things/ObjOnPushDialog.cs new file mode 100644 index 0000000..534516d --- /dev/null +++ b/InGame/GameObjects/Things/ObjOnPushDialog.cs @@ -0,0 +1,48 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjOnPushDialog : GameObject + { + private readonly string _signText; + + public ObjOnPushDialog() : base("signpost_0") { } + + public ObjOnPushDialog(Map.Map map, int posX, int posY, string signText, int width, int height) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, width, height); + + _signText = signText; + + var box = new CBox(EntityPosition, 0, 0, width, height, 16); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(box, Values.CollisionTypes.Normal | Values.CollisionTypes.PushIgnore)); + AddComponent(PushableComponent.Index, new PushableComponent(box, OnPush)); + } + + public ObjOnPushDialog(Map.Map map, int posX, int posY, int width, int height, string signText) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, width, height); + + _signText = signText; + + var box = new CBox(EntityPosition, 0, 0, width, height, 16); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(box, Values.CollisionTypes.Normal | Values.CollisionTypes.PushIgnore)); + AddComponent(PushableComponent.Index, new PushableComponent(box, OnPush)); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (type == PushableComponent.PushType.Impact) + return false; + + Game1.GameManager.StartDialogPath(_signText); + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjOnPushKeySetter.cs b/InGame/GameObjects/Things/ObjOnPushKeySetter.cs new file mode 100644 index 0000000..c0bf197 --- /dev/null +++ b/InGame/GameObjects/Things/ObjOnPushKeySetter.cs @@ -0,0 +1,40 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjOnPushKeySetter : GameObject + { + private readonly string _strKey; + + public ObjOnPushKeySetter() : base("signpost_0") { } + + public ObjOnPushKeySetter(Map.Map map, int posX, int posY, string strKey, int inertiaTime, bool reset) : base(map) + { + if (string.IsNullOrEmpty(strKey)) + { + IsDead = true; + return; + } + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + _strKey = strKey; + + if (reset) + Game1.GameManager.SaveManager.SetString(_strKey, "0"); + + var box = new CBox(EntityPosition, 0, 0, 16, 16, 16); + AddComponent(PushableComponent.Index, new PushableComponent(box, OnPush) { InertiaTime = inertiaTime }); + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + Game1.GameManager.SaveManager.SetString(_strKey, "1"); + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjOverworld.cs b/InGame/GameObjects/Things/ObjOverworld.cs new file mode 100644 index 0000000..efb9a01 --- /dev/null +++ b/InGame/GameObjects/Things/ObjOverworld.cs @@ -0,0 +1,30 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjOverworld : GameObject + { + private readonly Vector2 _offset; + + public ObjOverworld() : base("editor overworld") { } + + public ObjOverworld(Map.Map map, int posX, int posY) : base(map) + { + map.IsOverworld = true; + _offset = new Vector2(posX, posY); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + public void Update() + { + // update the players position on the map + Game1.GameManager.SetMapPosition(new Point( + (int)(MapManager.ObjLink.PosX - _offset.X) / Values.FieldWidth, + (int)(MapManager.ObjLink.PosY - _offset.Y) / Values.FieldHeight)); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjOverworldTeleporter.cs b/InGame/GameObjects/Things/ObjOverworldTeleporter.cs new file mode 100644 index 0000000..7568f7c --- /dev/null +++ b/InGame/GameObjects/Things/ObjOverworldTeleporter.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjOverworldTeleporter : GameObject + { + public static Dictionary TeleporterDictionary = new Dictionary(); + + private readonly Rectangle _field; + private readonly int _teleporterId; + private bool _registred; + + public ObjOverworldTeleporter(Map.Map map, int posX, int posY, int teleporterId) : base(map) + { + SprEditorImage = Resources.SprWhite; + EditorIconSource = new Rectangle(0, 0, 16, 16); + EditorColor = Color.HotPink * 0.75f; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + _teleporterId = teleporterId; + if (_teleporterId < 0) + Console.WriteLine("Error: teleporter id needs to be bigger than -1"); + + _field = Map.GetField(posX, posY); + + var animator = AnimatorSaveLoad.LoadAnimator("Objects/holeTeleporter"); + animator.Play("idle"); + + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(animator, sprite, new Vector2(8, 8)); + + var collisionRectangle = new Rectangle(posX, posY, 16, 16); + AddComponent(ObjectCollisionComponent.Index, new ObjectCollisionComponent(collisionRectangle, OnCollision)); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(new CBox(posX + 1, posY + 1, 0, 14, 14, 16), Values.CollisionTypes.Hole)); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerBottom)); + + // clear the teleporter dictionary + TeleporterDictionary.Clear(); + } + + public override void Init() + { + // register the teleporter if it was already unlocked + if (Game1.GameManager.SaveManager.GetString("unlocked_teleporter_" + _teleporterId) == "1") + RegisterTeleporter(); + } + + public void SetNextTeleporterPosition() + { + // find the next teleporter + var minId = int.MaxValue; + var minBiggerId = int.MaxValue; + + foreach (var teleporter in TeleporterDictionary) + { + // find the next bigger teleporter + if (teleporter.Key > _teleporterId && teleporter.Key < minBiggerId) + minBiggerId = teleporter.Key; + // find the teleporter with the smallest id + if (teleporter.Key < minId && teleporter.Key >= 0) + minId = teleporter.Key; + } + + if (minBiggerId != int.MaxValue) + TeleporterDictionary[minBiggerId].SetPosition(); + else if (minId != int.MaxValue) + TeleporterDictionary[minId].SetPosition(); + else + SetPosition(); + } + + public void SetPosition() + { + MapManager.ObjLink.StartWorldTelportation(new Vector2(EntityPosition.X + 8, EntityPosition.Y + 38)); + } + + private void Update() + { + if (!_registred && _field.Contains(MapManager.ObjLink.EntityPosition.Position)) + { + RegisterTeleporter(); + UnlockTeleporter(); + } + } + + private void RegisterTeleporter() + { + _registred = true; + + // register object + if (!TeleporterDictionary.ContainsKey(_teleporterId)) + TeleporterDictionary.Add(_teleporterId, this); + else + Console.WriteLine("Error: teleporter with duplicate id " + _teleporterId); + } + + private void OnCollision(GameObject gameObject) + { + // unlock the teleporter + if (!_registred) + { + RegisterTeleporter(); + UnlockTeleporter(); + } + + MapManager.ObjLink.HoleTeleporterId = _teleporterId; + } + + private void UnlockTeleporter() + { + Game1.GameManager.SaveManager.SetString("unlocked_teleporter_" + _teleporterId, "1"); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjPhotoFlash.cs b/InGame/GameObjects/Things/ObjPhotoFlash.cs new file mode 100644 index 0000000..b384c6e --- /dev/null +++ b/InGame/GameObjects/Things/ObjPhotoFlash.cs @@ -0,0 +1,64 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjPhotoFlash : GameObject + { + private Rectangle _rectangle; + + private float _flashTime = 125; + private float _percentage = 1; + private bool _fullScreen; + + public ObjPhotoFlash(Map.Map map) : base(map) + { + _rectangle = new Rectangle(0, 0, Map.MapWidth * Values.TileSize, Map.MapHeight * Values.TileSize); + + // on the overworld we use a fullscreen flash + if (map.MapWidth >= 4 || map.MapHeight >= 4) + _fullScreen = true; + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerTop, new CPosition(0, 0, 0))); + AddComponent(LightDrawComponent.Index, new LightDrawComponent(DrawLight)); + } + + public override void Init() + { + Game1.GameManager.PlaySoundEffect("D378-63-40"); + } + + private void Update() + { + _flashTime -= Game1.DeltaTime; + if (_flashTime > 0) + return; + + _percentage -= Game1.TimeMultiplier * 0.075f; + if (_percentage < 0) + Map.Objects.DeleteObjects.Add(this); + } + + private void Draw(SpriteBatch spriteBatch) + { + if (_fullScreen) + spriteBatch.Draw(Resources.SprWhite, MapManager.Camera.GetGameView(), Color.White * _percentage); + else + spriteBatch.Draw(Resources.SprWhite, _rectangle, Color.White * _percentage); + } + + private void DrawLight(SpriteBatch spriteBatch) + { + if (_fullScreen) + spriteBatch.Draw(Resources.SprWhite, MapManager.Camera.GetGameView(), Color.White * _percentage); + else + spriteBatch.Draw(Resources.SprWhite, _rectangle, Color.White * _percentage); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjPickupAnimation.cs b/InGame/GameObjects/Things/ObjPickupAnimation.cs new file mode 100644 index 0000000..f48787c --- /dev/null +++ b/InGame/GameObjects/Things/ObjPickupAnimation.cs @@ -0,0 +1,75 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjPickupAnimation : GameObject + { + private Rectangle _sourceRectangle0 = new Rectangle(66, 258, 12, 12); + private Rectangle _sourceRectangle1 = new Rectangle(80, 256, 16, 16); + + private double _counter; + private int _state; + + public ObjPickupAnimation(Map.Map map, float posX, float posY) : base(map) + { + SprEditorImage = Resources.SprItem; + EditorIconSource = new Rectangle(64, 168, 16, 16); + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(-29, -29, 58, 58); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + } + + private void Update() + { + if (_state == 0) + { + if (_counter > 380) + { + _state = 1; + _counter = 0; + } + } + else if (_state == 1) + { + if (_counter > 66) + { + _state = 2; + _counter = 0; + } + } + else if (_state == 2) + { + if (_counter > 116) + Map.Objects.DeleteObjects.Add(this); + } + + _counter += Game1.DeltaTime; + } + + private void Draw(SpriteBatch spriteBatch) + { + if (_state == 0) + { + for (var y = 0; y < 2; y++) + for (var x = 0; x < 2; x++) + { + var distance = (float)(23 * (1 - _counter / 380)); + var position = EntityPosition.Position + new Vector2(x * 2 - 1, y * 2 - 1) * distance + new Vector2(-6, -6); + spriteBatch.Draw(Resources.SprItem, position, _sourceRectangle0, Color.White); + } + } + else if (_state == 1) + spriteBatch.Draw(Resources.SprItem, EntityPosition.Position + new Vector2(-6, -6), _sourceRectangle0, Color.White); + else if (_state == 2) + spriteBatch.Draw(Resources.SprItem, EntityPosition.Position + new Vector2(-8, -8), _sourceRectangle1, Color.White); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjPositionDialog.cs b/InGame/GameObjects/Things/ObjPositionDialog.cs new file mode 100644 index 0000000..9e3348b --- /dev/null +++ b/InGame/GameObjects/Things/ObjPositionDialog.cs @@ -0,0 +1,68 @@ +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjPositionDialog : GameObject + { + public static Map.Map CurrentMap; + + private readonly GameObject _spawnObject; + + private readonly string _strKey; + private readonly string _strValue; + + private bool _isSpawned; + + public ObjPositionDialog() : base("editor position dialog") { } + + public ObjPositionDialog(Map.Map map, int posX, int posY, string strKey, string strValue, string dialogName) : base(map) + { + _strKey = strKey; + _strValue = strValue; + + CurrentMap = map; + Game1.GameManager.SaveManager.SetInt(dialogName + "posX", posX); + Game1.GameManager.SaveManager.SetInt(dialogName + "posY", posY); + + _spawnObject = new ObjDialogBox(map, posX, posY, dialogName); + + // spawn object deactivated + Map.Objects.SpawnObject(_spawnObject); + _spawnObject.IsActive = false; + + // add key change listener + if (!string.IsNullOrEmpty(_strKey)) + { + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + // if we spawn a door we need to use this here for objects refering to the player enter position in the init method + KeyChanged(); + } + else + { + _spawnObject.IsActive = true; + IsDead = true; + } + } + + //public override void Init() + //{ + // KeyChanged(); + //} + + private void KeyChanged() + { + var value = Game1.GameManager.SaveManager.GetString(_strKey); + + if (!_isSpawned && value == _strValue) + { + // activate the object + _spawnObject.IsActive = true; + + _isSpawned = true; + + Map.Objects.DeleteObjects.Add(this); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjPowder.cs b/InGame/GameObjects/Things/ObjPowder.cs new file mode 100644 index 0000000..14a5342 --- /dev/null +++ b/InGame/GameObjects/Things/ObjPowder.cs @@ -0,0 +1,110 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjPowder : GameObject + { + private Rectangle _sourceRectangle = new Rectangle(1, 145, 4, 4); + + private Vector3[] _points = new Vector3[3]; + private Vector3[] _velocity = new Vector3[3]; + private float[] _live = new float[3]; + + private float _gravity = -0.05f; + private bool _damage; + + public ObjPowder(Map.Map map, float posX, float posY, float posZ, bool playerPowder) : base(map) + { + EntityPosition = new CPosition(posX, posY, posZ); + EntitySize = new Rectangle(-8, -16, 16, 16); + + _points[0] = new Vector3(posX, posY, posZ + 7); + _points[1] = new Vector3(posX - 1, posY, posZ + 6); + _points[2] = new Vector3(posX + 1, posY, posZ + 6); + + _velocity[0] = new Vector3(0, 0, 0); + _velocity[1] = new Vector3(-Game1.RandomNumber.Next(50, 150) / 1000f, 0, 0); + _velocity[2] = new Vector3(Game1.RandomNumber.Next(50, 150) / 1000f, 0, 0); + + _live[0] = 1; + _live[1] = 1; + _live[2] = 1; + + // play sound effect + if (playerPowder) + Game1.GameManager.PlaySoundEffect("D360-05-05", true); + else + _damage = true; + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + AddComponent(LightDrawComponent.Index, new LightDrawComponent(DrawLight)); + } + + public void Update() + { + var finishedFalling = true; + + for (var i = 0; i < _points.Length; i++) + { + if (_points[i].Z <= 3 && !_damage) + { + // deals damage + _damage = true; + Map.Objects.Hit(this, new Vector2(EntityPosition.X, EntityPosition.Y), + new Box(EntityPosition.X - 3, EntityPosition.Y - 8, 0, 6, 10, 8), + HitType.MagicPowder, 2, false, false); + } + + // finished falling + if (_points[i].Z <= 0) + { + _points[i].Z = 0; + _live[i] -= 0.1f * Game1.TimeMultiplier; + } + else + { + _points[i] += _velocity[i] * Game1.TimeMultiplier; + _velocity[i].Z += _gravity * Game1.TimeMultiplier; + } + + if (_live[i] > 0) + finishedFalling = false; + else + _live[i] = 0; + } + + // remove object from the map + if (finishedFalling) + { + Map.Objects.DeleteObjects.Add(this); + } + } + + public void Draw(SpriteBatch spriteBatch) + { + for (var i = 0; i < _points.Length; i++) + { + spriteBatch.Draw(Resources.SprItem, new Vector2( + _points[i].X - _sourceRectangle.Width / 2, + _points[i].Y - _sourceRectangle.Height - _points[i].Z), _sourceRectangle, Color.White * _live[i]); + } + } + + public void DrawLight(SpriteBatch spriteBatch) + { + // draw shadow + for (var i = 0; i < _points.Length; i++) + { + DrawHelper.DrawLight(spriteBatch, new Rectangle( + (int)_points[i].X - 12, (int)(_points[i].Y - _points[i].Z) - 2 - 12, 24, 24), new Color(255, 220, 220) * 0.125f * _live[i]); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjPullBridge.cs b/InGame/GameObjects/Things/ObjPullBridge.cs new file mode 100644 index 0000000..04dc2d2 --- /dev/null +++ b/InGame/GameObjects/Things/ObjPullBridge.cs @@ -0,0 +1,171 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjPullBridge : GameObject + { + private readonly DictAtlasEntry _spriteStart; + private readonly DictAtlasEntry _spriteMiddle; + private readonly DictAtlasEntry _spriteEnd; + private readonly DictAtlasEntry _spriteHook; + private readonly DictAtlasEntry _spriteRope; + private readonly DictAtlasEntry _spritePullBridge; + + private Vector2 _startPosition; + + private readonly string _strKey; + private float _state; + + private readonly int _min = 6; + private readonly int _max = 72; + + private readonly bool _up; + private bool _startedPulling; + private bool _finishedPulling; + + public ObjPullBridge(Map.Map map, int posX, int posY, string strKey, bool up) : base(map, "pull_bridge") + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, up ? 0 : -64, 16, 80); + + _strKey = strKey; + _up = up; + + _spritePullBridge = Resources.GetSprite("pull_bridge"); + _spriteStart = Resources.GetSprite("pull_bridge_start"); + _spriteMiddle = Resources.GetSprite("pull_bridge_middle"); + _spriteEnd = Resources.GetSprite("pull_bridge_end"); + _spriteHook = Resources.GetSprite("pull_bridge_hook"); + _spriteRope = Resources.GetSprite("pull_bridge_rope"); + + var box = new CBox(posX + 4, posY + 2, 0, 8, 12, 8); + + // was the bridge already pulled? + if (!string.IsNullOrEmpty(_strKey) && Game1.GameManager.SaveManager.GetString(_strKey) == "1") + FinishedPull(); + else + { + AddComponent(HittableComponent.Index, new HittableComponent(box, OnHit)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBottom, EntityPosition)); + } + + private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower) + { + var dir = AnimationHelper.GetDirection(direction); + + if (!_startedPulling && type == HitType.Hookshot) + { + // attacking from the wrong direction? + if(!(_up && dir == 1 || !_up && dir == 3)) + return Values.HitCollision.RepellingParticle; + + MapManager.ObjLink.Hookshot.HookshotPosition.AddPositionListener(typeof(ObjPullBridge), OnPositionChange); + + _startPosition = MapManager.ObjLink.Hookshot.HookshotPosition.Position; + _startedPulling = true; + + return Values.HitCollision.Blocking; + } + + return Values.HitCollision.None; + } + + private void OnPositionChange(CPosition newPosition) + { + var distance = _startPosition - newPosition.Position; + _state = Math.Clamp((distance.Length() + _min) / _max, 0, 1); + + if (_state >= 1) + FinishedPull(); + } + + private void Update() + { + if (_startedPulling && !_finishedPulling && !MapManager.ObjLink.Hookshot.IsMoving) + FinishedPull(); + + //_state = ((float)Math.Clamp(Math.Sin(Game1.TotalGameTime / 1000f) * 0.6f + 0.5f, 0, 1) * (_max - _min) + _min) / _max; + } + + private void FinishedPull() + { + _state = 1; + _finishedPulling = true; + MapManager.ObjLink.Hookshot.HookshotPosition.PositionChangedDict.Remove(typeof(ObjPullBridge)); + RemoveHoles(); + + if (!string.IsNullOrEmpty(_strKey)) + Game1.GameManager.SaveManager.SetString(_strKey, "1"); + } + + private void Draw(SpriteBatch spriteBatch) + { + var state = (int)Math.Floor((_state * _max) / 8); + + var startPosition = new Vector2(EntityPosition.Position.X + 8, EntityPosition.Position.Y + (_up ? 0 : 16)); + var position = startPosition; + var dir = _up ? 1 : -1; + + if (_state * _max <= _min) + { + spriteBatch.Draw(_spritePullBridge.Texture, new Vector2(position.X, position.Y + dir * 16), _spritePullBridge.ScaledRectangle, Color.White, + _up ? MathF.PI : 0, new Vector2(_spritePullBridge.ScaledRectangle.Width / 2f, 0), Vector2.One, SpriteEffects.None, 0); + return; + } + + if (state >= 9) + { + position.Y = startPosition.Y + (6 + _state * _max + 2) * dir; + spriteBatch.Draw(_spriteEnd.Texture, position, _spriteEnd.ScaledRectangle, Color.White, + _up ? MathF.PI : 0, new Vector2(_spriteEnd.ScaledRectangle.Width / 2f, 0), Vector2.One, SpriteEffects.None, 0); + } + else + { + position.Y = startPosition.Y + (6 + _state * _max - 4) * dir; + spriteBatch.Draw(_spriteRope.Texture, position, _spriteRope.ScaledRectangle, Color.White, + _up ? MathF.PI : 0, new Vector2(_spriteRope.ScaledRectangle.Width / 2f, 0), Vector2.One, SpriteEffects.None, 0); + } + + position = new Vector2(startPosition.X, startPosition.Y + (state * 8 + 6) * dir); + for (var y = 0; y < state; y++) + { + spriteBatch.Draw(_spriteMiddle.Texture, position, _spriteMiddle.ScaledRectangle, Color.White, + _up ? MathF.PI : 0, new Vector2(_spriteMiddle.ScaledRectangle.Width / 2f, 0), Vector2.One, SpriteEffects.None, 0); + position.Y -= 8 * dir; + } + + spriteBatch.Draw(_spriteStart.Texture, position, _spriteStart.ScaledRectangle, Color.White, + _up ? MathF.PI : 0, new Vector2(_spriteStart.ScaledRectangle.Width / 2f, 0), Vector2.One, SpriteEffects.None, 0); + + // draw the hook + if (state < 9) + { + position = startPosition; + position.Y = startPosition.Y + (6 + _state * _max + 5) * dir; + spriteBatch.Draw(_spriteHook.Texture, position, _spriteHook.ScaledRectangle, Color.White, + _up ? MathF.PI : 0, new Vector2(_spriteHook.ScaledRectangle.Width / 2f, 0), Vector2.One, SpriteEffects.None, 0); + } + } + + private void RemoveHoles() + { + var holeList = new List(); + Map.Objects.GetGameObjectsWithTag(holeList, Values.GameObjectTag.Hole, + (int)EntityPosition.X + EntitySize.X, (int)EntityPosition.Y + EntitySize.Y, EntitySize.Width - 1, EntitySize.Height - 1); + + Map.Objects.DeleteObjects.AddRange(holeList); + } + } +} diff --git a/InGame/GameObjects/Things/ObjPullLever.cs b/InGame/GameObjects/Things/ObjPullLever.cs new file mode 100644 index 0000000..8713573 --- /dev/null +++ b/InGame/GameObjects/Things/ObjPullLever.cs @@ -0,0 +1,172 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjPullLever : GameObject + { + private readonly DictAtlasEntry _dictLever; + private readonly DictAtlasEntry _dictLeverTop; + + // currently only supports one lever per map + public static float LeverState; + + private CPosition _position; + private Rectangle _field; + private Point _startPosition; + + private string _openStrKey; + + private const int MinLeverLength = 4; + private const int MaxLeverLength = 47; + private const float PullSpeed = 0.24f; + private readonly float RetractingSpeed; + private const float OpenSpeed = 0.25f; + + private float _length = MinLeverLength; // 4 - 47 + + private bool _isOpening; + private bool _isGrabbed; + private bool _wasPulled; + + public ObjPullLever() : base("pull_lever") { } + + public ObjPullLever(Map.Map map, int posX, int posY, float retractingSpeed, string openStrKey) : base(map) + { + _startPosition = new Point(posX + 8, posY); + + _position = new CPosition(posX + 8, posY + _length + 16, 0); + //EntitySize = new Rectangle(-8, -56, 16, 56); + + RetractingSpeed = retractingSpeed; + _openStrKey = openStrKey; + + LeverState = 1; + + _field = map.GetField(posX, posY, 12); + + _dictLever = Resources.GetSprite("pull_lever"); + _dictLeverTop = Resources.GetSprite("pull_lever_top"); + + var collisionBox = new CBox(_position, -2, -56, 0, 4, 54, 8); + + if (!string.IsNullOrEmpty(_openStrKey)) + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + AddComponent(CarriableComponent.Index, new CarriableComponent( + new CRectangle(_position, new Rectangle(-3, -4, 6, 2)), null, null, null) + { StartGrabbing = StartGrabbing, Pull = OnPull }); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(collisionBox, Values.CollisionTypes.Normal)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBottom, _position)); + } + + private void OnKeyChange() + { + var openState = Game1.GameManager.SaveManager.GetString(_openStrKey, "0"); + if (openState == "1") + { + _isOpening = true; + Game1.GameManager.SaveManager.SetString(_openStrKey, "0"); + } + } + + private void StartGrabbing() + { + if (MapManager.ObjLink.Direction != 1) + return; + + UpdatePlayerPosition(); + } + + private bool OnPull(Vector2 direction) + { + if (MapManager.ObjLink.Direction != 1) + return false; + + _isGrabbed = true; + + if (direction.X != 0 || direction.Y < 0) + return true; + + // play soundeffect on pull + if (!_wasPulled && direction.Y > 0) + Game1.GameManager.PlaySoundEffect("D378-17-11"); + _wasPulled = direction.Y > 0; + + _position.Move(direction * PullSpeed); + + _length = _position.Y - 16 - _startPosition.Y; + + if (_length > MaxLeverLength) + { + _length = MaxLeverLength; + _position.Set(new Vector2(_startPosition.X, _startPosition.Y + 16 + _length)); + } + + UpdateLeverState(direction.Y * (PullSpeed + 0.01f) * Game1.TimeMultiplier); + + UpdatePlayerPosition(); + + // this is used to not continuously play the pull animation + if (_length == MaxLeverLength) + return false; + + return true; + } + + private void UpdatePlayerPosition() + { + // set the position of the player + MapManager.ObjLink.EntityPosition.Set(new Vector2( + _position.X, _position.Y + MapManager.ObjLink.BodyRectangle.Height - 2)); + } + + private void UpdateLeverState(float offset) + { + LeverState += offset / (MaxLeverLength - MinLeverLength); + LeverState = Math.Clamp(LeverState, 0, 1); + } + + private void Update() + { + var insideRoom = _field.Contains(MapManager.ObjLink.EntityPosition.Position); + if (insideRoom) + _isOpening = false; + + if (_isOpening) + UpdateLeverState(OpenSpeed * Game1.TimeMultiplier); + else if (!_isGrabbed && insideRoom) + UpdateLeverState(-RetractingSpeed * Game1.TimeMultiplier); + + // move the lever back to the starting position + if (!_isGrabbed) + { + _position.Move(new Vector2(0, -RetractingSpeed)); + if (_position.Y < _startPosition.Y + 16 + MinLeverLength) + _position.Set(new Vector2(_startPosition.X, _startPosition.Y + 16 + MinLeverLength)); + + _length = _position.Y - 16 - _startPosition.Y; + } + + _isGrabbed = false; + } + + private void Draw(SpriteBatch spriteBatch) + { + // thing + spriteBatch.Draw(_dictLeverTop.Texture, + new Rectangle(_startPosition.X - 2, _startPosition.Y, 4, (int)_length + 1), _dictLeverTop.ScaledRectangle, Color.White); + + // pull thing + spriteBatch.Draw(_dictLever.Texture, + new Vector2(_position.X - 8, _position.Y - 16), _dictLever.ScaledRectangle, Color.White); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjQuicksand.cs b/InGame/GameObjects/Things/ObjQuicksand.cs new file mode 100644 index 0000000..188966f --- /dev/null +++ b/InGame/GameObjects/Things/ObjQuicksand.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjQuicksand : GameObject + { + private readonly List _collidingObjects = new List(); + + private readonly RectangleF _collisionBox; + private readonly Vector2 _direction; + private readonly int _mode; + + public ObjQuicksand() : base("rollband_0") { } + + public ObjQuicksand(Map.Map map, int posX, int posY, float dirX, float dirY, int mode) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + _direction = new Vector2(dirX, dirY); + // mode 0: quicksand + // mode 1: only move the raft + _mode = mode; + + // why was this not the full size? + //_collisionBox = new Rectangle(posX + 2, posY + 3, 12, 10); + _collisionBox = new Rectangle(posX, posY, 16, 16); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + private void Update() + { + // get and move the components colliding with the quicksand + _collidingObjects.Clear(); + Map.Objects.GetComponentList(_collidingObjects, + (int)_collisionBox.Left, (int)_collisionBox.Top, (int)_collisionBox.Width, (int)_collisionBox.Height, BodyComponent.Mask); + + foreach (var gameObject in _collidingObjects) + { + if (_mode == 1 && !(gameObject is ObjRaft)) + continue; + + var gameObjectBody = ((BodyComponent)gameObject.Components[BodyComponent.Index]); + if (gameObjectBody.IsActive && gameObjectBody.IsGrounded && + _collisionBox.Intersects(gameObjectBody.BodyBox.Box.Rectangle())) + { + if (gameObjectBody.AdditionalMovementVT == Vector2.Zero) + gameObjectBody.AdditionalMovementVT = gameObjectBody.LastAdditionalMovementVT; + + var distance = gameObjectBody.BodyBox.Box.Center - _collisionBox.Center; + var distanceMult = 2 - Math.Clamp(distance.Length() / 8f, 0, 2); + gameObjectBody.AdditionalMovementVT = Vector2.Lerp(gameObjectBody.AdditionalMovementVT, _direction, 0.125f * Game1.TimeMultiplier * distanceMult); + } + } + } + } +} diff --git a/InGame/GameObjects/Things/ObjRaccoonTeleporter.cs b/InGame/GameObjects/Things/ObjRaccoonTeleporter.cs new file mode 100644 index 0000000..23e2942 --- /dev/null +++ b/InGame/GameObjects/Things/ObjRaccoonTeleporter.cs @@ -0,0 +1,95 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameSystems; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjRaccoonTeleporter : GameObject + { + private readonly int _offsetX; + private readonly int _offsetY; + + private float _teleportTime; + private float _teleportCount; + + private float _fadeTime; + + private int _direction; + private int _mode; + private bool _isTeleporting; + + public ObjRaccoonTeleporter() : base("editor teleporter") + { + EditorColor = Color.Green * 0.5f; + } + + // mode 0: racoon + // mode 1: dungeon 6 + public ObjRaccoonTeleporter(Map.Map map, int posX, int posY, int offsetX, int offsetY, int width, int height, int mode) : base(map) + { + // TODO_End: the object lights up the scene so we cant set the EntitySize + //EntityPosition = new CPosition(posX, posY, 0); + //EntitySize = new Rectangle(0, 0, width, height); + + _offsetX = offsetX; + _offsetY = offsetY; + _mode = mode; + + _teleportTime = _mode == 0 ? 300 : 300; + _fadeTime = mode == 0 ? 200 : 250; + + AddComponent(ObjectCollisionComponent.Index, new ObjectCollisionComponent(new Rectangle(posX, posY, width, height), OnCollision)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + private void Update() + { + if (!_isTeleporting) + return; + + if (_mode == 0 || _mode == 1) + MapManager.ObjLink.FreezePlayer(); + + _teleportCount += Game1.DeltaTime * _direction; + if (_teleportCount >= _teleportTime) + { + _teleportCount = _teleportTime; + _direction = -1; + + // teleport the colliding player to the new position + MapManager.ObjLink.SetPosition(new Vector2( + MapManager.ObjLink.PosX + _offsetX * Values.TileSize, + MapManager.ObjLink.PosY + _offsetY * Values.TileSize)); + + var goalPosition = Game1.GameManager.MapManager.GetCameraTarget(); + MapManager.Camera.SoftUpdate(goalPosition); + } + + if (_direction < 0 && _teleportCount <= 0) + { + _isTeleporting = false; + } + + var transitionSystem = (MapTransitionSystem)Game1.GameManager.GameSystems[typeof(MapTransitionSystem)]; + transitionSystem.SetColorMode(_mode == 0 ? Color.White : Color.Black, MathHelper.Clamp(_teleportCount / _fadeTime, 0, 1), false); + } + + private void OnCollision(GameObject gameObject) + { + if (_isTeleporting) + return; + + _direction = 1; + _isTeleporting = true; + + if (_mode == 0) + { + Game1.GameManager.PlaySoundEffect("D360-30-1E"); + Game1.GameManager.SaveManager.SetString("raccoon_warning", "0"); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjRaft.cs b/InGame/GameObjects/Things/ObjRaft.cs new file mode 100644 index 0000000..bc372cf --- /dev/null +++ b/InGame/GameObjects/Things/ObjRaft.cs @@ -0,0 +1,276 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.GameObjects.Things +{ + public class ObjRaft : GameObject + { + public readonly BodyComponent Body; + + private readonly Animator _animator; + private readonly AiComponent _aiComponent; + //private readonly CRectangle _collisionRectangle; + + private Vector2 _startPosition; + private Vector2 _targetPosition; + + private float _jumpMoveTime; + private float _jumpTime; + private float _jumpCounter; + + private bool _isActive; + private bool _wasColliding; + private bool _wasMoved; + + public ObjRaft() : base("raft") { } + + public ObjRaft(Map.Map map, int posX, int posY, string strActivationKey) : base(map) + { + if (!string.IsNullOrEmpty(strActivationKey)) + { + var activationValue = Game1.GameManager.SaveManager.GetString(strActivationKey); + if (activationValue != null && activationValue == "1") + _isActive = true; + } + + var offsetY = -5; + EntityPosition = new CPosition(posX + 8, posY + 16 + offsetY + (_isActive ? 16 : 0), 0); + EntitySize = new Rectangle(-8, -16 - offsetY, 16, 16); + + //_collisionRectangle = new CRectangle(EntityPosition, new Rectangle(-4, -offsetY - 6, 8, 4)); + + Body = new BodyComponent(EntityPosition, -4, -offsetY - 14, 8, 10, 8) + { + IsActive = false, + IgnoreHeight = true, + IgnoreHoles = true, + IsSlider = true, + Gravity = -0.2f, + MoveCollision = OnMoveCollision, + CollisionTypes = Values.CollisionTypes.Normal | Values.CollisionTypes.RaftExit, + }; + + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", new AiState(UpdateIdle)); + _aiComponent.States.Add("moving", new AiState(UpdateMoving)); + _aiComponent.ChangeState("idle"); + + _animator = AnimatorSaveLoad.LoadAnimator("Objects/raft"); + _animator.Play(_isActive ? "water" : "idle"); + + var _sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(_animator, _sprite, new Vector2(-8, -offsetY - 15)); + + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BodyComponent.Index, Body); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerBottom)); + + AddComponent(CollisionComponent.Index, + new BoxCollisionComponent(new CBox(EntityPosition, -8, -16 - offsetY, -8, 16, 16, 8), Values.CollisionTypes.Normal)); + + if (!_isActive) + AddComponent(CollisionComponent.Index, new BoxCollisionComponent( + new CBox(EntityPosition, -8, -offsetY - 1, 16, 1, 8), Values.CollisionTypes.Normal | Values.CollisionTypes.ThrowWeaponIgnore)); + } + + public override void Init() + { + if (_isActive) + ToggleWater(); + } + + // toggle the water field state + private void ToggleWater() + { + var fieldX = (int)EntityPosition.X / 16; + var fieldY = (int)EntityPosition.Y / 16; + + var oldState = Map.GetFieldState(fieldX, fieldY); + Map.SetFieldState(fieldX, fieldY, oldState ^ MapStates.FieldStates.DeepWater); + } + + private void OnMoveCollision(Values.BodyCollision collision) + { + // align with the raft exit + var offset = Vector2.Zero; + if ((collision & Values.BodyCollision.Left) != 0) + offset.X -= 1; + if ((collision & Values.BodyCollision.Right) != 0) + offset.X += 1; + if ((collision & Values.BodyCollision.Top) != 0) + offset.Y -= 1; + if ((collision & Values.BodyCollision.Bottom) != 0) + offset.Y += 1; + + var box = Body.BodyBox.Box; + box.X += offset.X; + box.Y += offset.Y; + var outBox = Box.Empty; + Map.Objects.Collision(box, box, Values.CollisionTypes.RaftExit, 0, 0, ref outBox); + + if (outBox != Box.Empty) + { + var exitCenter = outBox.Center; + var direction = exitCenter - EntityPosition.Position; + var alignSpeed = 0.5f * Game1.TimeMultiplier; + var maxAlignDist = 6; + + // align horizontally or vertically + if ((collision & Values.BodyCollision.Vertical) != 0) + { + Body.AdditionalMovementVT = Vector2.Zero; + Body.LastAdditionalMovementVT = Vector2.Zero; + if (alignSpeed < Math.Abs(direction.X) && Math.Abs(direction.X) < maxAlignDist) + Body.SlideOffset.X = Math.Sign(direction.X) * alignSpeed; + else if (Math.Abs(direction.X) < maxAlignDist) + { + EntityPosition.Set(new Vector2(exitCenter.X, EntityPosition.Y)); + ExitRaft(); + } + } + else if ((collision & Values.BodyCollision.Horizontal) != 0) + { + Body.AdditionalMovementVT = Vector2.Zero; + Body.LastAdditionalMovementVT = Vector2.Zero; + if (alignSpeed < Math.Abs(direction.Y) && Math.Abs(direction.Y) < maxAlignDist) + Body.SlideOffset.Y = Math.Sign(direction.Y) * alignSpeed; + else if (Math.Abs(direction.Y) < maxAlignDist) + { + EntityPosition.Set(new Vector2(EntityPosition.X, exitCenter.Y)); + ExitRaft(); + } + } + } + } + + public void TargetVelocity(Vector2 direction) + { + var targetDir = direction - Body.VelocityTarget; + if (targetDir.Length() > 0.1f * Game1.TimeMultiplier) + { + targetDir.Normalize(); + Body.VelocityTarget += targetDir * 0.1f * Game1.TimeMultiplier; + } + else + { + Body.VelocityTarget = direction; + } + + _wasMoved = true; + } + + public void Jump(Vector2 targetPosition, int time) + { + targetPosition.Y -= 7; + _startPosition = EntityPosition.Position; + _targetPosition = targetPosition; + + var percentage = (targetPosition.Y - _startPosition.Y) / 80; + _jumpMoveTime = 150;// * percentage; + _jumpTime = 1000 * percentage; + _jumpCounter = 0; + + Body.IsActive = false; + Body.VelocityTarget = Vector2.Zero; + + MapManager.ObjLink._body.IsGrounded = false; + MapManager.ObjLink._body.IsActive = false; + } + + private void UpdateIdle() + { + var distance = MapManager.ObjLink.EntityPosition.Position - new Vector2(EntityPosition.X, EntityPosition.Y + 1); + var isColliding = Math.Abs(distance.X) <= 3 && Math.Abs(distance.Y) <= 1; + + if (_isActive && isColliding && !_wasColliding && MapManager.ObjLink.IsGrounded()) + EnterRaft(); + + _wasColliding = isColliding; + } + + private void UpdateMoving() + { + if (!_wasMoved) + TargetVelocity(Vector2.Zero); + _wasMoved = false; + + // jump + if (_jumpTime > 0) + { + var lastJumpCounter = _jumpCounter; + _jumpCounter += Game1.DeltaTime; + // finished jumping? + if (MapManager.ObjLink._body.IsGrounded || _jumpCounter > _jumpTime) + { + _jumpTime = 0; + EntityPosition.Set(_targetPosition); + Map.CameraTarget = null; + } + else + { + var percentage = MathHelper.Clamp(_jumpCounter / _jumpMoveTime, 0, 1); + + if (_jumpCounter <= _jumpMoveTime) + { + var percentageHeight = _jumpCounter / _jumpMoveTime; + var posZ = MathF.Sin(percentageHeight * MathF.PI * 0.5f); + EntityPosition.Z = posZ * 12 + percentage * (_targetPosition.Y - _startPosition.Y); + MapManager.ObjLink.EntityPosition.Z = posZ * 16 + percentage * (_targetPosition.Y - _startPosition.Y); + } + else if (lastJumpCounter <= _jumpMoveTime) + { + MapManager.ObjLink._body.IsActive = true; + Body.IsActive = true; + } + + Map.CameraTarget = new Vector2(MapManager.ObjLink.EntityPosition.X, MapManager.ObjLink.EntityPosition.Y - MapManager.ObjLink.EntityPosition.Z); + + var newPosition = Vector2.Lerp(_startPosition, _targetPosition, percentage); + EntityPosition.Set(newPosition); + } + } + } + + private void EnterRaft() + { + ToggleWater(); + + Body.IsActive = true; + Body.VelocityTarget = Vector2.Zero; + _aiComponent.ChangeState("moving"); + EntityPosition.AddPositionListener(typeof(ObjRaft), OnPositionChange); + + ((DrawComponent)Components[DrawComponent.Index]).Layer = Values.LayerPlayer; + + MapManager.ObjLink.StartRaftRiding(this); + } + + private void ExitRaft() + { + ToggleWater(); + + Body.IsActive = false; + Body.VelocityTarget = Vector2.Zero; + _aiComponent.ChangeState("idle"); + EntityPosition.RemovePositionListener(typeof(ObjRaft)); + + ((DrawComponent)Components[DrawComponent.Index]).Layer = Values.LayerBottom; + + MapManager.ObjLink.ExitRaft(); + } + + private void OnPositionChange(CPosition newPosition) + { + MapManager.ObjLink.SetPosition(new Vector2(newPosition.X, newPosition.Y + 1)); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjRollBand.cs b/InGame/GameObjects/Things/ObjRollBand.cs new file mode 100644 index 0000000..9f93080 --- /dev/null +++ b/InGame/GameObjects/Things/ObjRollBand.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjRollBand : GameObject + { + private readonly List _collidingObjects = new List(); + + private readonly Box _collisionBox; + private readonly Rectangle _sourceRectangle; + private readonly Vector2 _vecRollBand; + private readonly Point _drawPosition; + + private readonly float _direction; + private int _animationCount; + private int _animationSpeed = 100; + + public ObjRollBand() : base("rollband_0") { } + + public ObjRollBand(Map.Map map, int posX, int posY, int direction) : base(map) + { + _sourceRectangle = Resources.SourceRectangle("rollband_0"); + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + _drawPosition.X = posX + 8; + _drawPosition.Y = posY + 8; + + _direction = (float)(direction * Math.PI / 2f); + + _vecRollBand = AnimationHelper.DirectionOffset[(direction + 3) % 4] * 0.25f;// 10.0f / 60.0f; // 10 pixels/second + + _collisionBox = new Box(posX + 3, posY + 3, 0, 10, 10, 8); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBottom, EntityPosition)); + } + + public void Update() + { + _animationCount = ((int)(Game1.TotalGameTime) % (16 * _animationSpeed)) / _animationSpeed; + + // get and move the components colliding with the rollband + _collidingObjects.Clear(); + Map.Objects.GetComponentList(_collidingObjects, + (int)_collisionBox.Left, (int)_collisionBox.Back, (int)_collisionBox.Width, (int)_collisionBox.Height, BodyComponent.Mask); + + foreach (var gameObject in _collidingObjects) + { + var gameObjectBody = ((BodyComponent)gameObject.Components[BodyComponent.Index]); + if (_collisionBox.Contains(gameObjectBody.BodyBox.Box)) + gameObjectBody.AdditionalMovementVT = _vecRollBand; + } + } + + public void Draw(SpriteBatch spriteBatch) + { + var sourceY = -_animationCount % 16; + spriteBatch.Draw(Resources.SprObjects, new Rectangle( + _drawPosition.X, _drawPosition.Y, _sourceRectangle.Width, _sourceRectangle.Height), + new Rectangle(_sourceRectangle.X, _sourceRectangle.Y + sourceY, _sourceRectangle.Width, _sourceRectangle.Height), + Color.White, _direction, new Vector2(8, 8), SpriteEffects.None, 0); + } + } +} diff --git a/InGame/GameObjects/Things/ObjRollBandDungeon.cs b/InGame/GameObjects/Things/ObjRollBandDungeon.cs new file mode 100644 index 0000000..c3c4890 --- /dev/null +++ b/InGame/GameObjects/Things/ObjRollBandDungeon.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjRollBandDungeon : GameObject + { + private readonly List _collidingObjects = new List(); + + private readonly Box _collisionBox; + private readonly Rectangle _sourceRectangle; + private readonly Vector2 _vecRollBand; + private readonly Vector2 _drawPosition; + + private readonly float _direction; + private float _animationCount; + private float _animationSpeed = 60f / 5; + + public ObjRollBandDungeon() : base("rollband_1") { } + + public ObjRollBandDungeon(Map.Map map, int posX, int posY, int direction) : base(map) + { + _sourceRectangle = Resources.SourceRectangle("rollband_1"); + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + _drawPosition = new Vector2(posX + 8, posY + 8); + + _direction = (float)(direction * Math.PI / 2f); + + _vecRollBand = AnimationHelper.DirectionOffset[direction] * 1 / 5; + + var marginX = direction == 0 || direction == 2 ? 0 : 3; + var marginY = direction == 0 || direction == 2 ? 3 : 0; + _collisionBox = new Box(posX + marginX, posY + marginY, 0, 16 - marginX * 2, 16 - marginY * 2, 8); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBottom, EntityPosition)); + } + + private void Update() + { + _animationCount = (int)(Game1.TotalGameTime / 1000 * _animationSpeed) % 16; + + // get and move the components colliding with the rollband + _collidingObjects.Clear(); + Map.Objects.GetComponentList(_collidingObjects, + (int)_collisionBox.Left, (int)_collisionBox.Back, (int)_collisionBox.Width, (int)_collisionBox.Height, BodyComponent.Mask); + + foreach (var gameObject in _collidingObjects) + { + var gameObjectBody = ((BodyComponent)gameObject.Components[BodyComponent.Index]); + if (gameObjectBody.IsActive && gameObjectBody.IsGrounded && _collisionBox.Intersects(gameObjectBody.BodyBox.Box)) + if (gameObjectBody.LastAdditionalMovementVT == Vector2.Zero || + gameObjectBody.LastAdditionalMovementVT == _vecRollBand && ( + _vecRollBand.X != 0 && (gameObjectBody.LastVelocityCollision & Values.BodyCollision.Horizontal) == 0 || + _vecRollBand.Y != 0 && (gameObjectBody.LastVelocityCollision & Values.BodyCollision.Vertical) == 0) || + gameObjectBody.LastAdditionalMovementVT != _vecRollBand && ( + _vecRollBand.X != 0 && (gameObjectBody.LastVelocityCollision & Values.BodyCollision.Vertical) != 0 || + _vecRollBand.Y != 0 && (gameObjectBody.LastVelocityCollision & Values.BodyCollision.Horizontal) != 0)) + gameObjectBody.AdditionalMovementVT = _vecRollBand; + } + } + + private void Draw(SpriteBatch spriteBatch) + { + spriteBatch.Draw(Resources.SprObjects, _drawPosition, + new Rectangle(_sourceRectangle.X + (int)_animationCount % 16, _sourceRectangle.Y, 16, _sourceRectangle.Height), + Color.White, _direction, new Vector2(8, 8), Vector2.One, (_direction % 2) != 0 ? SpriteEffects.FlipVertically : SpriteEffects.None, 0); + } + } +} diff --git a/InGame/GameObjects/Things/ObjRollbandEdge.cs b/InGame/GameObjects/Things/ObjRollbandEdge.cs new file mode 100644 index 0000000..5caa387 --- /dev/null +++ b/InGame/GameObjects/Things/ObjRollbandEdge.cs @@ -0,0 +1,62 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjRollBandEdge : GameObject + { + private readonly List _collidingObjects = new List(); + private readonly Box _itemDetectionBox; + + private Box _collisionBox; + + public ObjRollBandEdge(Map.Map map, int posX, int posY) : base(map) + { + SprEditorImage = Resources.SprWhite; + EditorIconSource = new Rectangle(0, 0, 16, 16); + EditorColor = Color.Sienna * 0.5f; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 8); + + _collisionBox = new Box(posX, posY, 0, 16, 8, 8); + _itemDetectionBox = new Box(posX, posY, 0, 16, 10, 8); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(CollisionComponent.Index, new CollisionComponent(Collision)); + } + + public void Update() + { + // get and move the components colliding with the rollband + _collidingObjects.Clear(); + Map.Objects.GetComponentList(_collidingObjects, + (int)_itemDetectionBox.Left, (int)_itemDetectionBox.Back, (int)_itemDetectionBox.Width, (int)_itemDetectionBox.Height, BodyComponent.Mask); + + foreach (var gameObject in _collidingObjects) + { + var gameObjectBody = ((BodyComponent)gameObject.Components[BodyComponent.Index]); + if (_itemDetectionBox.Contains(gameObjectBody.BodyBox.Box)) + { + // stop moving and fall from the edge + gameObjectBody.AdditionalMovementVT = Vector2.Zero; + gameObjectBody.Position.Set(new Vector3( + gameObjectBody.Position.X, EntityPosition.Y + gameObjectBody.Height + 8, (EntityPosition.Y + gameObjectBody.Height + 8) - gameObjectBody.Position.Y)); + } + } + } + + private bool Collision(Box box, int dir, int level, ref Box collidingBox) + { + if (dir != 1 || !_collisionBox.Intersects(box)) return false; + + collidingBox = _collisionBox; + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjScriptOnTouch.cs b/InGame/GameObjects/Things/ObjScriptOnTouch.cs new file mode 100644 index 0000000..5e66645 --- /dev/null +++ b/InGame/GameObjects/Things/ObjScriptOnTouch.cs @@ -0,0 +1,53 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + public class ObjScriptOnTouch : GameObject + { + private readonly Box _collisionBox; + private readonly string _scriptName; + + private bool _wasColliding; + + public override bool IsActive + { + get => base.IsActive; + set + { + base.IsActive = value; + if (!value) + _wasColliding = false; + } + } + + public ObjScriptOnTouch() : base("editor script on touch") { } + + public ObjScriptOnTouch(Map.Map map, int posX, int posY, int width, int height, string scriptName) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, width, height); + + _collisionBox = new Box(posX, posY, 0, width, height, 32); + _scriptName = scriptName; + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + public void Update() + { + var colliding = MapManager.ObjLink._body.BodyBox.Box.Intersects(_collisionBox); + + // player just started colliding? + if (!_wasColliding && colliding) + Game1.GameManager.StartDialogPath(_scriptName); + + _wasColliding = colliding; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjShadowDisabler.cs b/InGame/GameObjects/Things/ObjShadowDisabler.cs new file mode 100644 index 0000000..087c7ba --- /dev/null +++ b/InGame/GameObjects/Things/ObjShadowDisabler.cs @@ -0,0 +1,19 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjShadowDisabler : GameObject + { + public ObjShadowDisabler() : base("editor shadow disabler") { } + + public ObjShadowDisabler(Map.Map map, int posX, int posY) : base(map) + { + EditorColor = Color.Red; + + Map.UseShadows = false; + + IsDead = true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjShadowSetter.cs b/InGame/GameObjects/Things/ObjShadowSetter.cs new file mode 100644 index 0000000..d309388 --- /dev/null +++ b/InGame/GameObjects/Things/ObjShadowSetter.cs @@ -0,0 +1,21 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjShadowSetter : GameObject + { + public ObjShadowSetter() : base("editor shadow setter") + { + EditorColor = Color.Red; + } + + public ObjShadowSetter(Map.Map map, int posX, int posY, float height, float rotation) : base(map) + { + Map.ShadowHeight = height; + Map.ShadowRotation = rotation; + + IsDead = true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjShellHouse.cs b/InGame/GameObjects/Things/ObjShellHouse.cs new file mode 100644 index 0000000..422dadf --- /dev/null +++ b/InGame/GameObjects/Things/ObjShellHouse.cs @@ -0,0 +1,193 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjShellHouse : GameObject + { + private readonly DictAtlasEntry _barSprite; + private readonly Animator _barAnimator; + + private bool _triggerEntryDialog; + private bool _triggerDialog; + + private float _barHeight = 16; + private int _shellCount; + private int _targetHeight; + private bool _fillBar; + + private float _soundCounter; + private float _partileCounter = 1250; + private bool _particle; + + private float _spawnCounter = 300; + private bool _spawnPresent; + + public ObjShellHouse() : base("shell_bar") { } + + public ObjShellHouse(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX, posY + 16, 0); + EntitySize = new Rectangle(0, -16, 16, 16); + + // already collected the sword + if (Game1.GameManager.SaveManager.GetString("hasSword2") == "1") + { + IsDead = true; + return; + } + + _barSprite = Resources.GetSprite("shell_bar"); + _barAnimator = AnimatorSaveLoad.LoadAnimator("Objects/shell_mansion_bar"); + + var objShells = Game1.GameManager.GetItem("shell"); + if (objShells != null) + { + _shellCount = objShells.Count; + _targetHeight = 16; + // the first 10 shells move the bar more + _targetHeight += (int)(MathHelper.Min(_shellCount, 10) / 5f * 32); + // the second 10 shells move the bar half as much + _targetHeight += (int)MathHelper.Max(0, (_shellCount - 10) / 10f * 32); + } + + if (objShells == null || objShells.Count == 0) + { + _triggerDialog = true; + _targetHeight = 0; + } + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBottom, EntityPosition)); + } + + private void Update() + { + var playerDistance = EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position; + if (!_triggerEntryDialog && playerDistance.X < 105) + { + _triggerEntryDialog = true; + Game1.GameManager.StartDialogPath("shell_mansion_entry"); + } + + if (!_triggerDialog && playerDistance.X < 66) + { + _fillBar = true; + _triggerDialog = true; + } + + if (_fillBar) + { + MapManager.ObjLink.FreezePlayer(); + + _soundCounter -= Game1.DeltaTime; + if (_soundCounter < 0) + { + _soundCounter += 150; + Game1.GameManager.PlaySoundEffect("D370-06-06"); + } + + // 2sec -> 16px + // 2000 / 16 = 125ms + var addValue = Game1.DeltaTime / 125 * 2; + if (_targetHeight > _barHeight + addValue) + { + _barHeight += addValue; + } + else + { + _fillBar = false; + _barHeight = _targetHeight; + + _particle = true; + + if (_shellCount == 20) + _barAnimator.Play("idle"); + + if (_shellCount == 5 || _shellCount == 10 || _shellCount == 20) + Game1.GameManager.PlaySoundEffect("D360-02-02"); + else + Game1.GameManager.PlaySoundEffect("D360-29-1D"); + + var objParticle0 = new ObjAnimator(Map, 0, 0, 0, 0, Values.LayerPlayer, "Particles/shell_mansion_particle", "idle", true); + objParticle0.Animator.CurrentAnimation.LoopCount = 1; + objParticle0.EntityPosition.Set(new Vector2((int)EntityPosition.X - 8, (int)EntityPosition.Y - (int)_barHeight + 7)); + Map.Objects.SpawnObject(objParticle0); + + var objParticle1 = new ObjAnimator(Map, 0, 0, 0, 0, Values.LayerPlayer, "Particles/shell_mansion_particle", "idle", true); + objParticle1.Animator.CurrentAnimation.LoopCount = 1; + objParticle1.EntityPosition.Set(new Vector2((int)EntityPosition.X + 16 + 8, (int)EntityPosition.Y - (int)_barHeight + 7)); + Map.Objects.SpawnObject(objParticle1); + } + } + + // wait a little bit while showing the particles + if (_particle) + { + MapManager.ObjLink.FreezePlayer(); + + if (_partileCounter > 0) + _partileCounter -= Game1.DeltaTime; + else + { + _particle = false; + if (_shellCount == 5 || _shellCount == 10) + { + _spawnPresent = true; + + Game1.GameManager.PlaySoundEffect("D378-12-0C"); + + var objExplosion = new ObjAnimator(Map, 0, 0, 0, 0, Values.LayerBottom, "Particles/explosionBomb", "run", true); + objExplosion.EntityPosition.Set(new Vector2((int)EntityPosition.X - 48, (int)EntityPosition.Y - 64)); + Map.Objects.SpawnObject(objExplosion); + } + else if (_shellCount == 20) + { + Game1.GameManager.StartDialogPath("shell_mansion_sword"); + } + else + { + Game1.GameManager.StartDialogPath("shell_mansion_nothing"); + } + } + } + + if (_spawnPresent) + { + if (_spawnCounter > 0) + _spawnCounter -= Game1.DeltaTime; + else + { + _spawnPresent = false; + + var objItem = new ObjItem(Map, 0, 0, null, null, "shellPresent", null); + objItem.EntityPosition.Set(new Vector2((int)EntityPosition.X - 48, (int)EntityPosition.Y - 56)); + Map.Objects.SpawnObject(objItem); + } + } + + if (_barAnimator.IsPlaying) + _barAnimator.Update(); + } + + private void Draw(SpriteBatch spriteBatch) + { + // draw the animated bar + if (_barAnimator.IsPlaying) + { + for (int i = 1; i < 8; i++) + _barAnimator.Draw(spriteBatch, new Vector2(EntityPosition.X, EntityPosition.Y - 16 * i), Color.White); + } + else + { + spriteBatch.Draw(_barSprite.Texture, new Rectangle((int)EntityPosition.X, (int)EntityPosition.Y - (int)_barHeight, 16, (int)_barHeight), _barSprite.ScaledRectangle, Color.White); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjShoreSound.cs b/InGame/GameObjects/Things/ObjShoreSound.cs new file mode 100644 index 0000000..c2aa915 --- /dev/null +++ b/InGame/GameObjects/Things/ObjShoreSound.cs @@ -0,0 +1,36 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using System; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjShoreSound : GameObject + { + private readonly int _positionY; + private float _shoreTimer; + + public ObjShoreSound() : base("editor shore sound") { } + + public ObjShoreSound(Map.Map map, int posX, int posY) : base(map) + { + _positionY = posY; + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + private void Update() + { + if (MapManager.ObjLink.PosY < _positionY) + return; + + _shoreTimer += Game1.DeltaTime; + + if (_shoreTimer > 2000) + { + _shoreTimer -= 2000; + Game1.GameManager.PlaySoundEffect("D378-15-0F", true, new Vector2(MathF.Min(160 * 5.5f, MapManager.ObjLink.PosX), _positionY + 200)); + } + } + } +} diff --git a/InGame/GameObjects/Things/ObjSignpost.cs b/InGame/GameObjects/Things/ObjSignpost.cs new file mode 100644 index 0000000..d50a431 --- /dev/null +++ b/InGame/GameObjects/Things/ObjSignpost.cs @@ -0,0 +1,48 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjSignpost : GameObject + { + private readonly string _signText; + private readonly int _direction; + + public ObjSignpost() : base("signpost_0") { } + + public ObjSignpost(Map.Map map, int posX, int posY, string signText, string spriteId, Rectangle interactionRectangle, int direction) : base(map) + { + _signText = signText; + _direction = direction; + + EntityPosition = new CPosition(posX + 8, posY + 16, 0); + EntitySize = new Rectangle(-8, -16, 16, 16); + + var interactBox = new CBox( + posX + interactionRectangle.X, posY + interactionRectangle.Y, 0, + interactionRectangle.Width, interactionRectangle.Height, 16); + AddComponent(InteractComponent.Index, new InteractComponent(interactBox, OnInteract)); + + if (string.IsNullOrEmpty(spriteId)) + return; + + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(interactBox, Values.CollisionTypes.Normal)); + AddComponent(DrawComponent.Index, new DrawSpriteComponent(spriteId, EntityPosition, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new DrawShadowSpriteComponent(spriteId, EntityPosition)); + } + + private bool OnInteract() + { + if (_direction >= 0 && MapManager.ObjLink.Direction != _direction) + return false; + + Game1.GameManager.StartDialogPath(_signText); + + return true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjSlow.cs b/InGame/GameObjects/Things/ObjSlow.cs new file mode 100644 index 0000000..d864c8f --- /dev/null +++ b/InGame/GameObjects/Things/ObjSlow.cs @@ -0,0 +1,36 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjSlow : GameObject + { + private readonly float _slowdownPercentage; + + public ObjSlow() : base("editor slow") + { + EditorColor = Color.Orange * 0.5f; + } + + public ObjSlow(Map.Map map, int posX, int posY, float slowdownPercentage) : base(map) + { + _slowdownPercentage = slowdownPercentage; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + AddComponent(ObjectCollisionComponent.Index, + new ObjectCollisionComponent(new Rectangle(posX, posY, 16, 12), OnCollision)); + } + + private void OnCollision(GameObject gameObject) + { + // slow the player down while he is standing on this area + // could be made more general and slow down all bodies that are touching the area + MapManager.ObjLink.SlowDown(_slowdownPercentage); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjSmallStone.cs b/InGame/GameObjects/Things/ObjSmallStone.cs new file mode 100644 index 0000000..ee5349d --- /dev/null +++ b/InGame/GameObjects/Things/ObjSmallStone.cs @@ -0,0 +1,102 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjSmallStone : GameObject + { + private readonly BodyComponent _bodyComponent; + private readonly BodyDrawShadowComponent _shadowComponent; + private readonly CSprite _sprite; + + private float _despawnCounter; + private readonly int _fadeOutTime = 75; + private readonly int _despawnTime = 150; + + private readonly bool _blueStone; + + public ObjSmallStone(Map.Map map, int posX, int posY, int posZ, Vector3 velocity, bool flipSprite = false, int despawnTime = 0) : base(map) + { + EntityPosition = new CPosition(posX, posY + 8, posZ); + EntitySize = new Rectangle(-4, -24, 8, 24); + + if (despawnTime > 0) + _despawnTime = despawnTime; + else + _despawnTime = Game1.RandomNumber.Next(225, 275); + + _bodyComponent = new BodyComponent(EntityPosition, -4, -8, 8, 8, 8) + { + CollisionTypes = Values.CollisionTypes.None, + Bounciness = 0.75f, + Gravity = -0.15f, + Gravity2D = 0.1f, + Drag = 0.5f, + DragAir = 1.0f, + MaxJumpHeight = 8, + IsGrounded = false, // this is needed for the MaxJumpHeight to work + Velocity = velocity, + MoveCollision = OnCollision + }; + + _blueStone = posZ > 32; + + var sourceRectangle = Resources.SourceRectangle(_blueStone ? "stone_particle_1" : "stone_particle"); + + _sprite = new CSprite(Resources.SprObjects, EntityPosition, sourceRectangle, new Vector2(-4, -8)); + _sprite.Color = Color.White; + _sprite.SpriteEffect = flipSprite ? SpriteEffects.FlipHorizontally : SpriteEffects.None; + + AddComponent(BodyComponent.Index, _bodyComponent); + if (_blueStone) + AddComponent(UpdateComponent.Index, new UpdateComponent(UpdateBounceDespawn)); + else + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, _blueStone ? Values.LayerPlayer : Values.LayerTop)); + AddComponent(DrawShadowComponent.Index, _shadowComponent = new BodyDrawShadowComponent(_bodyComponent, _sprite)); + } + + private void OnCollision(Values.BodyCollision collision) + { + // jump in a random direction + if (_blueStone && (collision & Values.BodyCollision.Floor) != 0) + { + _bodyComponent.Velocity.X = Game1.RandomNumber.Next(0, 11) / 5f - 1.0f; + _bodyComponent.Velocity.Y = Game1.RandomNumber.Next(0, 11) / 5f - 1.0f; + if (_bodyComponent.Velocity.Z > 2.0f) + _bodyComponent.Velocity.Z = 2.0f; + } + + // reflect of a wall + if ((collision & Values.BodyCollision.Horizontal) != 0) + _bodyComponent.Velocity.X = -_bodyComponent.Velocity.X * 0.25f; + if ((collision & Values.BodyCollision.Vertical) != 0) + _bodyComponent.Velocity.Y = -_bodyComponent.Velocity.Y * 0.25f; + } + + private void UpdateBounceDespawn() + { + if (_bodyComponent.Velocity.Z == 0 && _bodyComponent.IsGrounded) + { + Map.Objects.DeleteObjects.Add(this); + } + } + + private void Update() + { + _despawnCounter += Game1.DeltaTime; + + var transparency = (1 - (_despawnCounter - _despawnTime) / _fadeOutTime); + _sprite.Color = Color.White * transparency; + _shadowComponent.Transparency = transparency; + + // delete the object + if (_despawnCounter >= _despawnTime + _fadeOutTime) + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjSpikes.cs b/InGame/GameObjects/Things/ObjSpikes.cs new file mode 100644 index 0000000..0b69962 --- /dev/null +++ b/InGame/GameObjects/Things/ObjSpikes.cs @@ -0,0 +1,46 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjSpikes : GameObject + { + private readonly Animator _animator; + private readonly int _animationLength; + + public ObjSpikes() : base("spikes") { } + + public ObjSpikes(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + Tags = Values.GameObjectTag.Lamp; + + _animator = AnimatorSaveLoad.LoadAnimator("Objects/spikes"); + _animator.Play("idle"); + + _animationLength = _animator.GetAnimationTime(0, _animator.CurrentAnimation.Frames.Length); + + var sprite = new CSprite(EntityPosition); + + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(new CBox(posX + 2, posY + 2, 0, 12, 12, 2), HitType.Spikes, 2)); + AddComponent(BaseAnimationComponent.Index, new AnimationComponent(_animator, sprite, Vector2.Zero)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerBottom)); + } + + private void Update() + { + // @HACK: this is used to sync all the animations with the same length + // otherwise they would not be in sync if they did not get updated at the same time + _animator.SetFrame(0); + _animator.SetTime(Game1.TotalGameTime % _animationLength); + _animator.Update(); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjSpikes2D.cs b/InGame/GameObjects/Things/ObjSpikes2D.cs new file mode 100644 index 0000000..0a5c849 --- /dev/null +++ b/InGame/GameObjects/Things/ObjSpikes2D.cs @@ -0,0 +1,37 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjSpikes2D : GameObject + { + private readonly DamageFieldComponent _damageField; + + public ObjSpikes2D(Map.Map map, int posX, int posY) : base(map) + { + SprEditorImage = Resources.SprWhite; + EditorIconSource = new Rectangle(0, 0, 16, 16); + EditorColor = Color.Red; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + var box = new CBox(posX, posY + 10, 0, 16, 6, 8); + AddComponent(DamageFieldComponent.Index, _damageField = new DamageFieldComponent(box, HitType.Object, 2) + { + OnDamage = DamagePlayer + }); + } + + private bool DamagePlayer() + { + MapManager.ObjLink.InflictSpikeDamage2D(); + + return MapManager.ObjLink.HitPlayer(new Vector2(0, -1), _damageField.DamageType, _damageField.Strength, true); + } + } +} diff --git a/InGame/GameObjects/Things/ObjSprite.cs b/InGame/GameObjects/Things/ObjSprite.cs new file mode 100644 index 0000000..fa71bed --- /dev/null +++ b/InGame/GameObjects/Things/ObjSprite.cs @@ -0,0 +1,59 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + public class ObjSprite : GameObject + { + public CSprite Sprite; + + // sprite + shadow + public ObjSprite(Map.Map map, int posX, int posY, + string spriteId, Vector2 positionOffset, int layer, + string shadowSpriteId) : base(map, spriteId) + { + EntityPosition = new CPosition(posX + positionOffset.X, posY + positionOffset.Y, 0); + + var sprite = Resources.GetSprite(spriteId); + Sprite = new CSprite(sprite, EntityPosition); + EntitySize = new Rectangle(-(int)sprite.Origin.X, -(int)sprite.Origin.Y, Sprite.SourceRectangle.Width, Sprite.SourceRectangle.Height); + + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(Sprite, layer)); + + if (!string.IsNullOrEmpty(shadowSpriteId)) + { + var shadowSprite = Resources.GetSprite(shadowSpriteId); + AddComponent(DrawShadowComponent.Index, + new DrawShadowSpriteComponent(shadowSprite.Texture, EntityPosition, shadowSprite.ScaledRectangle, -shadowSprite.Origin)); + } + } + + // sprite + shadow + collision + public ObjSprite(Map.Map map, int posX, int posY, + string spriteId, Vector2 positionOffset, int layer, + string shadowSpriteId, + Rectangle collisionRectangle, Values.CollisionTypes collisionType) : this(map, posX, posY, spriteId, positionOffset, layer, shadowSpriteId) + { + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(new CBox(EntityPosition, + collisionRectangle.X, collisionRectangle.Y, 0, collisionRectangle.Width, collisionRectangle.Height, 16), collisionType)); + } + + // used for the chest + public ObjSprite(Map.Map map, int posX, int posY, Texture2D sprTexture, Rectangle sourceRectangle, Vector2 drawOffset, int layer) : base(map) + { + SprEditorImage = sprTexture; + EditorIconSource = sourceRectangle; + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle((int)drawOffset.X, (int)drawOffset.Y, sourceRectangle.Width, sourceRectangle.Height); + + Sprite = new CSprite(sprTexture, EntityPosition, sourceRectangle, drawOffset); + + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(Sprite, layer)); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjStone.cs b/InGame/GameObjects/Things/ObjStone.cs new file mode 100644 index 0000000..a9ab307 --- /dev/null +++ b/InGame/GameObjects/Things/ObjStone.cs @@ -0,0 +1,344 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Dungeon; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjStone : GameObject + { + private readonly BodyComponent _body; + private readonly BoxCollisionComponent _collisionComponent; + private readonly CarriableComponent _carriableComponent; + + private readonly CBox _upperBox; + private readonly CBox _lowerBox; + private readonly CBox _damageBox; + + private readonly Point _spawnPosition; + + private readonly string _spawnItem; + private readonly string _pickupKey; + private readonly string _dialogPath; + + private readonly bool _potMessage; + + private int _offsetY = 3; + + private bool _thrown; + private bool _isAlive = true; + private bool _damagePlayer; + private bool _isHeavy; + + public ObjStone(Map.Map map, int posX, int posY, string spriteId, string spawnItem, string pickupKey, string dialogPath, bool isHeavy, bool potMessage) : base(map, spriteId) + { + var sprite = Resources.GetSprite(spriteId); + + EntityPosition = new CPosition(posX + 8, posY + 16 - _offsetY, 0); + EntitySize = new Rectangle( + -sprite.SourceRectangle.Width / 2, _offsetY - sprite.SourceRectangle.Height * 2, sprite.SourceRectangle.Width, sprite.SourceRectangle.Height * 2 + 4); + + _spawnPosition = new Point(posX, posY + 2); + + _spawnItem = spawnItem; + _pickupKey = pickupKey; + _dialogPath = dialogPath; + + _isHeavy = isHeavy; + _potMessage = potMessage; + + _upperBox = new CBox(EntityPosition, -4, -8 + _offsetY, 0, 8, 8, 4, true); + _lowerBox = new CBox(EntityPosition, -4, -8 + _offsetY, 0, 8, 8, 4); + + _damageBox = new CBox(EntityPosition, -7, -14 + _offsetY, 0, 14, 14, 12, true); + + var height = map.Is2dMap ? 15 : 13; + var heightOffset = map.Is2dMap ? 0 : 2; + var collisionBox = new CBox(EntityPosition, -sprite.SourceRectangle.Width / 2, -height + _offsetY, 0, sprite.SourceRectangle.Width, height - heightOffset, 12, true); + _body = new BodyComponent(EntityPosition, -4, -8 + _offsetY, 8, 8, 12) + { + CollisionTypes = Values.CollisionTypes.Normal, + MoveCollision = OnCollision, + HoleAbsorb = OnHoleAbsorb, + DragAir = 1.0f, + Gravity = -0.125f, + IgnoreHeight = true + }; + + var cSprite = new CSprite(spriteId, EntityPosition, new Vector2(-sprite.SourceRectangle.Width / 2, -sprite.SourceRectangle.Height + _offsetY)); + + if (!string.IsNullOrEmpty(_dialogPath)) + AddComponent(PushableComponent.Index, new PushableComponent(collisionBox, OnPush) { InertiaTime = 50 }); + AddComponent(BodyComponent.Index, _body); + AddComponent(CarriableComponent.Index, _carriableComponent = new CarriableComponent( + new CRectangle(EntityPosition, new Rectangle( + -sprite.SourceRectangle.Width / 2, -13 + _offsetY, sprite.SourceRectangle.Width, 13)), CarryInit, CarryUpdate, CarryThrow) + { + IsHeavy = _isHeavy + }); + AddComponent(CollisionComponent.Index, _collisionComponent = new BoxCollisionComponent(collisionBox, Values.CollisionTypes.Normal | Values.CollisionTypes.Hookshot)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(cSprite, Values.LayerPlayer)); + AddComponent(DrawShadowComponent.Index, new BodyDrawShadowComponent(_body, cSprite)); + } + + public bool MakeFlyingStone() + { + // was already picked up? + if (!_isAlive || !_collisionComponent.IsActive) + return false; + + _body.IgnoresZ = true; + _collisionComponent.IsActive = false; + _carriableComponent.IsActive = false; + + var damageBox = new CBox(EntityPosition, -6, -13, 0, 12, 20, 8, true); + AddComponent(DamageFieldComponent.Index, new DamageFieldComponent(damageBox, HitType.Enemy, 3) { OnDamage = DamagePlayer }); + + // deal damage to the player + _damagePlayer = true; + + return true; + } + + private bool DamagePlayer() + { + if (MapManager.ObjLink.HitPlayer(_damageBox.Box, HitType.Enemy, 2)) + { + OnCollision(); + return true; + } + + return false; + } + + public void ThrowStone(Vector2 direction) + { + _thrown = true; + _body.VelocityTarget = direction; + _body.CollisionTypes = Values.CollisionTypes.None; + } + + public void LetGo() + { + _body.IgnoresZ = false; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType pushType) + { + if (pushType == PushableComponent.PushType.Impact) + return false; + + Game1.GameManager.StartDialogPath(_dialogPath); + + return false; + } + + private void Update() + { + if (!_thrown) + return; + + // this is used because the normal collision detection looks strang when throwing directly towards a lower wall + var outBox = Box.Empty; + if (!Map.Is2dMap && + Map.Objects.Collision(_upperBox.Box, Box.Empty, Values.CollisionTypes.Normal, 0, _body.Level, ref outBox) && + Map.Objects.Collision(_lowerBox.Box, Box.Empty, Values.CollisionTypes.Normal, 0, _body.Level, ref outBox)) + OnCollision(); + + if (_damagePlayer) + return; + + // TODO: find the right hittype with the correct amount of damage or create a extra one? + var hitCollision = Map.Objects.Hit(this, _damageBox.Box.Center, _damageBox.Box, HitType.ThrownObject, 2, false); + + // hit something? + if (hitCollision != Values.HitCollision.None && + hitCollision != Values.HitCollision.NoneBlocking) + { + OnCollision(); + } + } + + private Vector3 CarryInit() + { + if (_spawnItem != null) + { + // spawn item + var objItem = new ObjItem(Map, _spawnPosition.X, _spawnPosition.Y, "j", _pickupKey, _spawnItem, ""); + if (!objItem.IsDead) + Map.Objects.SpawnObject(objItem); + else if (_spawnItem == "fairy") + { + // spawn fairy + var objFairy = new ObjDungeonFairy(Map, (int)EntityPosition.X, (int)EntityPosition.Y, 0); + Map.Objects.SpawnObject(objFairy); + } + } + // @HACK: if we spawn an item we use the pickupKey as the item save key + // set the pickup key + else if (!string.IsNullOrEmpty(_pickupKey)) + Game1.GameManager.SaveManager.SetString(_pickupKey, "1"); + + // the stone was picked up + _collisionComponent.IsActive = false; + _body.IsActive = false; + // we ignore move collisions and use the update methode to get nicer looking collisions + if (!Map.Is2dMap) + _body.CollisionTypes = Values.CollisionTypes.None; + + return new Vector3(EntityPosition.X, EntityPosition.Y - _offsetY, EntityPosition.Z); + } + + private bool CarryUpdate(Vector3 newPosition) + { + EntityPosition.X = newPosition.X; + + if (!Map.Is2dMap) + { + EntityPosition.Y = newPosition.Y - _offsetY; + EntityPosition.Z = newPosition.Z; + } + else + { + EntityPosition.Y = newPosition.Y - _offsetY - newPosition.Z; + EntityPosition.Z = 0; + } + + EntityPosition.NotifyListeners(); + return true; + } + + private void CarryThrow(Vector2 velocity) + { + _thrown = true; + _body.IsGrounded = false; + _body.IsActive = true; + _body.Velocity = new Vector3(velocity.X, velocity.Y, 0) * 1.0f; + _body.Level = MapStates.GetLevel(MapManager.ObjLink._body.CurrentFieldState); + } + + private void OnCollision(Values.BodyCollision direction) + { + // not sure why we check for the floor collision + if ((direction & Values.BodyCollision.Floor) != 0 || (_thrown && Map.Is2dMap)) + OnCollision(); + } + + private void OnCollision() + { + if (!_isAlive) + return; + + if (_body.CurrentFieldState.HasFlag(MapStates.FieldStates.DeepWater)) + { + // spawn splash effect + var fallAnimation = new ObjAnimator(Map, + (int)(_body.Position.X + _body.OffsetX + _body.Width / 2.0f), + (int)(_body.Position.Y + _body.OffsetY + _body.Height / 2.0f), + Values.LayerPlayer, "Particles/fishingSplash", "idle", true); + Map.Objects.SpawnObject(fallAnimation); + } + else + { + if (_potMessage) + Game1.GameManager.StartDialogPath("break_pot"); + + Game1.GameManager.PlaySoundEffect(_isHeavy ? "D378-41-29" : "D378-09-09"); + + // spawn small particle stones + SpawnParticles(EntityPosition.ToVector3()); + if (_isHeavy) + SpawnParticles(new Vector3(EntityPosition.X, EntityPosition.Y, EntityPosition.Z + 12)); + } + + // remove the stone object from the map + Map.Objects.DeleteObjects.Add(this); + + _isAlive = false; + } + + // would be nicer if it would not directly absorb the stone + private void OnHoleAbsorb() + { + if (!_isAlive) + return; + + // remove the stone object from the map + Map.Objects.DeleteObjects.Add(this); + + // play sound effect + Game1.GameManager.PlaySoundEffect("D360-24-18"); + + var fallAnimation = new ObjAnimator(Map, 0, 0, Values.LayerBottom, "Particles/fall", "idle", true); + fallAnimation.EntityPosition.Set(new Vector2( + _body.Position.X + _body.OffsetX + _body.Width / 2.0f - 5, + _body.Position.Y + _body.OffsetY + _body.Height / 2.0f - 5)); + Map.Objects.SpawnObject(fallAnimation); + + _isAlive = false; + } + + private void SpawnParticles(Vector3 position) + { + var diff = 200f; + + var mult = 0.125f; + var bodyVelocity = new Vector3( + _body.Velocity.X * mult, _body.Velocity.Y * mult, 1.25f); + + if (Map.Is2dMap) + { + if ((_body.VelocityCollision & Values.BodyCollision.Horizontal) != 0) + bodyVelocity.X = -bodyVelocity.X * 0.5f; + if ((_body.VelocityCollision & Values.BodyCollision.Vertical) != 0) + bodyVelocity.Y = -bodyVelocity.Y * 0.5f; + } + + var rndMin = 50; + var rndMax = 75; + + Vector3 vector0; + Vector3 vector1; + Vector3 vector2; + Vector3 vector3; + + if (Map.Is2dMap) + { + bodyVelocity.Y = 0; + bodyVelocity.Z = 0; + rndMin = 55; + vector0 = new Vector3(-0.25f, -3, 0) * Game1.RandomNumber.Next(rndMin, rndMax) / diff; + vector1 = new Vector3(-0.75f, -2.75f, 0) * Game1.RandomNumber.Next(rndMin, rndMax) / diff; + vector2 = new Vector3(0.25f, -3, 0) * Game1.RandomNumber.Next(rndMin, rndMax) / diff; + vector3 = new Vector3(0.75f, -2.75f, 0) * Game1.RandomNumber.Next(rndMin, rndMax) / diff; + } + else + { + vector0 = new Vector3(-1, -1, 0) * Game1.RandomNumber.Next(rndMin, rndMax) / diff; + vector1 = new Vector3(-1, 0, 0) * Game1.RandomNumber.Next(rndMin, rndMax) / diff; + vector2 = new Vector3(1, -1, 0) * Game1.RandomNumber.Next(rndMin, rndMax) / diff; + vector3 = new Vector3(1, 0, 0) * Game1.RandomNumber.Next(rndMin, rndMax) / diff; + } + + vector0 += bodyVelocity; + vector1 += bodyVelocity; + vector2 += bodyVelocity; + vector3 += bodyVelocity; + + var stone0 = new ObjSmallStone(Map, (int)position.X - 2, (int)position.Y - 13 + _offsetY, (int)position.Z, vector0, true); + var stone1 = new ObjSmallStone(Map, (int)position.X - 1, (int)position.Y - 8 + _offsetY, (int)position.Z, vector1, true); + var stone2 = new ObjSmallStone(Map, (int)position.X + 3, (int)position.Y - 13 + _offsetY, (int)position.Z, vector2, false); + var stone3 = new ObjSmallStone(Map, (int)position.X + 2, (int)position.Y - 8 + _offsetY, (int)position.Z, vector3, false); + + Map.Objects.SpawnObject(stone0); + Map.Objects.SpawnObject(stone1); + Map.Objects.SpawnObject(stone2); + Map.Objects.SpawnObject(stone3); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjStoneSpawner.cs b/InGame/GameObjects/Things/ObjStoneSpawner.cs new file mode 100644 index 0000000..22951b1 --- /dev/null +++ b/InGame/GameObjects/Things/ObjStoneSpawner.cs @@ -0,0 +1,98 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjStoneSpawner : GameObject + { + private readonly ObjSprite[] _objSprites = new ObjSprite[4]; + private readonly DictAtlasEntry[] _stoneRectangleSource = new DictAtlasEntry[2]; + + private bool _isActive = true; + public override bool IsActive + { + set + { + for (var i = 0; i < _objSprites.Length; i++) + _objSprites[i].IsActive = value; + _isActive = value; + } + get => _isActive; + } + + private bool _hidden; + public bool Hidden + { + set + { + for (var i = 0; i < _objSprites.Length; i++) + _objSprites[i].IsActive = !value; + _hidden = value; + } + get => _hidden; + } + + private int _holeX; + private int _holeY; + + public ObjStoneSpawner() : base("small_stones") { } + + public ObjStoneSpawner(Map.Map map, int posX, int posY) : base(map) + { + _stoneRectangleSource[0] = Resources.GetSprite("small_stone_0"); + _stoneRectangleSource[1] = Resources.GetSprite("small_stone_1"); + + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + _holeX = posX / 16; + _holeY = posY / 16; + + var position = new Point(posX, posY); + + // spawn the four stones + // set the placement of the stones depending on the position of the spawner + var stoneCount = (position.X + position.Y) / (Values.TileSize * 2) % 2 * 2 + 1; + for (var i = 0; i < 4; i++) + { + // ... + var stoneIndex = (stoneCount & 0b10) >> 1; + stoneCount++; + var fieldX = i % 2 * 8; + var fieldY = i / 2 * 8; + + // deterministic offset of the stones depending on the position of the stone + // i really do not know if this is a good way of doing this... + var offsetIndex = (position.X + position.Y) / 8 + i; + var offsetX = offsetIndex % (8 - _stoneRectangleSource[stoneIndex].SourceRectangle.Width); + var offsetY = offsetIndex % (8 - _stoneRectangleSource[stoneIndex].SourceRectangle.Height); + var stonePosition = new Vector2(fieldX + offsetX, fieldY + offsetY); + var centerX = (int)(_stoneRectangleSource[stoneIndex].ScaledRectangle.Width / 2); + var strStoneSprite = "small_stone_" + stoneIndex; + + _objSprites[i] = new ObjSprite(Map, + position.X + (int)stonePosition.X + centerX, position.Y + 5 + (int)stonePosition.Y, + strStoneSprite, Vector2.Zero, Values.LayerPlayer, strStoneSprite); + + Map.Objects.SpawnObject(_objSprites[i]); + } + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + private void Update() + { + // hide rocks when there has been dug at the tile + if (!Hidden && Map.HoleMap != null && + Map.HoleMap.ArrayTileMap[_holeX, _holeY, 0] != -1) + Hidden = true; + if (Hidden && Map.HoleMap != null && + Map.HoleMap.ArrayTileMap[_holeX, _holeY, 0] == -1) + Hidden = false; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjStoreItem.cs b/InGame/GameObjects/Things/ObjStoreItem.cs new file mode 100644 index 0000000..3d00bd8 --- /dev/null +++ b/InGame/GameObjects/Things/ObjStoreItem.cs @@ -0,0 +1,152 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjStoreItem : GameObject + { + private readonly GameItem _item; + + private readonly Rectangle _sourceRectangle; + private readonly Vector2 _itemPosition; + + private readonly string _itemName; + private readonly int _itemPrice; + private readonly int _itemCount; + + private bool _holding; + + public ObjStoreItem() : base("item") { } + + public ObjStoreItem(Map.Map map, int posX, int posY, string itemName, int itemPrice, int count) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 32, 40); + + _itemPrice = itemPrice; + _itemCount = count; + + _itemName = itemName; + _item = Game1.GameManager.ItemManager[itemName]; + + if (_item == null) + { + IsDead = true; + return; + } + + if (_item.SourceRectangle.HasValue) + _sourceRectangle = _item.SourceRectangle.Value; + else + { + var baseItem = Game1.GameManager.ItemManager[_item.Name]; + _sourceRectangle = baseItem.SourceRectangle.Value; + } + + var countLength = _itemCount.ToString().Length; + var textWidth = _itemCount > 1 ? ItemDrawHelper.LetterWidth * countLength + countLength + 6 : 0; + + _itemPosition = new Vector2( + EntityPosition.X + 16 - (int)(_sourceRectangle.Width + textWidth) / 2, + EntityPosition.Y + 22 - _sourceRectangle.Height / 2); + + var interactRectangle = new CBox(posX, posY, 0, 32, 40, 16); + AddComponent(InteractComponent.Index, new InteractComponent(interactRectangle, Interact)); + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + AddComponent(DrawShadowComponent.Index, new DrawShadowComponent(DrawShadow)); + } + + private bool Interact() + { + if (!_holding) + { + if (MapManager.ObjLink.StoreItem != null) + return false; + + Game1.GameManager.SaveManager.SetString("itemShopItem", _itemName); + Game1.GameManager.SaveManager.SetString("itemShopPrice", _itemPrice.ToString()); + Game1.GameManager.SaveManager.SetString("itemShopCount", _itemCount.ToString()); + + MapManager.ObjLink.StartHoldingItem(_item); + } + else + { + + MapManager.ObjLink.StopHoldingItem(); + } + + Game1.GameManager.PlaySoundEffect("D360-19-13"); + + _holding = !_holding; + + return true; + } + + private void KeyChanged() + { + if (!_holding) + return; + + var value = Game1.GameManager.SaveManager.GetString("holdItem"); + var result = Game1.GameManager.SaveManager.GetString("result"); + + if (value == "0") + { + _holding = false; + MapManager.ObjLink.StopHoldingItem(); + + // the item was bought? + if (result != null && result == "0") + Map.Objects.DeleteObjects.Add(this); + } + } + + private void Draw(SpriteBatch spriteBatch) + { + if (_holding) + return; + + // draw the price of the item + var priceLength = _itemPrice.ToString().Length; + var textWidth = ItemDrawHelper.LetterWidth * priceLength + priceLength - 1; + ItemDrawHelper.DrawNumber(spriteBatch, + (int)(EntityPosition.X + 16 - textWidth / 2f), + (int)(EntityPosition.Y + 12 - ItemDrawHelper.LetterHeight), _itemPrice, priceLength, 1, Color.Black); + + if (_itemCount > 1) + { + spriteBatch.DrawString(Resources.GameFont, "x", + new Vector2( + (int)(_itemPosition.X + _sourceRectangle.Width), + (int)(EntityPosition.Y + 24 - ItemDrawHelper.LetterHeight)), Color.Black); + + var countLength = _itemCount.ToString().Length; + ItemDrawHelper.DrawNumber(spriteBatch, + (int)(_itemPosition.X + _sourceRectangle.Width + 7), + (int)(EntityPosition.Y + 25 - ItemDrawHelper.LetterHeight), _itemCount, countLength, 1, Color.Black); + } + + // draw the item + ItemDrawHelper.DrawItem(spriteBatch, _item, _itemPosition, Color.White, 1, true); + } + + private void DrawShadow(SpriteBatch spriteBatch) + { + if (_holding) + return; + + var baseItem = _item.SourceRectangle.HasValue ? _item : Game1.GameManager.ItemManager[_item.Name]; + var sourceRectangle = baseItem.SourceRectangle.Value; + + DrawHelper.DrawShadow(Resources.SprItem, _itemPosition, + sourceRectangle, sourceRectangle.Width, sourceRectangle.Height, + false, Map.ShadowHeight, Map.ShadowRotation, Color.White); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjSwordShot.cs b/InGame/GameObjects/Things/ObjSwordShot.cs new file mode 100644 index 0000000..6114fab --- /dev/null +++ b/InGame/GameObjects/Things/ObjSwordShot.cs @@ -0,0 +1,120 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjSwordShot : GameObject + { + private readonly CSprite _sprite; + private readonly BodyComponent _body; + private readonly CBox _damageBox; + + private readonly Vector2 _spawnPosition; + + private float _spawnCounter; + private const int SpawnTime = 10; + // ~ time to move from the left side of a room to the right + private const int DespawnTime = 500; + private const int FadeInTime = 15; + private const int FadeOutTime = 25; + + private const float MoveSpeed = 4; + + public ObjSwordShot(Map.Map map, Vector3 position, int direction) : base(map) + { + EntityPosition = new CPosition(position); + EntitySize = new Rectangle(-8, -8, 16, 16); + + _spawnPosition = new Vector2(position.X, position.Y); + _damageBox = new CBox(EntityPosition, -3, -3, 0, 6, 6, 8); + + _sprite = new CSprite("swordShot", EntityPosition) + { + Color = Color.Transparent, + Rotation = (direction - 1) * MathF.PI * 0.5f, + DrawOffset = -AnimationHelper.DirectionOffset[direction] * 4 + }; + + // offset the body to not collide with the wall if the player is standing next to one + var directionOffset = AnimationHelper.DirectionOffset[(direction + 1) % 4]; + _body = new BodyComponent(EntityPosition, -1 + (int)directionOffset.X * 2, -1 + (int)directionOffset.Y * 2, 2, 2, 8) + { + VelocityTarget = AnimationHelper.DirectionOffset[direction] * MoveSpeed, + MoveCollision = OnCollision, + IgnoreHoles = true, + IgnoresZ = true, + IgnoreInsideCollision = false, + Level = MapStates.GetLevel(MapManager.ObjLink._body.CurrentFieldState) + }; + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(BodyComponent.Index, _body); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition)); + } + + public override void Init() + { + Game1.GameManager.PlaySoundEffect("D360-59-3B"); + } + + public void Update() + { + _spawnCounter += Game1.DeltaTime; + + // only start showing the sprite after the spawn time + if (_spawnCounter > SpawnTime) + { + if (_spawnCounter > DespawnTime) + // fade out + _sprite.Color = Color.White * (1 - Math.Clamp((_spawnCounter - DespawnTime) / FadeOutTime, 0, 1)); + else + // fade in + _sprite.Color = Color.White * Math.Clamp((_spawnCounter - SpawnTime) / FadeInTime, 0, 1); + + if (_spawnCounter > DespawnTime + FadeOutTime) + { + Map.Objects.DeleteObjects.Add(this); + return; + } + } + + var collision = Map.Objects.Hit(this, EntityPosition.Position, _damageBox.Box, HitType.SwordShot, 2, false); + if ((collision & (Values.HitCollision.Blocking | Values.HitCollision.Enemy)) != 0) + Map.Objects.DeleteObjects.Add(this); + } + + private void Draw(SpriteBatch spriteBatch) + { + // draw the trail + var spawnDistance = (new Vector2(EntityPosition.X, EntityPosition.Y) - _spawnPosition).Length(); + var trailCount = 3; + var distMult = 1.5f; + for (int i = 0; i < trailCount; i++) + { + var drawPosition = new Vector2(EntityPosition.X, EntityPosition.Y) + _sprite.DrawOffset - new Vector2(_body.VelocityTarget.X, _body.VelocityTarget.Y) * (trailCount - i) * distMult; + // make sure to not show the tail behind the actual spawn position + if (spawnDistance > ((trailCount - i) * MoveSpeed * distMult)) + spriteBatch.Draw(_sprite.SprTexture, drawPosition, _sprite.SourceRectangle, _sprite.Color * (0.20f + 0.30f * ((i + 1) / (float)trailCount)), + _sprite.Rotation, _sprite.Center * _sprite.Scale, new Vector2(_sprite.Scale), SpriteEffects.None, 0); + } + + // draw the actual sprite + _sprite.Draw(spriteBatch); + } + + private void OnCollision(Values.BodyCollision collision) + { + var animation = new ObjAnimator(Map, (int)EntityPosition.X, (int)EntityPosition.Y - (int)EntityPosition.Z, + 0, 0, Values.LayerTop, "Particles/swordShotDespawn", "run", true); + Map.Objects.SpawnObject(animation); + + Map.Objects.DeleteObjects.Add(this); + } + } +} diff --git a/InGame/GameObjects/Things/ObjSwordSpawner.cs b/InGame/GameObjects/Things/ObjSwordSpawner.cs new file mode 100644 index 0000000..0f82f6d --- /dev/null +++ b/InGame/GameObjects/Things/ObjSwordSpawner.cs @@ -0,0 +1,176 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjSwordSpawner : GameObject + { + private Animator _animator; + private CSprite _sprite; + private SpriteShader _spriteShader; + + private ObjItem _objSword; + private BodyComponent _swordBody; + private bool _swordHitFloor; + + private DictAtlasEntry _thunder; + + private float _counter; + private int _thunderIndex; + private bool _drawThunder = true; + + private float _animationCounter; + private bool _animationStarted; + + private bool _spawnedSword; + + private float _thunderCounter; + private bool _soundEffect; + + public ObjSwordSpawner() : base("sword_spawn") { } + + public ObjSwordSpawner(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX + 8, posY + 8, 0); + EntitySize = new Rectangle(-8, -8, 16, 16); + + _animator = AnimatorSaveLoad.LoadAnimator("Objects/sword spawn"); + + _thunder = Resources.GetSprite("sword_thunder_0"); + + _sprite = new CSprite(EntityPosition); + + AddComponent(BaseAnimationComponent.Index, new AnimationComponent(_animator, _sprite, Vector2.Zero)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBottom, EntityPosition)); + } + + private void SpawnSword() + { + _spawnedSword = true; + _objSword = new ObjItem(Map, (int)EntityPosition.X - 8, (int)EntityPosition.Y, null, "sword2", "sword2", null); + ((DrawComponent)_objSword.Components[DrawComponent.Index]).IsActive = false; + _swordBody = ((BodyComponent)_objSword.Components[BodyComponent.Index]); + _swordBody.OffsetY -= 1; + _swordBody.Bounciness2D = 0.5f; + Map.Objects.SpawnObject(_objSword); + } + + private void Update() + { + _counter += Game1.DeltaTime; + _animationCounter += Game1.DeltaTime; + + if (!_spawnedSword) + { + MapManager.ObjLink.FreezePlayer(); + Game1.GameManager.InGameOverlay.DisableInventoryToggle = true; + } + + if (_animationCounter > 2200 && !_soundEffect) + { + _soundEffect = true; + Game1.GameManager.PlaySoundEffect("D370-30-1E"); + } + + if (_drawThunder) + { + _thunderCounter -= Game1.DeltaTime; + if (_thunderCounter < 0) + { + _thunderCounter += 66; + Game1.GameManager.PlaySoundEffect("D378-51-33"); + } + } + + if (_animationCounter > 2750 && !_animationStarted) + { + _animationStarted = true; + _animator.Play("idle"); + } + + if (_drawThunder && _animationCounter > 2750 + 4500) + { + _drawThunder = false; + _thunderIndex = -1; + } + + // finished playing? + if (_animationCounter > 2750 && !_animator.IsPlaying && !_spawnedSword) + { + SpawnSword(); + } + + _spriteShader = _counter % (AiDamageState.BlinkTime * 2) >= AiDamageState.BlinkTime ? Resources.DamageSpriteShader0 : null; + + if (_counter > AiDamageState.BlinkTime * 2) + { + _counter -= AiDamageState.BlinkTime * 2; + _thunderIndex += Game1.RandomNumber.Next(1, 4); + _thunderIndex %= 4; + } + + if (_objSword != null && !_swordHitFloor) + { + if (_swordBody.Velocity.Y < 0) + { + _swordHitFloor = true; + ((DrawComponent)_objSword.Components[DrawComponent.Index]).IsActive = true; + } + } + } + + private void Draw(SpriteBatch spriteBatch) + { + if (_spriteShader != null) + { + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, _spriteShader); + } + + // draw the blinking sword + if (_objSword != null && !_swordHitFloor) + _objSword.Draw(spriteBatch); + + if (_animator.IsPlaying) + _sprite.Draw(spriteBatch); + + if (_drawThunder) + { + if (_thunderIndex == 0) + { + spriteBatch.Draw(_thunder.Texture, new Vector2(EntityPosition.X, EntityPosition.Y), _thunder.ScaledRectangle, Color.White, 0, _thunder.Origin, _thunder.Scale, SpriteEffects.None, 0); + spriteBatch.Draw(_thunder.Texture, new Vector2(EntityPosition.X, EntityPosition.Y), _thunder.ScaledRectangle, Color.White, 0, Vector2.Zero, _thunder.Scale, SpriteEffects.FlipHorizontally | SpriteEffects.FlipVertically, 0); + } + else if (_thunderIndex == 1) + { + spriteBatch.Draw(_thunder.Texture, new Vector2(EntityPosition.X + 16, EntityPosition.Y), _thunder.ScaledRectangle, Color.White, 0, _thunder.Origin, _thunder.Scale, SpriteEffects.FlipVertically, 0); + spriteBatch.Draw(_thunder.Texture, new Vector2(EntityPosition.X - 16, EntityPosition.Y), _thunder.ScaledRectangle, Color.White, 0, Vector2.Zero, _thunder.Scale, SpriteEffects.FlipHorizontally, 0); + } + else if (_thunderIndex == 2) + { + spriteBatch.Draw(_thunder.Texture, new Vector2(EntityPosition.X + 16, EntityPosition.Y), _thunder.ScaledRectangle, Color.White, 0, _thunder.Origin, _thunder.Scale, SpriteEffects.FlipHorizontally | SpriteEffects.FlipVertically, 0); + spriteBatch.Draw(_thunder.Texture, new Vector2(EntityPosition.X - 16, EntityPosition.Y), _thunder.ScaledRectangle, Color.White, 0, Vector2.Zero, _thunder.Scale, SpriteEffects.None, 0); + } + else if (_thunderIndex == 3) + { + spriteBatch.Draw(_thunder.Texture, new Vector2(EntityPosition.X + 32, EntityPosition.Y), _thunder.ScaledRectangle, Color.White, 0, _thunder.Origin, _thunder.Scale, SpriteEffects.FlipHorizontally, 0); + spriteBatch.Draw(_thunder.Texture, new Vector2(EntityPosition.X - 32, EntityPosition.Y), _thunder.ScaledRectangle, Color.White, 0, Vector2.Zero, _thunder.Scale, SpriteEffects.FlipVertically, 0); + } + } + + if (_spriteShader != null) + { + spriteBatch.End(); + ObjectManager.SpriteBatchBegin(spriteBatch, null); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjTransition.cs b/InGame/GameObjects/Things/ObjTransition.cs new file mode 100644 index 0000000..aa1f361 --- /dev/null +++ b/InGame/GameObjects/Things/ObjTransition.cs @@ -0,0 +1,80 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjTransition : GameObject + { + public Color TransitionColor; + public float Percentage; + + public float Brightness; + public float WobblePercentage; + public bool WobbleTransition; + + private float _circleSize; + + public ObjTransition(Map.Map map) : base(map) + { + SprEditorImage = Resources.SprObjects; + EditorIconSource = new Rectangle(240, 16, 16, 16); + + // should be on top of every other object, + // except the player object but only while transitioning + AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerTop, new CPosition(0, 0, 0))); + } + + public void Draw(SpriteBatch spriteBatch) + { + var gameWidth = Game1.RenderWidth; + var gameHeight = Game1.RenderHeight; + + if (!WobbleTransition) + { + _circleSize = (1 - Percentage) * (float)Math.Sqrt(gameWidth * gameWidth + gameHeight * gameHeight) / 2; + + var playerPosition = new Vector2( + MapManager.ObjLink.PosX * MapManager.Camera.Scale, + (MapManager.ObjLink.PosY - 8 - MapManager.ObjLink.PosZ) * MapManager.Camera.Scale); + var centerX = gameWidth / 2.0f - (MapManager.Camera.Location.X - playerPosition.X); + var centerY = gameHeight / 2.0f - (MapManager.Camera.Location.Y - playerPosition.Y); + + Resources.CircleShader.Parameters["softRad"].SetValue(15f); + Resources.CircleShader.Parameters["size"].SetValue(_circleSize); + Resources.CircleShader.Parameters["centerX"].SetValue(centerX); + Resources.CircleShader.Parameters["centerY"].SetValue(centerY); + Resources.CircleShader.Parameters["width"].SetValue(gameWidth); + Resources.CircleShader.Parameters["height"].SetValue(gameHeight); + + // draw the circle + spriteBatch.Begin(SpriteSortMode.Immediate, null, SamplerState.PointWrap, null, null, Resources.CircleShader, Game1.GetMatrix); + spriteBatch.Draw(Resources.SprWhite, new Rectangle(0, 0, gameWidth, gameHeight), TransitionColor); + spriteBatch.End(); + } + else + { + // draw the wobble transition effect + Game1.GameManager.ChangeRenderTarget(); + + Resources.WobbleEffect.Parameters["width"].SetValue(gameWidth); + Resources.WobbleEffect.Parameters["height"].SetValue(gameHeight); + Resources.WobbleEffect.Parameters["scale"].SetValue(MapManager.Camera.Scale); + Resources.WobbleEffect.Parameters["brightness"].SetValue(Brightness); + + Resources.WobbleEffect.Parameters["offset"].SetValue(WobblePercentage * 30); + Resources.WobbleEffect.Parameters["offsetWidth"].SetValue((0.5f - MathF.Cos(WobblePercentage * 4) / 2) * 3); + Resources.WobbleEffect.Parameters["offsetHeight"].SetValue(16); + + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, Resources.WobbleEffect); + spriteBatch.Draw(Game1.GameManager.GetLastRenderTarget(), Vector2.Zero, Color.White); + spriteBatch.End(); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjUpperLevel.cs b/InGame/GameObjects/Things/ObjUpperLevel.cs new file mode 100644 index 0000000..125eee5 --- /dev/null +++ b/InGame/GameObjects/Things/ObjUpperLevel.cs @@ -0,0 +1,20 @@ +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.Map; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjUpperLevel : GameObject + { + // this object was created because some objects (hookshot, boomerang, arrow, etc.) care about the height + // the can be thrown down if the player is standing on top of the platform, but can't get thrown up the same platform if the player is standing on the bottom + // this was added late in the development but hopefully it still works good enough + + public ObjUpperLevel() : base("editor upper level") { } + + public ObjUpperLevel(Map.Map map, int posX, int posY, int level) : base(map) + { + Map.AddFieldState(posX / 16, posY / 16, level == 1 ? MapStates.FieldStates.Level1 : MapStates.FieldStates.Level2); + IsDead = true; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjWater.cs b/InGame/GameObjects/Things/ObjWater.cs new file mode 100644 index 0000000..2460fb4 --- /dev/null +++ b/InGame/GameObjects/Things/ObjWater.cs @@ -0,0 +1,57 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjWater : GameObject + { + public override bool IsActive + { + get { return _isActive; } + set + { + _isActive = value; + UpdateFieldState(); + } + } + private bool _isActive = true; + + private int fieldX; + private int fieldY; + + public ObjWater() : base("editor water") + { + EditorColor = Color.AliceBlue * 0.65f; + + } + + public ObjWater(Map.Map map, int posX, int posY, int depth) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + fieldX = posX / 16; + fieldY = posY / 16; + UpdateFieldState(); + + AddComponent(CollisionComponent.Index, + new BoxCollisionComponent(new CBox(posX, posY, -10 + depth, 16, 16, 10), Values.CollisionTypes.Normal)); + } + + private void UpdateFieldState() + { + if(_isActive) + Map.AddFieldState(fieldX, fieldY, MapStates.FieldStates.Water); + else + { + // remove the water state + var fieldState = Map.GetFieldState(fieldX, fieldY); + Map.SetFieldState(fieldX, fieldY, fieldState ^ MapStates.FieldStates.Water); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjWaterDeep.cs b/InGame/GameObjects/Things/ObjWaterDeep.cs new file mode 100644 index 0000000..390b727 --- /dev/null +++ b/InGame/GameObjects/Things/ObjWaterDeep.cs @@ -0,0 +1,32 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjWaterDeep : GameObject + { + public ObjWaterDeep() : base("editor water") + { + EditorColor = Color.CadetBlue * 0.65f; + } + + public ObjWaterDeep(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + Map.AddFieldState(posX / 16, posY / 16, MapStates.FieldStates.DeepWater); + + // step that goes down a little + AddComponent(CollisionComponent.Index, + new BoxCollisionComponent(new CBox(posX, posY, -12, 16, 16, 10), Values.CollisionTypes.Normal)); + + // collider that is used for enemies to avoid the deep water; currently this is 3 high to allow blocking a body but not jumping into it + map.Objects.SpawnObject(new ObjCollider(map, posX, posY, 3, new Rectangle(0, 0, 16, 16), Values.CollisionTypes.DeepWater, 0)); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjWaterfall.cs b/InGame/GameObjects/Things/ObjWaterfall.cs new file mode 100644 index 0000000..7d6675b --- /dev/null +++ b/InGame/GameObjects/Things/ObjWaterfall.cs @@ -0,0 +1,238 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjWaterfall : GameObject + { + private const string SW1 = "water1"; + private const string SW2 = "water2"; + private const string SWF = "waterFall"; + private const string SPW = "stoneSpawner"; + + private readonly string[,] _spawnObjects = { + { null, null, null, null, null, null, null, SW2, null }, + { null, SWF, null, null, null, null, null, SW2, SW2 }, + { null, SWF, null, null, null, SWF, null, SW2, SW2 }, + { SW1, SW1, SW1, SW1, SW1, SW1, SW1, SW2, SW2 }, + { null, null, SWF, SWF, SWF, null, null, SW1, SW2 }, + { null, null, SWF, SWF, SWF, null, null, null, null }, + { null, null, SWF, SWF, SWF, null, null, null, null }, + { null, null, SWF, SWF, SWF, null, null, null, null }, + { null, SW1, SW1, SW1, SW1, SW1, null, null, null }, + { null, SW1, SW1, SW1, SW1, SW1, null, null, null }, + { null, null, SW1, SW1, SW1, SW1, null, null, null }, + }; + + private readonly string[,] _stoneMap = { + { null, null, null, null, null, null, null, null, null }, + { null, null, null, null, null, null, null, null, null }, + { null, null, null, null, null, null, null, null, null }, + { null, SPW, null, null, SPW, SPW, null, null, null }, + { null, null, null, null, null, null, null, SPW, null }, + { null, null, null, null, null, null, null, null, null }, + { null, null, null, null, null, null, null, null, null }, + { null, null, null, null, null, null, null, null, null }, + { null, null, SPW, null, SPW, null, null, null, null }, + { null, null, null, null, null, SPW, null, null, null }, + { null, null, null, null, null, null, null, null, null }, + }; + + private readonly List _waterObjects = new List(); + + private readonly int[,] _despawnTime = + { + {0, 0, 0, 0, 0, 0, 0, 5, 0}, + {0, 1, 0, 0, 0, 0, 0, 5, 5}, + {0, 2, 0, 0, 0, 1, 0, 4, 5}, + {3, 3, 3, 3, 3, 3, 3, 4, 4}, + {0, 0, 5, 5, 5, 0, 0, 4, 4}, + {0, 0, 6, 6, 6, 0, 0, 0, 0}, + {0, 0, 7, 7, 7, 0, 0, 0, 0}, + {0, 0, 8, 8, 8, 0, 0, 0, 0}, + {0, 9, 9, 9, 9, 9, 0, 0, 0}, + {0, 11, 11, 10, 10, 10, 0, 0, 0}, + {0, 0, 11, 11, 11, 11, 0, 0, 0}, + }; + + private GameObject[,] _gameObjects; + private readonly Point _position; + + private readonly string _strKey; + + private float _despawnCounter; + private bool _isDespawning; + private bool _wasUpdated; + + public ObjWaterfall() : base("waterfall") { } + + public ObjWaterfall(Map.Map map, int posX, int posY, string strKey) : base(map) + { + _strKey = strKey; + _position = new Point(posX, posY); + + if (!string.IsNullOrEmpty(_strKey) && + Game1.GameManager.SaveManager.GetString(_strKey) == "1") + { + SpawnStones(); + IsDead = true; + return; + } + + SpawnObjects(new Vector2(posX, posY)); + + // add key change listener + if (!string.IsNullOrEmpty(_strKey)) + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged)); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + private void Update() + { + _wasUpdated = true; + + if (!_isDespawning) + return; + + MapManager.ObjLink.FreezePlayer(); + + _despawnCounter += Game1.DeltaTime; + var timeStep = _despawnCounter / 585f; + + DespawnObjects(timeStep); + + if (timeStep > 12) + { + // stop the music + Game1.GameManager.SetMusic(-1, 2); + + Map.Objects.DeleteObjects.Add(this); + } + } + + private void SpawnStones() + { + for (var y = 0; y < _stoneMap.GetLength(0); y++) + for (var x = 0; x < _stoneMap.GetLength(1); x++) + if (_stoneMap[y, x] != null) + { + var objStones = new ObjStoneSpawner(Map, _position.X + x * 16, _position.Y + y * 16); + Map.Objects.SpawnObject(objStones); + } + } + + private void SpawnObjects(Vector2 spawnPosition) + { + _gameObjects = new GameObject[_spawnObjects.GetLength(1), _spawnObjects.GetLength(0)]; + + for (var y = 0; y < _spawnObjects.GetLength(0); y++) + { + for (var x = 0; x < _spawnObjects.GetLength(1); x++) + { + var objName = _spawnObjects[y, x]; + if (objName == null) + continue; + + var _objParameter = MapData.GetParameter(objName, null); + if (_objParameter != null) + { + _objParameter[1] = (int)spawnPosition.X + x * 16; + _objParameter[2] = (int)spawnPosition.Y + y * 16; + } + + var newObject = ObjectManager.GetGameObject(Map, objName, _objParameter); + Map.Objects.SpawnObject(newObject); + + _gameObjects[x, y] = newObject; + + // spawn deep water + if (objName == SW1) + { + var objWater = new ObjWaterDeep(Map, _position.X + x * 16, _position.Y + y * 16); + Map.Objects.SpawnObject(objWater); + _waterObjects.Add(objWater); + } + else if (objName == SW2) + { + var objWater = new ObjWater(Map, _position.X + x * 16, _position.Y + y * 16, -2); + Map.Objects.SpawnObject(objWater); + _waterObjects.Add(objWater); + } + } + } + } + + private void DespawnObjects(float timeStep) + { + for (var y = 0; y < _gameObjects.GetLength(1); y++) + { + for (var x = 0; x < _gameObjects.GetLength(0); x++) + { + if (_gameObjects[x, y] == null) + continue; + + // cut the tile in half to have a nicer transition + if (_despawnTime[y, x] - 0.5f < timeStep) + { + var animatedTile = _gameObjects[x, y] as ObjAnimatedTile; + if (animatedTile != null && animatedTile.Sprite.SourceRectangle.Height * animatedTile.Sprite.Scale == 16) + { + animatedTile.Sprite.SourceRectangle.Y += 8; + animatedTile.Sprite.SourceRectangle.Height = 8; + animatedTile.EntityPosition.Offset(new Vector2(0, 8)); + } + } + + if (timeStep < _despawnTime[y, x]) + continue; + + Map.Objects.DeleteObjects.Add(_gameObjects[x, y]); + _gameObjects[x, y] = null; + + // spawn stones + if (_stoneMap[y, x] != null) + { + var objStoneSpawn = new ObjStoneSpawner(Map, + _position.X + x * 16, _position.Y + y * 16); + Map.Objects.SpawnObject(objStoneSpawn); + } + } + } + + foreach (var objWater in _waterObjects) + { + // @HACK: should get reset by despawning the deep water obj + var fieldX = (int)objWater.EntityPosition.X / 16; + var fieldY = (int)objWater.EntityPosition.Y / 16; + var currentState = Map.GetFieldState(fieldX, fieldY); + if (objWater is ObjWater) + Map.SetFieldState(fieldX, fieldY, currentState & ~MapStates.FieldStates.Water); + if (objWater is ObjWaterDeep) + Map.SetFieldState(fieldX, fieldY, currentState & ~MapStates.FieldStates.DeepWater); + + Map.Objects.DeleteObjects.Add(objWater); + } + + _waterObjects.Clear(); + } + + private void KeyChanged() + { + if (_isDespawning || Game1.GameManager.SaveManager.GetString(_strKey) != "1") + return; + + Game1.GameManager.SetMusic(75, 2); + + _isDespawning = true; + + // do not repeat the animation + if (!_wasUpdated) + _despawnCounter = 9999; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjWaterfallSound.cs b/InGame/GameObjects/Things/ObjWaterfallSound.cs new file mode 100644 index 0000000..0e1c35a --- /dev/null +++ b/InGame/GameObjects/Things/ObjWaterfallSound.cs @@ -0,0 +1,50 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; + +namespace ProjectZ.InGame.GameObjects.Things +{ + class ObjWaterfallSound : GameObject + { + private const int Range = 128; + + private static Vector2 _maxPosition; + private static float _maxDistance; + private static double _lastTime; + private static float _soundTimer; + + public ObjWaterfallSound() : base("editor shore sound") { } + + public ObjWaterfallSound(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + private void Update() + { + var distance = (EntityPosition.Position - MapManager.ObjLink.EntityPosition.Position).Length(); + if (distance < _maxDistance) + { + _maxDistance = distance; + _maxPosition = EntityPosition.Position; + } + + // @HACK: only update the sound from one object + if (_lastTime == Game1.TotalGameTime) + return; + + _lastTime = Game1.TotalGameTime; + _soundTimer -= Game1.DeltaTime; + if (_soundTimer < 0) + { + _soundTimer += Game1.RandomNumber.Next(64, 80); + Game1.GameManager.PlaySoundEffect("D378-30-1E", true, _maxPosition, Range); + _maxDistance = float.MaxValue; + } + } + } +} diff --git a/InGame/GameObjects/Things/ObjWeatherBird.cs b/InGame/GameObjects/Things/ObjWeatherBird.cs new file mode 100644 index 0000000..bc5147f --- /dev/null +++ b/InGame/GameObjects/Things/ObjWeatherBird.cs @@ -0,0 +1,152 @@ +using System; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Components.AI; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjWeatherBird : GameObject + { + private readonly AiComponent _aiComponent; + private readonly Point[] _moveOffset = { new Point(-1, 0), new Point(0, -1), new Point(1, 0), new Point(0, 1) }; + + private readonly string _saveKey; + private readonly int _allowedDirection = 1; + + private Vector2 _startPosition; + private Vector2 _aimPosition; + + private const int PushTime = 250; + private const int MoveTime = 500; + + private float _pushCounter; + private bool _wasPushed; + + public ObjWeatherBird() : base("weather_bird") { } + + public ObjWeatherBird(Map.Map map, int posX, int posY, string saveKey) : base(map) + { + EntityPosition = new CPosition(posX + 1, posY + 30, 0); + EntitySize = new Rectangle(0, -30, 16, 32); + + _saveKey = saveKey; + + var movingTrigger = new AiTriggerCountdown(MoveTime, MoveTick, MoveEnd); + _aiComponent = new AiComponent(); + _aiComponent.States.Add("idle", new AiState(UpdateIdle)); + _aiComponent.States.Add("moving", new AiState { Init = InitMoving, Trigger = { movingTrigger } }); + _aiComponent.States.Add("moved", new AiState()); + + if (_saveKey != null && Game1.GameManager.SaveManager.GetString(_saveKey) == "1") + { + EntityPosition.Set(new Vector2(EntityPosition.X, EntityPosition.Y - 16)); + _aiComponent.ChangeState("moved"); + } + else + _aiComponent.ChangeState("idle"); + + var body = new BodyComponent(EntityPosition, 0, -10, 14, 12, 8) + { + FieldRectangle = map.GetField(posX, posY) + }; + + var animator = AnimatorSaveLoad.LoadAnimator("Objects/weatherBird"); + var sprite = new CSprite(EntityPosition); + var animationComponent = new AnimationComponent(animator, sprite, new Vector2(0, -30)); + animator.Play("idle"); + + AddComponent(InteractComponent.Index, new InteractComponent(body.BodyBox, Interact)); + AddComponent(AiComponent.Index, _aiComponent); + AddComponent(BaseAnimationComponent.Index, animationComponent); + AddComponent(CollisionComponent.Index, new BoxCollisionComponent(body.BodyBox, Values.CollisionTypes.Normal)); + AddComponent(DrawComponent.Index, new BodyDrawComponent(body, sprite, Values.LayerPlayer)); + AddComponent(PushableComponent.Index, new PushableComponent(body.BodyBox, OnPush)); + } + + private bool Interact() + { + Game1.GameManager.StartDialogPath("weatherBird"); + return true; + } + + private bool OnPush(Vector2 direction, PushableComponent.PushType type) + { + if (_aiComponent.CurrentStateId != "idle") + return false; + + // move the stone + if (type != PushableComponent.PushType.Continues) + return false; + + var stoneLifter = Game1.GameManager.GetItem("stonelifter2"); + if (stoneLifter == null) + return false; + + var pushDirection = AnimationHelper.GetDirection(direction); + + if (_allowedDirection != -1 && _allowedDirection != pushDirection) + return false; + + _wasPushed = true; + _pushCounter += Game1.DeltaTime; + + // start moving + if (_pushCounter < PushTime) + return false; + + _startPosition = EntityPosition.Position; + + _aimPosition = new Vector2( + _startPosition.X + _moveOffset[pushDirection].X * 16, + _startPosition.Y + _moveOffset[pushDirection].Y * 16); + + _aiComponent.ChangeState("moving"); + + return true; + } + + private void UpdateIdle() + { + // reset the moveCounter used for measuring how long the player is already pushing + // this is used so the stone does not move instantly after the first collision with the player + if (!_wasPushed) + _pushCounter = 0; + + _wasPushed = false; + } + + private void InitMoving() + { + Game1.GameManager.PlaySoundEffect("D378-17-11"); + + // set the key + if (_saveKey != null) + Game1.GameManager.SaveManager.SetString(_saveKey, "1"); + } + + private void MoveTick(double time) + { + // freeze the player + MapManager.ObjLink.FreezePlayer(); + + // the movement is fast in the beginning and slows down at the end + var amount = (float)Math.Sin((MoveTime - time) / MoveTime * (Math.PI / 2f)); + EntityPosition.Set(Vector2.Lerp(_startPosition, _aimPosition, amount)); + } + + private void MoveEnd() + { + Game1.GameManager.PlaySoundEffect("D360-35-23"); + + // finished moving + EntityPosition.Set(_aimPosition); + + _aiComponent.ChangeState("moved"); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjWindfish.cs b/InGame/GameObjects/Things/ObjWindfish.cs new file mode 100644 index 0000000..24e8ffc --- /dev/null +++ b/InGame/GameObjects/Things/ObjWindfish.cs @@ -0,0 +1,82 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjWindfish : GameObject + { + private readonly CSprite _sprite; + private readonly Vector2 _spawnPosition; + + private CPosition _drawPosition; + private string _spawnKey; + private float _hoverCounter; + private double _wobbleCounter; + private double _wobbleTime; + private bool _isVisible; + + public ObjWindfish() : base("editor_windfish") { } + + public ObjWindfish(Map.Map map, int posX, int posY, string spawnKey) : base(map) + { + _spawnKey = spawnKey; + _spawnPosition = new Vector2(posX, posY); + + _sprite = new CSprite("final_wale", _drawPosition = new CPosition(posX, posY, 0)) { Color = Color.Transparent, SpriteShader = Resources.WindFishShader }; + + if (!string.IsNullOrEmpty(_spawnKey)) + AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange)); + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerBackground)); + } + + private void OnKeyChange() + { + if (!_isVisible && Game1.GameManager.SaveManager.GetString(_spawnKey) == "1") + { + Game1.GameManager.PlaySoundEffect("D370-31-1F"); + _isVisible = true; + } + if (_isVisible && Game1.GameManager.SaveManager.GetString(_spawnKey) == "0") + { + Game1.GameManager.PlaySoundEffect("D370-31-1F"); + _isVisible = false; + } + } + + private void Update() + { + _hoverCounter += Game1.DeltaTime; + _drawPosition.Y = _spawnPosition.Y + MathF.Sin(_hoverCounter / 2000 * MathF.PI * 2) * 2; + + if (_isVisible && _wobbleCounter < 3500) + UpdateFadeAnimation(1); + if (!_isVisible && _wobbleCounter > 0) + UpdateFadeAnimation(-1); + } + + private void UpdateFadeAnimation(int dir) + { + _wobbleTime += Game1.DeltaTime / 125; + _wobbleCounter += Game1.DeltaTime * dir; + if (_wobbleCounter < 0) + _wobbleCounter = 0; + if (_wobbleCounter > 3500) + _wobbleCounter = 3500; + + var offset = 0.05f - 0.05f * MathHelper.Clamp((float)(_wobbleCounter - (3500 - 650)) / 650, 0, 1); + var period = 25f - 5f * MathHelper.Clamp((float)(_wobbleCounter - 1500) / 2000, 0, 1); + + Resources.WindFishShader.FloatParameter["Offset"] = offset; + Resources.WindFishShader.FloatParameter["Period"] = period; + Resources.WindFishShader.FloatParameter["Time"] = (float)_wobbleTime; + + var fadePercentage = (float)_wobbleCounter / 3000; + _sprite.Color = Color.White * fadePercentage; + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjZZZ.cs b/InGame/GameObjects/Things/ObjZZZ.cs new file mode 100644 index 0000000..73d4177 --- /dev/null +++ b/InGame/GameObjects/Things/ObjZZZ.cs @@ -0,0 +1,48 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjZZZ : GameObject + { + private readonly CSprite _sprite; + private readonly Vector2 _direction; + private readonly Vector2 _dirOrthogonal; + private float _moveCounter; + private float _transparency; + + public ObjZZZ(Map.Map map, Vector2 position, Vector2 direction) : base(map) + { + EntityPosition = new CPosition(position.X, position.Y, 0); + EntitySize = new Rectangle(-8, -8, 16, 16); + + _sprite = new CSprite("tarin_zzz", EntityPosition); + + _direction = direction; + _dirOrthogonal = new Vector2(_direction.Y, -_direction.X); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerTop)); + } + + private void Update() + { + // fade in/out + var target = _moveCounter < 750 ? 1 : 0; + _transparency = AnimationHelper.MoveToTarget(_transparency, target, 0.25f * Game1.TimeMultiplier); + _sprite.Color = Color.White * _transparency; + + // move + _moveCounter += Game1.DeltaTime; + EntityPosition.Set(EntityPosition.Position + _direction * 0.175f * Game1.TimeMultiplier + _dirOrthogonal * Game1.TimeMultiplier * 0.125f * MathF.Sin(_moveCounter / 100)); + + // despawn + if (_moveCounter > 850) + Map.Objects.DeleteObjects.Add(this); + } + } +} \ No newline at end of file diff --git a/InGame/GameObjects/Things/ObjZZZSpawner.cs b/InGame/GameObjects/Things/ObjZZZSpawner.cs new file mode 100644 index 0000000..3e72f58 --- /dev/null +++ b/InGame/GameObjects/Things/ObjZZZSpawner.cs @@ -0,0 +1,34 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.CObjects; +using ProjectZ.InGame.GameObjects.Base.Components; + +namespace ProjectZ.InGame.GameObjects.Things +{ + internal class ObjZZZSpawner : GameObject + { + private float _spawnCounter; + private const int SpawnTime = 600; + + public ObjZZZSpawner() : base("tarin_zzz") { } + + public ObjZZZSpawner(Map.Map map, int posX, int posY) : base(map) + { + EntityPosition = new CPosition(posX, posY, 0); + EntitySize = new Rectangle(0, 0, 16, 16); + + AddComponent(UpdateComponent.Index, new UpdateComponent(Update)); + } + + private void Update() + { + _spawnCounter -= Game1.DeltaTime; + if(_spawnCounter < 0) + { + _spawnCounter += SpawnTime; + var objZzz = new ObjZZZ(Map, new Vector2(EntityPosition.X + 8, EntityPosition.Y + 8), new Vector2(1, -1)); + Map.Objects.SpawnObject(objZzz); + } + } + } +} \ No newline at end of file diff --git a/InGame/GameSystems/EndingSystem.cs b/InGame/GameSystems/EndingSystem.cs new file mode 100644 index 0000000..4e86999 --- /dev/null +++ b/InGame/GameSystems/EndingSystem.cs @@ -0,0 +1,50 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.GameSystems +{ + class EndingSystem : GameSystem + { + private float _counter; + private bool _isActive; + + public override void OnLoad() + { + _isActive = false; + } + + public override void Update() + { + if(!_isActive) + return; + + _counter -= Game1.DeltaTime; + + if (_counter < 0) + { + _isActive = false; + Game1.ScreenManager.ChangeScreen(Values.ScreenEnding); + } + } + + public override void Draw(SpriteBatch spriteBatch) + { + + } + + public void StartEnding() + { + _isActive = true; + _counter = 2000; + + MapManager.ObjLink.MapTransitionStart = new Vector2(MapManager.ObjLink.EntityPosition.X, MapManager.ObjLink.EntityPosition.Y); + MapManager.ObjLink.MapTransitionEnd = MapManager.ObjLink.MapTransitionStart; + //MapManager.ObjLink.DirectionExit = Direction; + + // append a map change + ((MapTransitionSystem)Game1.GameManager.GameSystems[typeof(MapTransitionSystem)]).AppendMapChange("ending.map", "entry"); + } + } +} diff --git a/InGame/GameSystems/GameOverSystem.cs b/InGame/GameSystems/GameOverSystem.cs new file mode 100644 index 0000000..2ebdda9 --- /dev/null +++ b/InGame/GameSystems/GameOverSystem.cs @@ -0,0 +1,78 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Pages; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.GameSystems +{ + class GameOverSystem : GameSystem + { + private const int DyingTime = 500; + + private double _dyingCount; + private float _percentage; + private bool _isRunning; + + public void StartDeath() + { + _dyingCount = -850; + _isRunning = true; + _percentage = 0; + } + + public void EndSystem() + { + _isRunning = false; + Game1.GameManager.InGameOverlay.HudTransparency = 1; + Game1.GameManager.DrawPlayerOnTopPercentage = 0; + } + + public override void Update() + { + if (!_isRunning) + return; + + Game1.GameManager.InGameOverlay.DisableOverlayToggle = true; + + // draw the player on top of everything + (MapManager.ObjLink.Components[DrawComponent.Index] as DrawComponent).Layer = Values.LayerTop; + + if (_dyingCount < DyingTime) + _dyingCount += Game1.DeltaTime; + + _percentage = MathHelper.Clamp((float)_dyingCount / DyingTime, 0, 1); + + // fade out hud + Game1.GameManager.InGameOverlay.HudTransparency = 1 - _percentage; + // make sure the player is drawn ontop + Game1.GameManager.DrawPlayerOnTopPercentage = _percentage; + //Game1.GameManager.MapManager.CurrentMap.LightState = _percentage; + + if (_dyingCount >= DyingTime && !MapManager.ObjLink.Animation.IsPlaying) + { + Game1.UpdateGame = false; + _dyingCount = DyingTime; + + if (Game1.UiPageManager.GetCurrentPage() == null || + Game1.UiPageManager.GetCurrentPage().GetType() != typeof(GameOverPage)) + { + Game1.UiPageManager.ClearStack(); + Game1.UiPageManager.ChangePage(typeof(GameOverPage), null, PageManager.TransitionAnimation.Fade, PageManager.TransitionAnimation.Fade); + } + } + } + + public override void Draw(SpriteBatch spriteBatch) + { + if (!_isRunning && _percentage > 0) + return; + + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null); + spriteBatch.Draw(Resources.SprWhite, new Rectangle(0, 0, Game1.RenderWidth, Game1.RenderHeight), Color.White * _percentage); + spriteBatch.End(); + } + } +} diff --git a/InGame/GameSystems/GameSystem.cs b/InGame/GameSystems/GameSystem.cs new file mode 100644 index 0000000..f324553 --- /dev/null +++ b/InGame/GameSystems/GameSystem.cs @@ -0,0 +1,13 @@ +using Microsoft.Xna.Framework.Graphics; + +namespace ProjectZ.InGame.GameSystems +{ + public class GameSystem + { + public virtual void OnLoad() { } + + public virtual void Update() { } + + public virtual void Draw(SpriteBatch spriteBatch) { } + } +} diff --git a/InGame/GameSystems/MapShowSystem.cs b/InGame/GameSystems/MapShowSystem.cs new file mode 100644 index 0000000..8928728 --- /dev/null +++ b/InGame/GameSystems/MapShowSystem.cs @@ -0,0 +1,159 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using System; +using System.Threading; + +namespace ProjectZ.InGame.GameSystems +{ + class MapShowSystem : GameSystem + { + private Thread _loadingThread; + + public Color TransitionColor = Color.White; + + private Vector2[] _cameraTargets = new Vector2[] { + new Vector2(248, 1344), + new Vector2(120, 1488), + new Vector2(416, 1984), + new Vector2(256, 704), + new Vector2(400, 1216) }; + + private float _counter; + private const float ChangeTargetTime = 5350; + private const float FadeTime = 500; + private const float FadeLock = 250; + private int _targetIndex; + + private bool _isActive; + private bool _finished; + private bool _finishedLoading; + private bool _init; + + public override void OnLoad() + { + _targetIndex = 0; + _finished = false; + _isActive = false; + } + + public override void Update() + { + if (!_isActive) + return; + + if (!_init) + { + if (_finishedLoading && _counter <= 0) + { + _counter = ChangeTargetTime; + _finishedLoading = false; + _init = true; + FinishLoading(); + } + else + { + _counter -= Game1.DeltaTime; + } + + return; + } + + _counter -= Game1.DeltaTime; + + if (_finished && _counter < ChangeTargetTime - FadeTime - FadeLock) + { + _isActive = false; + return; + } + + if (_counter < 0) + { + _counter += ChangeTargetTime; + + _targetIndex++; + if (_targetIndex < _cameraTargets.Length) + { + Game1.GameManager.MapManager.CurrentMap.CameraTarget = _cameraTargets[_targetIndex]; + MapManager.Camera.ForceUpdate(Game1.GameManager.MapManager.GetCameraTarget()); + } + else + { + _finished = true; + + // switch back to the ending map + var oldMap = Game1.GameManager.MapManager.CurrentMap; + Game1.GameManager.MapManager.CurrentMap = Game1.GameManager.MapManager.NextMap; + Game1.GameManager.MapManager.NextMap = oldMap; + + Game1.GameManager.InGameOverlay.StartSequence("final"); + } + } + } + + public override void Draw(SpriteBatch spriteBatch) + { + if (!_isActive) + return; + + spriteBatch.Begin(); + + var fadePercentage = 0f; + // fade out + if (_counter < FadeTime + FadeLock) + fadePercentage = 1 - MathF.Sin(MathHelper.Clamp((_counter - FadeLock) / FadeTime, 0, 1) * MathF.PI * 0.5f); + // fade in + else if (ChangeTargetTime - FadeTime - FadeLock < _counter) + fadePercentage = MathF.Sin((1 - MathHelper.Clamp((ChangeTargetTime - FadeLock - _counter) / FadeTime, 0, 1)) * MathF.PI * 0.5f); + + spriteBatch.Draw(Resources.SprWhite, new Rectangle(0, 0, Game1.RenderWidth, Game1.RenderHeight), TransitionColor * fadePercentage); + spriteBatch.End(); + } + + public void StartEnding() + { + if (_isActive) + return; + + _isActive = true; + _finishedLoading = false; + _init = false; + _counter = FadeLock + FadeTime; + + // used to spawn different npcs on the overworld + Game1.GameManager.SaveManager.SetString("final_show", "1"); + Game1.GameManager.SaveManager.SetString("marin_state", "1"); + + // start loading the new map in a thread + _loadingThread = new Thread(o => ThreadLoading("overworld.map")); + _loadingThread.Start(); + } + + private void ThreadLoading(string mapFileName) + { + // load the map file + SaveLoadMap.LoadMap(mapFileName, Game1.GameManager.MapManager.NextMap); + + // create the objects + Game1.GameManager.MapManager.NextMap.Objects.LoadObjects(); + + _finishedLoading = true; + } + + private void FinishLoading() + { + // switch to the new map + var oldMap = Game1.GameManager.MapManager.CurrentMap; + Game1.GameManager.MapManager.CurrentMap = Game1.GameManager.MapManager.NextMap; + Game1.GameManager.MapManager.NextMap = oldMap; + + // center the camera + Game1.GameManager.MapManager.CurrentMap.CameraTarget = _cameraTargets[_targetIndex]; + MapManager.Camera.ForceUpdate(Game1.GameManager.MapManager.GetCameraTarget()); + + Game1.GameManager.StartDialogPath("final_show_map"); + } + } +} diff --git a/InGame/GameSystems/MapTransitionSystem.cs b/InGame/GameSystems/MapTransitionSystem.cs new file mode 100644 index 0000000..7a31f71 --- /dev/null +++ b/InGame/GameSystems/MapTransitionSystem.cs @@ -0,0 +1,463 @@ +using System; +using System.Threading; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +#if WINDOWS +using System.Windows.Forms; +#endif + +namespace ProjectZ.InGame.GameSystems +{ + internal class MapTransitionSystem : GameSystem + { + public int AdditionalBlackScreenDelay; + public bool StartDreamTransition; + public bool StartTeleportTransition; + public bool StartKnockoutTransition; + + public enum TransitionState + { + Idle, + TransitionIn, + TransitionBlank_0, + TransitionBlank_1, + TransitionOut, + ColorMode + } + + public TransitionState CurrentState = TransitionState.Idle; + public const int ChangeMapTime = 350; + public const int BlackScreenDelay = 75; // 125 + + private readonly MapManager _gameMapManager; + private readonly ObjTransition _transitionObject; + + private Thread _loadingThread; + + private string _nextMapName; + private string _nextMapPosition; + private bool _nextMapCenter; + private bool _nextMapStartInMiddle; + private Color _nextMapColor; + private bool _nextColorMode; + + private float _changeMapCount; + + // will be reset after each transition + private bool _centerCamera; + private bool _finishedLoading; + private bool _fullColorMode; + private bool _knockoutTransition; + private bool _transitionEnded; + private bool _introTransition; + + private const int DreamTransitionTimeAddition = 3000; + private const int TeleportTransitionTimeAddition = 2000 - ChangeMapTime; + private int _wobbleTransitionTime; + private bool _wobbleTransitionOut; + private bool _wobbleTransitionIn; + + public MapTransitionSystem(MapManager gameMapManager) + { + _gameMapManager = gameMapManager; + + _transitionObject = new ObjTransition(_gameMapManager.CurrentMap); + } + + public override void OnLoad() + { + _nextMapName = null; + } + + public override void Update() + { + // start map change + if (_nextMapName != null) + { + if (!string.IsNullOrEmpty(_nextMapPosition)) + MapManager.ObjLink.SetNextMapPosition(_nextMapPosition); + + LoadMapFromFile(_nextMapName, _nextMapCenter, _nextMapStartInMiddle, _nextMapColor, _nextColorMode); + _nextMapName = null; + } + + if (_transitionEnded) + { + _transitionEnded = false; + Game1.GameManager.SaveManager.SetString("transition_ended", "0"); + } + + if (CurrentState != TransitionState.Idle) + Game1.GameManager.InGameOverlay.DisableOverlayToggle = true; + else + Game1.GbsPlayer.SetVolumeMultiplier(1); + + if (CurrentState == TransitionState.TransitionOut) + { + _changeMapCount += Game1.DeltaTime; + + var transitionState = _changeMapCount / ChangeMapTime; + var percentage = MathHelper.Clamp((float)(Math.Sin(transitionState * 1.1) / Math.Sin(1.1)), 0, 1); + MapManager.ObjLink.UpdateMapTransitionOut(percentage); + + if (!_wobbleTransitionOut && !_knockoutTransition) + Game1.GameManager.DrawPlayerOnTopPercentage = percentage; + + // slowly lower the volume of the music + var newVolume = 1 - MathHelper.Clamp(transitionState, 0, 1); + Game1.GbsPlayer.SetVolumeMultiplier(newVolume); + + if (_wobbleTransitionOut) + { + // fade out to a white screen + var wobblePercentage = MathHelper.Clamp(_changeMapCount / ChangeMapTime, 0, 1); + _transitionObject.Brightness = wobblePercentage; + _transitionObject.WobblePercentage = (_wobbleTransitionTime + _changeMapCount) / (_wobbleTransitionTime + ChangeMapTime); + } + + if (_changeMapCount >= ChangeMapTime) + CurrentState = TransitionState.TransitionBlank_0; + } + else if (CurrentState == TransitionState.TransitionBlank_0) + { + _changeMapCount += Game1.DeltaTime; + + MapManager.ObjLink.UpdateMapTransitionOut(1); + + // new map is loaded? + if (_finishedLoading && _changeMapCount >= ChangeMapTime + BlackScreenDelay + AdditionalBlackScreenDelay) + { + FinishLoading(); + CurrentState = TransitionState.TransitionBlank_1; + } + } + else if (CurrentState == TransitionState.TransitionBlank_1) + { + _changeMapCount += Game1.DeltaTime; + + MapManager.ObjLink.UpdateMapTransitionIn(0); + + if (_changeMapCount >= ChangeMapTime + BlackScreenDelay * 2 + AdditionalBlackScreenDelay) + { + CurrentState = TransitionState.TransitionIn; + + if (_wobbleTransitionIn) + _changeMapCount = _wobbleTransitionTime; + else + { + _transitionObject.WobbleTransition = false; + _changeMapCount = ChangeMapTime; + } + } + } + else if (CurrentState == TransitionState.TransitionIn) + { + _changeMapCount -= Game1.DeltaTime; + + // update the position of the player to walk into the new room + var percentage = MathHelper.Clamp(_changeMapCount / ChangeMapTime, 0, 1); + MapManager.ObjLink.UpdateMapTransitionIn(1 - (float)(Math.Sin(percentage * 1.1) / Math.Sin(1.1))); + + // slowly increase the volume of the music; the music is only playing + var newVolume = 1 - percentage; + if (Game1.GbsPlayer.GetVolumeMultiplier() < 1) + Game1.GbsPlayer.SetVolumeMultiplier(newVolume); + + if (!_wobbleTransitionOut && !_knockoutTransition && !_introTransition) + Game1.GameManager.DrawPlayerOnTopPercentage = percentage; + + if (_wobbleTransitionOut) + { + // fade out to a white screen + var wobblePercentage = 1 - MathHelper.Clamp((_wobbleTransitionTime - _changeMapCount) / ChangeMapTime, 0, 1); + _transitionObject.Brightness = wobblePercentage; + _transitionObject.WobblePercentage = _changeMapCount / _wobbleTransitionTime; + } + + // light up the scene + if (_changeMapCount <= 0) + { + _transitionEnded = true; + Game1.GameManager.SaveManager.SetString("transition_ended", "1"); + + CurrentState = TransitionState.Idle; + EndTransition(); + } + } + + if (_knockoutTransition) + { + var percentage = MathHelper.Clamp((_changeMapCount - 100) / (ChangeMapTime - 100), 0, 1); + _transitionObject.TransitionColor = _nextMapColor * percentage; + _transitionObject.Percentage = 1; + + Game1.GameManager.MapManager.UpdateCameraX = false; + Game1.GameManager.MapManager.UpdateCameraY = false; + } + + if (_fullColorMode) + { + _transitionObject.Percentage = 1; + _transitionObject.TransitionColor = _nextMapColor * TransitionPercentage(); + } + else if (!_knockoutTransition) + { + _transitionObject.Percentage = (float)Math.Sin(TransitionPercentage() * Math.PI / 2); + } + } + + public override void Draw(SpriteBatch spriteBatch) + { + if (CurrentState == TransitionState.Idle) + return; + + _transitionObject.Draw(spriteBatch); + } + + public void SetColorMode(Color color, float colorTransparency, bool playerOnTop = true) + { + if (colorTransparency > 0) + CurrentState = TransitionState.ColorMode; + else + CurrentState = TransitionState.Idle; + + _changeMapCount = ChangeMapTime; + + _transitionObject.TransitionColor = color * colorTransparency; + + if (playerOnTop) + Game1.GameManager.DrawPlayerOnTopPercentage = colorTransparency; + } + + public bool IsTransitioningOut() + { + return CurrentState == TransitionState.TransitionOut; + } + + public bool IsTransitioningIn() + { + return CurrentState == TransitionState.TransitionIn; + } + + private void StartTransition() + { + // draw the player on top of everything + MapManager.ObjLink.StartTransitioning(); + + _introTransition = Game1.GameManager.SaveManager.GetString("played_intro", "0") != "1"; + // dont show the player for the intro sequence transition + if (!_introTransition) + Game1.GameManager.DrawPlayerOnTopPercentage = 1.0f; + } + + private void EndTransition() + { + _knockoutTransition = false; + + MapManager.ObjLink.EndTransitioning(); + + // start the new music + Game1.GbsPlayer.SetVolumeMultiplier(1); + Game1.GbsPlayer.Play(); + + MapManager.Camera.SoftUpdate(Game1.GameManager.MapManager.GetCameraTarget()); + } + + public float TransitionPercentage() + { + return MathHelper.Clamp(_changeMapCount / ChangeMapTime, 0, 1); + } + + public void AppendMapChange(string mapName, string position) + { + AppendMapChange(mapName, position, false, false, Values.MapTransitionColor, false); + } + + public void AppendMapChange(string mapName, string position, bool centerCamera, bool startFromMiddle, Color transitionColor, bool colorMode) + { + _nextMapName = mapName; + _nextMapPosition = position; + _nextMapCenter = centerCamera; + _nextMapStartInMiddle = startFromMiddle; + _nextMapColor = transitionColor; + _nextColorMode = colorMode; + + MapManager.ObjLink.OnAppendMapChange(); + } + + public void LoadMapFromFile(string mapFileName, bool centerCamera, bool startFromMiddle, Color transitionColor, bool colorMode) + { + // abort the old loading thread if it is still running + // TODO: thread abort is not supported so it just waits till the loading is finished + if (_loadingThread != null && _loadingThread.IsAlive) + _loadingThread.Join(); + + //Debug.Assert(CurrentState == TransitionState.Idle || + // CurrentState == TransitionState.ColorMode, "Tried transition while not in idle"); + + _finishedLoading = false; + + // only show the opening transition + if (startFromMiddle) + { + _changeMapCount = ChangeMapTime; + CurrentState = TransitionState.TransitionBlank_0; + } + else + { + _changeMapCount = 0; + CurrentState = TransitionState.TransitionOut; + } + + // center after loading + _centerCamera = centerCamera; + + // add the transition object to the map + _knockoutTransition = false; + _fullColorMode = colorMode; + _nextMapColor = transitionColor; + + _wobbleTransitionOut = false; + _wobbleTransitionIn = false; + + _transitionObject.WobbleTransition = false; + + _transitionObject.TransitionColor = transitionColor; + _transitionObject.Percentage = startFromMiddle ? 1 : 0; + + // start transition + StartTransition(); + + if (StartDreamTransition) + { + StartDreamTransition = false; + DreamTransition(); + } + if (StartTeleportTransition) + { + StartTeleportTransition = false; + TeleportTransition(); + } + + if (StartKnockoutTransition) + { + StartKnockoutTransition = false; + KnockoutTransition(); + } + + // start loading the new map in a thread + _loadingThread = new Thread(o => ThreadLoading(mapFileName)); + _loadingThread.Start(); + } + + public void DreamTransition() + { + _transitionObject.WobbleTransition = true; + _fullColorMode = true; + _wobbleTransitionOut = true; + + Game1.GameManager.DrawPlayerOnTopPercentage = 0.0f; + _nextMapColor = Color.White; + + // take longer + _changeMapCount = -DreamTransitionTimeAddition; + _wobbleTransitionTime = DreamTransitionTimeAddition; + AdditionalBlackScreenDelay = 500; + } + + public void TeleportTransition() + { + _transitionObject.WobbleTransition = true; + _fullColorMode = true; + _wobbleTransitionOut = true; + _wobbleTransitionIn = true; + + Game1.GameManager.DrawPlayerOnTopPercentage = 0.0f; + _nextMapColor = Color.White; + + // take longer + _changeMapCount = -TeleportTransitionTimeAddition; + _wobbleTransitionTime = TeleportTransitionTimeAddition; + AdditionalBlackScreenDelay = 500; + } + + public void KnockoutTransition() + { + _knockoutTransition = true; + + Game1.GameManager.DrawPlayerOnTopPercentage = 0.0f; + _nextMapColor = Color.White; + + // take longer + AdditionalBlackScreenDelay = 1000; + } + + public void ThreadLoading(string mapFileName) + { + try + { + // @HACK: after loading the map the garbage collector will start and increase the frametime + // this also leads to the door soundeffect cracking sometimes + // if we wait a little bit the cracking gets reduced by a lot + //Thread.Sleep(75); + + // load the map file + SaveLoadMap.LoadMap(mapFileName, _gameMapManager.NextMap); + // create the objects + _gameMapManager.NextMap.Objects.LoadObjects(); + + _finishedLoading = true; + } + catch (Exception exception) + { +#if WINDOWS + // show the error message instead of just crashing the game + MessageBox.Show(exception.StackTrace, exception.Message, MessageBoxButtons.OK, MessageBoxIcon.Error); +#endif + throw; + } + } + + public void FinishLoading() + { + AdditionalBlackScreenDelay = 0; + + // switch to the new map + var oldMap = _gameMapManager.CurrentMap; + _gameMapManager.CurrentMap = _gameMapManager.NextMap; + _gameMapManager.NextMap = oldMap; + + var currentTrack = Game1.GbsPlayer.CurrentTrack; + var nextTrack = -1; + for (var i = 0; i < _gameMapManager.CurrentMap.MapMusic.Length; i++) + if (_gameMapManager.CurrentMap.MapMusic[i] >= 0) + nextTrack = _gameMapManager.CurrentMap.MapMusic[i]; + + if (currentTrack != nextTrack) + Game1.GbsPlayer.Pause(); + + Game1.GameManager.ResetMusic(); + + // finish loading map + _gameMapManager.FinishLoadingMap(_gameMapManager.CurrentMap); + + MapManager.ObjLink.UpdateMapTransitionIn(0); + + // set the new music + for (var i = 0; i < _gameMapManager.CurrentMap.MapMusic.Length; i++) + if (_gameMapManager.CurrentMap.MapMusic[i] >= 0) + Game1.GameManager.SetMusic(_gameMapManager.CurrentMap.MapMusic[i], i, false); + + // center the camera + var goalPosition = Game1.GameManager.MapManager.GetCameraTarget(); + if (_centerCamera) + MapManager.Camera.ForceUpdate(goalPosition); + else + MapManager.Camera.SoftUpdate(goalPosition); + } + } +} \ No newline at end of file diff --git a/InGame/Interface/InterfaceButton.cs b/InGame/Interface/InterfaceButton.cs new file mode 100644 index 0000000..fbfa9d0 --- /dev/null +++ b/InGame/Interface/InterfaceButton.cs @@ -0,0 +1,80 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Interface +{ + public class InterfaceButton : InterfaceElement + { + public InterfaceElement InsideElement; + + public delegate void BFunction(InterfaceElement element); + public BFunction ClickFunction; + + public InterfaceButton() + { + Selectable = true; + + Color = Values.MenuButtonColor; + SelectionColor = Values.MenuButtonColorSelected; + } + + public InterfaceButton(Point size, Point margin, InterfaceElement insideElement, BFunction clickFunction) : this() + { + Size = size; + Margin = margin; + InsideElement = insideElement; + ClickFunction = clickFunction; + } + + public InterfaceButton(Point size, Point margin, string text, BFunction clickFunction) : this() + { + Size = size; + Margin = margin; + + var label = new InterfaceLabel(text, size, Point.Zero); + + InsideElement = label; + ClickFunction = clickFunction; + } + + public override void Select(Directions direction, bool animate) + { + InsideElement?.Select(direction, animate); + + base.Select(direction, animate); + } + + public override void Deselect(bool animate) + { + InsideElement?.Deselect(animate); + + base.Deselect(animate); + } + + public override InputEventReturn PressedButton(CButtons pressedButton) + { + if (pressedButton != CButtons.A) + return InputEventReturn.Nothing; + + if (ClickFunction != null) + { + Game1.GameManager.PlaySoundEffect("D360-19-13"); + + ClickFunction(this); + return InputEventReturn.Something; + } + + return InputEventReturn.Nothing; + } + + public override void Draw(SpriteBatch spriteBatch, Vector2 drawPosition, float scale, float transparency) + { + base.Draw(spriteBatch, drawPosition, scale, transparency); + + // draw the embedded element + InsideElement?.Draw(spriteBatch, drawPosition, scale, transparency); + } + } +} \ No newline at end of file diff --git a/InGame/Interface/InterfaceCanvas.cs b/InGame/Interface/InterfaceCanvas.cs new file mode 100644 index 0000000..a87523e --- /dev/null +++ b/InGame/Interface/InterfaceCanvas.cs @@ -0,0 +1,18 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace ProjectZ.InGame.Interface +{ + public class InterfaceCanvas : InterfaceElement + { + public InterfaceElement InsideElement; + + public override void Draw(SpriteBatch spriteBatch, Vector2 drawPosition, float scale, float transparency) + { + base.Draw(spriteBatch, drawPosition, scale, transparency); + + // draw the embedded element + InsideElement?.Draw(spriteBatch, drawPosition, scale, transparency); + } + } +} \ No newline at end of file diff --git a/InGame/Interface/InterfaceElement.cs b/InGame/Interface/InterfaceElement.cs new file mode 100644 index 0000000..c7df33b --- /dev/null +++ b/InGame/Interface/InterfaceElement.cs @@ -0,0 +1,152 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.Interface +{ + public class InterfaceElement + { + [Flags] + public enum Gravities + { + Center = 0x01 << 0, + Left = 0x01 << 1, + Right = 0x01 << 2, + Top = 0x01 << 3, + Bottom = 0x01 << 4 + } + + public enum Directions + { + Left, Right, Top, Down + } + + public enum InputEventReturn + { + Nothing, Something + } + + public Gravities Gravity = Gravities.Center; + + public Color Color; + public Color SelectionColor; + + public Point Position; + public Point Size; + public Point Margin; + + public float CornerRadius = 3.0f; + + public bool SizeChanged; + public bool Selected; + public bool Selectable; + public bool ChangeUp; + public bool Recalculate; + + public bool Visible + { + get => _visible; + set + { + _visible = value; + } + } + + // this is ignored at the layout stage + public bool Hidden + { + get => _hidden; + set + { + ChangeUp = true; + _hidden = value; + } + } + + public float SelectionState; + + private float _selectionCounter; + private float _selectAnimationTime = 75; + private float _deselectionTime = 50; + + private bool _visible = true; + private bool _hidden; + + public virtual void Select(Directions direction, bool animate) + { + Selected = true; + SelectionState = animate ? 0 : 1; + _selectionCounter = animate ? _selectAnimationTime : 0; + } + + public virtual void Deselect(bool animate) + { + Selected = false; + // do not start the animation from the start if the element was selected in the same frame + if (_selectionCounter != _selectAnimationTime && animate) + { + SelectionState = 1; + _selectionCounter = _deselectionTime; + } + else + { + SelectionState = 0; + _selectionCounter = 0; + } + } + + public virtual InputEventReturn PressedButton(CButtons pressedButton) + { + return InputEventReturn.Nothing; + } + + public virtual void CalculatePosition() { } + + public virtual void Update() + { + if (_selectionCounter > 0) + { + _selectionCounter -= Game1.DeltaTime; + SelectionState = Selected ? 1 - _selectionCounter / _selectAnimationTime : _selectionCounter / _deselectionTime; + } + else + SelectionState = Selected ? 1 : 0; + } + + public virtual void Draw(SpriteBatch spriteBatch, Vector2 drawPosition, float scale, float transparency) + { + var color = Color.Lerp(Color, SelectionColor, SelectionState) * transparency; + + if (color != Color.Transparent) + { + spriteBatch.End(); + spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, null, Resources.RoundedCornerEffect, Game1.GetMatrix); + + Resources.RoundedCornerEffect.Parameters["radius"].SetValue(CornerRadius); + Resources.RoundedCornerEffect.Parameters["width"].SetValue(Size.X); + Resources.RoundedCornerEffect.Parameters["height"].SetValue(Size.Y); + Resources.RoundedCornerEffect.Parameters["scale"].SetValue(Game1.UiScale); + + // draw the background + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + (int)drawPosition.X + (int)(-SelectionState * scale), + (int)drawPosition.Y + (int)(-SelectionState * scale), + (int)(Size.X * scale) + (int)(SelectionState * 2 * scale), + (int)(Size.Y * scale) + (int)(SelectionState * 2 * scale)), color); + + spriteBatch.End(); + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, Game1.GetMatrix); + } + + // draw the debug background + if (Game1.DebugMode) + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + (int)drawPosition.X, + (int)drawPosition.Y, + (int)(Size.X * scale), + (int)(Size.Y * scale)), Color.White * 0.25f * transparency); + } + } +} \ No newline at end of file diff --git a/InGame/Interface/InterfaceGravityLayout.cs b/InGame/Interface/InterfaceGravityLayout.cs new file mode 100644 index 0000000..f3aff1a --- /dev/null +++ b/InGame/Interface/InterfaceGravityLayout.cs @@ -0,0 +1,98 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace ProjectZ.InGame.Interface +{ + public class InterfaceGravityLayout : InterfaceElement + { + public List Elements = new List(); + + public InterfaceGravityLayout() + { + Selectable = true; + } + + public override void Update() + { + base.Update(); + + foreach (var element in Elements) + element.Update(); + } + + public override void Deselect(bool animate) + { + foreach (var element in Elements) + if (element.Selectable) + element.Deselect(animate); + + base.Deselect(animate); + } + + public InterfaceElement AddElement(InterfaceElement element) + { + Recalculate = true; + Elements.Add(element); + return element; + } + + public override void Draw(SpriteBatch spriteBatch, Vector2 drawPosition, float scale, float transparency) + { + if (Recalculate) + CalculatePosition(); + + base.Draw(spriteBatch, drawPosition, scale, transparency); + + // draw all elements that are inside the layout + foreach (var element in Elements) + { + element.Draw(spriteBatch, element.Position.ToVector2() * scale + drawPosition, scale, transparency); + } + } + + public override void CalculatePosition() + { + Recalculate = false; + + var centerX = Size.X / 2; + var centerY = Size.Y / 2; + + var left = 0; + var right = Size.X; + var top = 0; + var down = Size.Y; + + foreach (var element in Elements) + { + if (element.ChangeUp) + element.CalculatePosition(); + + var elementPosition = Point.Zero; + + if (element.Gravity == Gravities.Center) + { + elementPosition = new Point( + centerX - element.Size.X / 2, centerY - element.Size.Y / 2); + } + else if (element.Gravity == Gravities.Left) + { + elementPosition = new Point( + left + element.Margin.X, centerY - element.Size.Y / 2); + + left += element.Size.X + element.Margin.X * 2; + } + else if (element.Gravity == Gravities.Right) + { + elementPosition = new Point( + right - element.Size.X - element.Margin.X, centerY - element.Size.Y / 2); + + left += element.Size.X + element.Margin.X * 2; + } + + element.Position = elementPosition; + } + } + + } +} \ No newline at end of file diff --git a/InGame/Interface/InterfaceImage.cs b/InGame/Interface/InterfaceImage.cs new file mode 100644 index 0000000..6e08a03 --- /dev/null +++ b/InGame/Interface/InterfaceImage.cs @@ -0,0 +1,57 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.SaveLoad; + +namespace ProjectZ.InGame.Interface +{ + public class InterfaceImage : InterfaceElement + { + public Rectangle SourceRectangle; + public Vector2 Offset; + public Color ImageColor = Color.White; + public Vector2 Origin; + public SpriteEffects Effects; + + private readonly Texture2D _sprImage; + private readonly Vector2 _drawOffset; + + public InterfaceImage(DictAtlasEntry sprite, Point margin) + { + _sprImage = sprite.Texture; + SourceRectangle = sprite.ScaledRectangle; + + Size = new Point(sprite.SourceRectangle.Width, sprite.SourceRectangle.Height); + Margin = margin; + } + + public InterfaceImage(Texture2D sprImage, Rectangle rectangle, Point size, Point margin) + { + _sprImage = sprImage; + SourceRectangle = rectangle; + + if (size == Point.Zero) + Size = new Point(SourceRectangle.Width, SourceRectangle.Height); + else + Size = size; + + Margin = margin; + + if (size != Point.Zero) + _drawOffset = new Vector2(Size.X / 2 - SourceRectangle.Width / 2, Size.Y / 2 - SourceRectangle.Height / 2); + } + + public override void Draw(SpriteBatch spriteBatch, Vector2 drawPosition, float scale, float transparency) + { + base.Draw(spriteBatch, drawPosition, scale, transparency); + + if (!Visible || Hidden) + return; + + spriteBatch.Draw(_sprImage, new Rectangle( + (int)(drawPosition.X + _drawOffset.X * scale + Offset.X * scale), + (int)(drawPosition.Y + _drawOffset.Y * scale + Offset.Y * scale), + (int)(SourceRectangle.Width * scale), + (int)(SourceRectangle.Height * scale)), SourceRectangle, ImageColor * transparency, 0, Origin, Effects, 0); + } + } +} \ No newline at end of file diff --git a/InGame/Interface/InterfaceLabel.cs b/InGame/Interface/InterfaceLabel.cs new file mode 100644 index 0000000..2f1793c --- /dev/null +++ b/InGame/Interface/InterfaceLabel.cs @@ -0,0 +1,102 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Interface +{ + public class InterfaceLabel : InterfaceElement + { + public SpriteFont Font; + + public Gravities TextAlignment + { + get { return _textAlignment; } + set + { + _textAlignment = value; + if (Text != null) + SetText(Text); + } + } + + public Color TextColor = Color.White; + + public string Text { get; set; } + public bool Translate = true; + + private Vector2 _drawOffset; + private Vector2 _textSize; + + private Gravities _textAlignment = Gravities.Center; + + private readonly string _textKey; + + public InterfaceLabel(SpriteFont font, string key, Point size, Point margin) + { + Font = font; + Size = size; + Margin = margin; + + if (string.IsNullOrEmpty(key)) + return; + + _textKey = key; + UpdateLanguageText(); + } + + public InterfaceLabel(string key, Point size, Point margin) : this(Resources.GameFont, key, size, margin) + { } + + public InterfaceLabel(string key) : this(key, Point.Zero, Point.Zero) + { + Size = new Point((int)_textSize.X, (int)_textSize.Y); + } + + public void SetText(string strText) + { + Text = strText; + + _textSize = Font.MeasureString(Text); + + if (Size != Point.Zero) + { + _drawOffset = new Vector2(Size.X / 2 - _textSize.X / 2, Size.Y / 2 - _textSize.Y / 2); + + // left/right + if ((TextAlignment & Gravities.Left) != 0) + _drawOffset.X = 0; + else if ((TextAlignment & Gravities.Right) != 0) + _drawOffset.X = Size.X - _textSize.X; + + // top/bottom + if ((TextAlignment & Gravities.Top) != 0) + _drawOffset.Y = 0; + else if ((TextAlignment & Gravities.Bottom) != 0) + _drawOffset.Y = Size.Y - _textSize.Y; + } + } + + public void UpdateLanguageText() + { + SetText(Game1.LanguageManager.GetString(_textKey, "error")); + } + + public override void Draw(SpriteBatch spriteBatch, Vector2 drawPosition, float scale, float transparency) + { + base.Draw(spriteBatch, drawPosition, scale, transparency); + + if (Translate && _textKey != null && Game1.LanguageManager.GetString(_textKey, "error") != Text) + UpdateLanguageText(); + + if (Text == null) + return; + + // draw the text + spriteBatch.DrawString(Font, Text, + new Vector2( + (int)(drawPosition.X + _drawOffset.X * scale), + (int)(drawPosition.Y + (_drawOffset.Y + 1) * scale)), + TextColor * transparency, 0, Vector2.Zero, new Vector2(scale), SpriteEffects.None, 0); + } + } +} \ No newline at end of file diff --git a/InGame/Interface/InterfaceListLayout.cs b/InGame/Interface/InterfaceListLayout.cs new file mode 100644 index 0000000..18aaf4f --- /dev/null +++ b/InGame/Interface/InterfaceListLayout.cs @@ -0,0 +1,244 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Controls; + +namespace ProjectZ.InGame.Interface +{ + public class InterfaceListLayout : InterfaceElement + { + public List Elements = new List(); + + public Gravities ContentAlignment = Gravities.Center; + + public bool HorizontalMode; + public bool AutoSize; + public bool PreventSelection; + + private int _selectionIndex; + private int _width; + private int _height; + + public InterfaceListLayout() { } + + public override void Update() + { + base.Update(); + + foreach (var element in Elements) + element.Update(); + } + + public override void Draw(SpriteBatch spriteBatch, Vector2 drawPosition, float scale, float transparency) + { + // look for changes + foreach (var element in Elements) + { + if (element.ChangeUp) + { + Recalculate = true; + element.ChangeUp = false; + } + } + + // recalculate the position of the elements if needed + if (Recalculate) + CalculatePosition(); + + base.Draw(spriteBatch, drawPosition, scale, transparency); + + // draw all the visible elements inside the layout + foreach (var element in Elements) + { + if (element.Visible && !element.Hidden) + element.Draw(spriteBatch, element.Position.ToVector2() * scale + drawPosition, scale, transparency); + } + } + + public override InputEventReturn PressedButton(CButtons pressedButton) + { + var eValue = Elements[_selectionIndex].PressedButton(pressedButton); + + // return if the upper element reacted to the button press + if (eValue != InputEventReturn.Nothing) + return eValue; + + var direction = 0; + + if (HorizontalMode ? ControlHandler.MenuButtonPressed(CButtons.Left) : ControlHandler.MenuButtonPressed(CButtons.Up)) + direction = -1; + + if (HorizontalMode ? ControlHandler.MenuButtonPressed(CButtons.Right) : ControlHandler.MenuButtonPressed(CButtons.Down)) + direction = 1; + + if (direction == 0) + return InputEventReturn.Nothing; + + // move selections + Elements[_selectionIndex].Deselect(true); + + var rValue = InputEventReturn.Something; + + do + { + _selectionIndex += direction; + + if (_selectionIndex < 0) + { + rValue = PreventSelection ? InputEventReturn.Something : InputEventReturn.Nothing; + _selectionIndex = Elements.Count - 1; + } + else if (_selectionIndex >= Elements.Count) + { + rValue = PreventSelection ? InputEventReturn.Something : InputEventReturn.Nothing; + _selectionIndex = 0; + } + + } while (!Elements[_selectionIndex].Selectable || !Elements[_selectionIndex].Visible); + + if (direction < 0) + Elements[_selectionIndex].Select(HorizontalMode ? Directions.Right : Directions.Down, true); + else + Elements[_selectionIndex].Select(HorizontalMode ? Directions.Left : Directions.Top, true); + + Game1.GameManager.PlaySoundEffect("D360-10-0A"); + + return rValue; + } + + public override void Select(Directions direction, bool animate) + { + if (!Selectable) + return; + + var dir = 1; + + if (!HorizontalMode && direction == Directions.Down || + HorizontalMode && direction == Directions.Right) + { + _selectionIndex = Elements.Count - 1; + dir = -1; + } + else if (!HorizontalMode && direction == Directions.Top || + HorizontalMode && direction == Directions.Left) + { + _selectionIndex = 0; + dir = 1; + } + + // find a selectable item in the list + while (!Elements[_selectionIndex].Selectable || !Elements[_selectionIndex].Visible) + _selectionIndex += dir; + + Elements[_selectionIndex].Select(direction, animate); + + base.Select(direction, animate); + } + + public void SetSelectionIndex(int index) + { + _selectionIndex = MathHelper.Clamp(index, 0, Elements.Count - 1); + } + + public void Select(int index, bool animate) + { + _selectionIndex = index; + Elements[_selectionIndex].Select(0, animate); + } + + public override void Deselect(bool animate) + { + if (!Selectable) + return; + + Elements[_selectionIndex].Deselect(animate); + + base.Deselect(animate); + } + + public InterfaceElement AddElement(InterfaceElement element) + { + Recalculate = true; + Elements.Add(element); + return element; + } + + public override void CalculatePosition() + { + Recalculate = false; + + _width = 0; + _height = 0; + + // calculate the width + foreach (var element in Elements) + { + if (element.Hidden) + continue; + + if (element.Recalculate) + element.CalculatePosition(); + + if (HorizontalMode) + { + _width += element.Size.X + element.Margin.X * 2; + _height = MathHelper.Max(element.Size.Y + element.Margin.Y * 2, _height); + } + else + { + _width = MathHelper.Max(element.Size.X + element.Margin.X * 2, _width); + _height += element.Size.Y + element.Margin.Y * 2; + } + } + + // set the size of the layout + if (AutoSize) + { + Size.X = _width; + Size.Y = _height; + ChangeUp = true; + } + + var centerX = Size.X / 2; + var centerY = Size.Y / 2; + + var currentX = centerX - _width / 2; + var currentY = centerY - _height / 2; + + // align content left/right + if ((ContentAlignment & Gravities.Left) != 0) + currentX = 0; + else if ((ContentAlignment & Gravities.Right) != 0) + currentX = Size.X - _width; + + // align content top/bottom + if ((ContentAlignment & Gravities.Top) != 0) + currentY = 0; + else if ((ContentAlignment & Gravities.Bottom) != 0) + currentY = Size.Y - _height; + + foreach (var element in Elements) + { + if (element.Hidden) + continue; + + Point elementPosition; + + if (HorizontalMode) + { + currentX += element.Margin.X; + elementPosition = new Point(currentX, centerY - element.Size.Y / 2); + currentX += element.Size.X + element.Margin.X; + } + else + { + currentY += element.Margin.Y; + elementPosition = new Point(centerX - element.Size.X / 2, currentY); + currentY += element.Size.Y + element.Margin.Y; + } + + element.Position = elementPosition; + } + } + } +} \ No newline at end of file diff --git a/InGame/Interface/InterfacePage.cs b/InGame/Interface/InterfacePage.cs new file mode 100644 index 0000000..0cccddf --- /dev/null +++ b/InGame/Interface/InterfacePage.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Controls; + +namespace ProjectZ.InGame.Interface +{ + public class InterfacePage + { + public InterfaceElement PageLayout; + + public virtual void OnLoad(Dictionary intent) { } + + public virtual void OnPop(Dictionary intent) { } + + public virtual void OnReturn(Dictionary intent) { } + + public virtual void Update(CButtons pressedButtons, GameTime gameTime) + { + PageLayout?.PressedButton(pressedButtons); + PageLayout?.Update(); + } + + public virtual void Draw(SpriteBatch spriteBatch, Vector2 position, int scale, float transparency) + { + PageLayout?.Draw(spriteBatch, position, scale, transparency); + } + } +} diff --git a/InGame/Interface/InterfaceSlider.cs b/InGame/Interface/InterfaceSlider.cs new file mode 100644 index 0000000..ade88e2 --- /dev/null +++ b/InGame/Interface/InterfaceSlider.cs @@ -0,0 +1,233 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Interface +{ + public class InterfaceSlider : InterfaceElement + { + public delegate void BFunction(int number); + public BFunction NumberChanged; + + public delegate string StringFunction(int number); + public StringFunction SetString; + + public SpriteFont Font; + public Color TextColor = Color.White; + + public string Text { get; set; } + private string TextPostfix; + + public int CurrentStep; + public int Start; + public int End; + public int StepSize; + + private static float _scrollCounter; + private static int _scrollStartTime = 350; + private static int _scrollTime = 75; + + private Color _colorSlider; + private Color _colorSliderBackground = new Color(79, 79, 79); + + private Rectangle _sliderBackgroundRectangle; + private Rectangle _sliderRectangle; + + private Vector2 _drawOffset; + private Vector2 _textSize; + + private Point _sliderSize = new Point(2, 2); + private string _textKey; + + private float _stepWidth; + private float _animationCounter; + private int _animationTime = 66; + private float _animationStepPosition; + private float _animationStepStart; + + private int _sliderHeight = 4; + private int _lastStep = -1; + private int _steps; + private bool _updateText; + + public InterfaceSlider() + { + Selectable = true; + + SelectionColor = Values.MenuButtonColorSelected; + + _colorSlider = Values.MenuButtonColorSlider; + } + + public InterfaceSlider(SpriteFont font, string key, int width, Point margin, int start, int end, int stepSize, int current, BFunction numberChanged) : this() + { + Font = font; + Size = new Point(width, 11 + 2 + _sliderSize.Y * 4); + Margin = margin; + + Start = start; + End = end; + StepSize = stepSize; + CurrentStep = current; + + NumberChanged = numberChanged; + + _sliderBackgroundRectangle = new Rectangle(_sliderSize.X * 2, 2, width - _sliderSize.X * 4, _sliderHeight); + + _sliderRectangle = new Rectangle( + _sliderSize.X, _sliderBackgroundRectangle.Y - _sliderSize.Y, + _sliderHeight + _sliderSize.X * 2, _sliderHeight + _sliderSize.Y * 2); + + _steps = End - Start + 1; + _stepWidth = (_sliderBackgroundRectangle.Width - 4) / ((float)_steps - 1); + + _animationStepPosition = _stepWidth * CurrentStep; + + if (key != null) + { + _textKey = key; + UpdateLanguageText(); + } + } + + public void UpdateStepSize(int start, int end, int steps) + { + if (start == Start && end == End) + return; + + _updateText = true; + + CurrentStep = MathHelper.Clamp(CurrentStep + Start, start, end) - start; + + Start = start; + End = end; + + _steps = steps; + _stepWidth = (_sliderBackgroundRectangle.Width - 4) / ((float)_steps - 1); + } + + public override InputEventReturn PressedButton(CButtons pressedButton) + { + _lastStep = CurrentStep; + + if (_scrollCounter < 0) + _scrollCounter += _scrollTime; + + if (ControlHandler.ButtonDown(CButtons.Left) || ControlHandler.ButtonDown(CButtons.Right)) + _scrollCounter -= Game1.DeltaTime; + else + _scrollCounter = _scrollStartTime; + + if (ControlHandler.ButtonPressed(CButtons.Left) || + ControlHandler.ButtonDown(CButtons.Left) && _scrollCounter < 0) + { + CurrentStep = MathHelper.Clamp(CurrentStep - StepSize, 0, _steps - 1); + + // start the animation + _animationCounter = _animationTime; + _animationStepStart = _stepWidth * _lastStep; + + NumberChanged?.Invoke(Start + CurrentStep); + + return InputEventReturn.Something; + } + + if (ControlHandler.ButtonPressed(CButtons.Right) || + ControlHandler.ButtonDown(CButtons.Right) && _scrollCounter < 0) + { + CurrentStep = MathHelper.Clamp(CurrentStep + StepSize, 0, _steps - 1); + + // start the animation + _animationCounter = _animationTime; + _animationStepStart = _stepWidth * _lastStep; + + NumberChanged?.Invoke(Start + CurrentStep); + + return InputEventReturn.Something; + } + + return InputEventReturn.Nothing; + } + + public void SetText(string strText) + { + Text = strText; + + if (SetString != null) + TextPostfix = SetString(Start + CurrentStep); + + _textSize = Font.MeasureString(Text + TextPostfix); + + if (Size != Point.Zero) + _drawOffset = new Vector2(Size.X / 2 - _textSize.X / 2, _textSize.Y); + } + + public void UpdateLanguageText() + { + SetText(Game1.LanguageManager.GetString(_textKey, "error")); + } + + public override void Update() + { + base.Update(); + + // update the animation + _animationCounter -= Game1.DeltaTime; + if (_animationCounter < 0) + _animationCounter = 0; + + _animationStepPosition = MathHelper.Lerp(_animationStepStart, _stepWidth * CurrentStep, + (float)Math.Sin((1 - _animationCounter / _animationTime) * Math.PI / 2)); + } + + public override void Draw(SpriteBatch spriteBatch, Vector2 drawPosition, float scale, float transparency) + { + base.Draw(spriteBatch, drawPosition, scale, transparency); + + Resources.RoundedCornerEffect.Parameters["scale"].SetValue(Game1.UiScale); + + spriteBatch.End(); + spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, null, Resources.RoundedCornerEffect, Game1.GetMatrix); + + Resources.RoundedCornerEffect.Parameters["radius"].SetValue(2.0f); + Resources.RoundedCornerEffect.Parameters["width"].SetValue(_sliderBackgroundRectangle.Width); + Resources.RoundedCornerEffect.Parameters["height"].SetValue(_sliderBackgroundRectangle.Height); + + // draw the toggle background line + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + (int)(drawPosition.X + _sliderBackgroundRectangle.X * scale), + (int)(drawPosition.Y + _sliderBackgroundRectangle.Y * scale + _drawOffset.Y * scale), + (int)(_sliderBackgroundRectangle.Width * scale), + (int)(_sliderBackgroundRectangle.Height * scale)), _colorSliderBackground * transparency); + + Resources.RoundedCornerEffect.Parameters["radius"].SetValue(2.0f); + Resources.RoundedCornerEffect.Parameters["width"].SetValue(_sliderRectangle.Width); + Resources.RoundedCornerEffect.Parameters["height"].SetValue(_sliderRectangle.Height); + + // draw the slider + var sliderPosition = (_sliderRectangle.X + _animationStepPosition); + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + (int)(drawPosition.X + sliderPosition * scale), + (int)(drawPosition.Y + _sliderRectangle.Y * scale + _drawOffset.Y * scale), + (int)(_sliderRectangle.Width * scale), + (int)(_sliderRectangle.Height * scale)), _colorSlider * transparency); + + spriteBatch.End(); + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, Game1.GetMatrix); + + if (_textKey != null && Game1.LanguageManager.GetString(_textKey, "error") != Text || CurrentStep != _lastStep || _updateText) + UpdateLanguageText(); + _updateText = false; + + if (Text == null) + return; + + // draw the text + spriteBatch.DrawString(Font, Text + TextPostfix, + new Vector2((int)(drawPosition.X + _drawOffset.X * scale), (int)(drawPosition.Y + scale)), + TextColor * transparency, 0, Vector2.Zero, new Vector2(scale), SpriteEffects.None, 0); + } + } +} \ No newline at end of file diff --git a/InGame/Interface/InterfaceToggle.cs b/InGame/Interface/InterfaceToggle.cs new file mode 100644 index 0000000..ae22826 --- /dev/null +++ b/InGame/Interface/InterfaceToggle.cs @@ -0,0 +1,143 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Interface +{ + public class InterfaceToggle : InterfaceElement + { + public delegate void BFunction(bool toggleState); + public BFunction ClickFunction; + + private readonly Color _colorToggledBackground; + private readonly Color _colorNotToggledBackground = new Color(188, 188, 188); + private readonly Color _colorToggled; + private readonly Color _colorNotToggled = new Color(79, 79, 79); + + private readonly Rectangle _toggleBackgroundRectangle; + private readonly Rectangle _toggleRectangle; + + private float _toggleAnimationState; + private float _toggleAnimationCounter; + + private const int ToggleAnimationTime = 100; + + private bool _toggleState; + + public bool ToggleState => _toggleState; + + public InterfaceToggle() + { + Color = Values.MenuButtonColor; + SelectionColor = Values.MenuButtonColorSelected; + + _colorToggledBackground = Values.MenuButtonColorSelected; + _colorToggled = Values.MenuButtonColorSlider; + } + + public InterfaceToggle(Point size, Point margin, bool startState, BFunction clickFunction) : this() + { + Size = size; + Margin = margin; + + _toggleState = startState; + + ClickFunction = clickFunction; + + _toggleBackgroundRectangle = new Rectangle(0, 0, size.X, size.Y); + _toggleRectangle = new Rectangle(2, 2, size.Y - 4, size.Y - 4); + + _toggleAnimationState = _toggleState ? 1 : 0; + } + + public static InterfaceListLayout GetToggleButton(Point size, Point margin, string textKey, bool startState, BFunction clickFunction) + { + var toggleLayout = new InterfaceListLayout() { Size = size, Margin = margin, HorizontalMode = true, Selectable = true }; + + var toggleSize = new Point((int)(size.Y * 1.75f), size.Y - 2); + var buttonSize = new Point(size.X - toggleSize.X - 4, size.Y); + + var toggle = new InterfaceToggle(toggleSize, new Point(2, 0), startState, clickFunction); + var button = new InterfaceButton(buttonSize, new Point(2, 0), textKey, buttonElement => toggle.Toggle()); + + toggleLayout.AddElement(button); + toggleLayout.AddElement(toggle); + + return toggleLayout; + } + + public override InputEventReturn PressedButton(CButtons pressedButton) + { + if (!ControlHandler.ButtonPressed(CButtons.A)) + return InputEventReturn.Nothing; + + Toggle(); + + return ClickFunction != null ? InputEventReturn.Something : InputEventReturn.Nothing; + } + + public void SetToggle(bool state) + { + _toggleState = state; + // no animation + _toggleAnimationCounter = 0; + } + + public void Toggle() + { + _toggleState = !_toggleState; + _toggleAnimationCounter = ToggleAnimationTime; + + ClickFunction?.Invoke(_toggleState); + } + + public override void Update() + { + base.Update(); + + // update the toggle animation + _toggleAnimationCounter -= Game1.DeltaTime; + if (_toggleAnimationCounter <= 0) + _toggleAnimationCounter = 0; + var percentage = (float)Math.Sin((1 - _toggleAnimationCounter / ToggleAnimationTime) * Math.PI / 2); + _toggleAnimationState = _toggleState ? percentage : 1 - percentage; + } + + public override void Draw(SpriteBatch spriteBatch, Vector2 drawPosition, float scale, float transparency) + { + Resources.RoundedCornerEffect.Parameters["scale"].SetValue(Game1.UiScale); + + spriteBatch.End(); + spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, null, Resources.RoundedCornerEffect, Game1.GetMatrix); + + Resources.RoundedCornerEffect.Parameters["radius"].SetValue(4.0f); + Resources.RoundedCornerEffect.Parameters["width"].SetValue(_toggleBackgroundRectangle.Width); + Resources.RoundedCornerEffect.Parameters["height"].SetValue(_toggleBackgroundRectangle.Height); + + // draw the toggle background + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + (int)(drawPosition.X + _toggleBackgroundRectangle.X * scale), + (int)(drawPosition.Y + _toggleBackgroundRectangle.Y * scale), + (int)(_toggleBackgroundRectangle.Width * scale), + (int)(_toggleBackgroundRectangle.Height * scale)), + (_toggleState ? _colorToggledBackground : _colorNotToggledBackground) * transparency); + + Resources.RoundedCornerEffect.Parameters["radius"].SetValue(4.0f); + Resources.RoundedCornerEffect.Parameters["width"].SetValue(_toggleRectangle.Width); + Resources.RoundedCornerEffect.Parameters["height"].SetValue(_toggleRectangle.Height); + + // draw the toggle + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + (int)(drawPosition.X + (_toggleRectangle.X + _toggleAnimationState * (_toggleBackgroundRectangle.Width - _toggleRectangle.Width - 4)) * scale), + (int)(drawPosition.Y + _toggleRectangle.Y * scale), + (int)(_toggleRectangle.Width * scale), + (int)(_toggleRectangle.Height * scale)), + (_toggleState ? _colorToggled : _colorNotToggled) * transparency); + + spriteBatch.End(); + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, Game1.GetMatrix); + } + } +} \ No newline at end of file diff --git a/InGame/Map/Camera.cs b/InGame/Map/Camera.cs new file mode 100644 index 0000000..785a82f --- /dev/null +++ b/InGame/Map/Camera.cs @@ -0,0 +1,146 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Map +{ + public class Camera + { + public Matrix TransformMatrix => Matrix.CreateScale(Scale) * + Matrix.CreateTranslation(new Vector3(-RoundX, -RoundY, 0)) * + Matrix.CreateTranslation(new Vector3((int)(_viewportWidth * 0.5f), (int)(_viewportHeight * 0.5f), 0)) * + Game1.GameManager.GetMatrix; + public Vector2 Location; + public Vector2 MoveLocation; + + // this is needed so there is no texture bleeding while rendering the game + public float RoundX => (int)Math.Round(Location.X + ShakeOffsetX * Scale, MidpointRounding.AwayFromZero); + public float RoundY => (int)Math.Round(Location.Y + ShakeOffsetY * Scale, MidpointRounding.AwayFromZero); + + public float Scale = 4; + public float ShakeOffsetX; + public float ShakeOffsetY; + public float CameraFollowMultiplier = 1; + + public int X => (int)Math.Round(Location.X + ShakeOffsetX * Scale); + public int Y => (int)Math.Round(Location.Y + ShakeOffsetY * Scale); + + private Vector2 _cameraDistance; + + private int _viewportWidth; + private int _viewportHeight; + + public void SetBounds(int viewportWidth, int viewportHeight) + { + _viewportWidth = viewportWidth; + _viewportHeight = viewportHeight; + } + + public Rectangle GetCameraRectangle() + { + var rectangle = new Rectangle( + (int)RoundX - _viewportWidth / 2, + (int)RoundY - _viewportHeight / 2, + _viewportWidth, _viewportHeight); + + return rectangle; + } + + public Rectangle GetGameView() + { + var rectangle = new Rectangle( + (int)(RoundX / Scale) - (int)(_viewportWidth / 2 / Scale), + (int)(RoundY / Scale) - (int)(_viewportHeight / 2 / Scale), + (int)(_viewportWidth / Scale), (int)(_viewportHeight / Scale)); + + return rectangle; + } + + public Rectangle GetGameViewBig() + { + var rectangle = new Rectangle( + (int)(RoundX / Scale) - Values.MinWidth, + (int)(RoundY / Scale) - Values.MinHeight, + Values.MinWidth * 2, Values.MinHeight * 2); + + return rectangle; + } + + public void Center(Vector2 position, bool moveX, bool moveY) + { + if (!GameSettings.SmoothCamera) + { + Location = position; + return; + } + + var direction = position - MoveLocation; + + if (direction != Vector2.Zero) + { + var distance = direction.Length() / Scale * CameraFollowMultiplier; + var speedMult = CameraFunction(distance / 12.5f); + + direction.Normalize(); + var cameraSpeed = direction * speedMult * Scale * Game1.TimeMultiplier; + + if (moveX) + MoveLocation.X += cameraSpeed.X; + if (moveY) + MoveLocation.Y += cameraSpeed.Y; + + if (distance <= 0.1f * Game1.TimeMultiplier) + MoveLocation = position; + } + + // this is needed so the player does not wiggle around while the camera is following him + if (moveX) + _cameraDistance.X = position.X - MoveLocation.X; + if (moveY) + _cameraDistance.Y = position.Y - MoveLocation.Y; + + Location = new Vector2((int)Math.Round(position.X), (int)Math.Round(position.Y)) - _cameraDistance; + } + + private float CameraFunction(float x) + { + var y = MathF.Atan(x); + + if (x > 2) + y += (x - 2) / 2; + + return y + 0.1f; + } + + public void ForceUpdate(Vector2 lockPosition) + { + MoveLocation = lockPosition; + Location = lockPosition; + } + + public void SoftUpdate(Vector2 position) + { + MoveLocation = position - _cameraDistance; + Location = position; + } + + public void OffsetCameraDistance(Vector2 offset) + { + _cameraDistance += offset; + } + + public void Draw(SpriteBatch spriteBatch) + { + if (!Game1.DebugMode) + return; + + var size = 10; + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + Game1.WindowWidthEnd / 2 - (int)(size * Scale), + Game1.WindowHeightEnd / 2 - (int)(size * Scale), + (int)(size * Scale * 2), + (int)(size * Scale * 2)), Color.Pink * 0.25f); + } + } +} diff --git a/InGame/Map/FieldStates.cs b/InGame/Map/FieldStates.cs new file mode 100644 index 0000000..c167991 --- /dev/null +++ b/InGame/Map/FieldStates.cs @@ -0,0 +1,32 @@ +using System; + +namespace ProjectZ.InGame.Map +{ + public class MapStates + { + [Flags] + public enum FieldStates + { + None = 0, + Init = 1, + Grass = 2, + Water = 4, + DeepWater = 8, + Lava = 16, + + UpperLevel = 32 | 64, + Level1 = 32, + Level2 = 64, + } + + public static int GetLevel(FieldStates state) + { + if ((state & FieldStates.Level1) != 0) + return 1; + if ((state & FieldStates.Level2) != 0) + return 2; + + return 0; + } + } +} \ No newline at end of file diff --git a/InGame/Map/Map.cs b/InGame/Map/Map.cs new file mode 100644 index 0000000..73f4072 --- /dev/null +++ b/InGame/Map/Map.cs @@ -0,0 +1,370 @@ +using Microsoft.Xna.Framework; +using ProjectZ.Base; +using ProjectZ.Editor; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Things; +using System; +using System.Collections.Generic; + +namespace ProjectZ.InGame.Map +{ + public class Map + { + public TileMap TileMap; + public TileMap HoleMap; + public string[,] DigMap; + + public ObjectManager Objects; + + public MapStates.FieldStates[,] StateMap; + public Vector2? CameraTarget; + + private Point _lastFieldPosition; + public int[,] UpdateMap; + + public Color LightColor; + + public string MapName; + public string MapFileName; + + // TODO_Opt: this is currently only set in dungeons + // this should probably be saved inside each mapfile + public string LocationName; + public string LocationFullName; + + public float LightState; + + public int MapWidth => TileMap.ArrayTileMap?.GetLength(0) ?? 0; + public int MapHeight => TileMap.ArrayTileMap?.GetLength(1) ?? 0; + + public int MapOffsetX; + public int MapOffsetY; + + public int[] MapMusic = new[] { -1, -1, -1 }; + + public float ShadowHeight; + public float ShadowRotation; + + public bool Is2dMap; + public bool DungeonMode; + public bool UseLight; + public bool UseShadows; + public bool IsOverworld; + + private List _digList = new List(); + + public Map() + { + TileMap = new TileMap(); + HoleMap = new TileMap(); + Objects = new ObjectManager(this); + } + + public static Map CreateEmptyMap() + { + var emptyMap = new Map(); + + emptyMap.Objects.Clear(); + emptyMap.Objects.LoadObjects(); + + emptyMap.StateMap = new MapStates.FieldStates[1, 1]; + emptyMap.UpdateMap = new int[1, 1]; + + return emptyMap; + } + + public void Reset() + { + CameraTarget = null; + Is2dMap = false; + IsOverworld = false; + DungeonMode = false; + LocationName = null; + UseLight = false; + MapMusic = new[] { -1, -1, -1 }; + UseShadows = true; + LightState = 0; + + ShadowHeight = Values.ShadowHeightDefault; + ShadowRotation = Values.ShadowRotationDefault; + } + + public void SetFieldState(int posX, int posY, MapStates.FieldStates newState) + { + if (0 <= posX && posX < StateMap.GetLength(0) && + 0 <= posY && posY < StateMap.GetLength(1)) + StateMap[posX, posY] = newState; + } + + public void AddFieldState(int posX, int posY, MapStates.FieldStates addState) + { + if (0 <= posX && posX < StateMap.GetLength(0) && + 0 <= posY && posY < StateMap.GetLength(1)) + StateMap[posX, posY] |= addState; + } + + public void RemoveFieldState(int posX, int posY, MapStates.FieldStates removeState) + { + if (0 <= posX && posX < StateMap.GetLength(0) && + 0 <= posY && posY < StateMap.GetLength(1)) + StateMap[posX, posY] &= ~removeState; + } + + public MapStates.FieldStates GetFieldState(int posX, int posY) + { + if (0 <= posX && posX < StateMap.GetLength(0) && + 0 <= posY && posY < StateMap.GetLength(1)) + return StateMap[posX, posY]; + + return MapStates.FieldStates.None; + } + + public MapStates.FieldStates GetFieldState(Vector2 centerF) + { + if (centerF.X < 0 || centerF.Y < 0) + return MapStates.FieldStates.None; + + var posX = (int)(centerF.X / 16); + var posY = (int)(centerF.Y / 16); + return GetFieldState(posX, posY); + } + + public int GetUpdateState(Vector2 center) + { + var posX = (int)(center.X - MapOffsetX * Values.TileSize) / Values.FieldWidth; + var posY = (int)(center.Y - MapOffsetY * Values.TileSize) / Values.FieldHeight; + return GetUpdateState(posX, posY); + } + + public int GetUpdateState(int posX, int posY) + { + if (0 <= posX && posX < UpdateMap.GetLength(0) && + 0 <= posY && posY < UpdateMap.GetLength(1)) + return UpdateMap[posX, posY]; + + return 0; + } + + public void ChangeUpdateState(int posX, int posY, int addition) + { + if (0 <= posX && posX < UpdateMap.GetLength(0) && + 0 <= posY && posY < UpdateMap.GetLength(1)) + UpdateMap[posX, posY] += addition; + } + + public void UpdateMapUpdateState() + { + var cameraPosition = new Vector2(MapManager.ObjLink.PosX, MapManager.ObjLink.PosY - 4); + var fieldPosition = new Point( + (int)(cameraPosition.X - MapOffsetX * Values.TileSize) / Values.FieldWidth, + (int)(cameraPosition.Y - MapOffsetY * Values.TileSize) / Values.FieldHeight); + + // increment the update counter for the fields the player left + for (var y = _lastFieldPosition.Y - 2; y <= _lastFieldPosition.Y + 2; y++) + for (var x = _lastFieldPosition.X - 2; x <= _lastFieldPosition.X + 2; x++) + { + if (Math.Abs(x - fieldPosition.X) > 2 || + Math.Abs(y - fieldPosition.Y) > 2) + { + ChangeUpdateState(x, y, 1); + ClearHoleMap(x, y); + } + } + + _lastFieldPosition = fieldPosition; + } + + private void ClearHoleMap(int posX, int posY) + { + if (HoleMap.ArrayTileMap == null) + return; + + if (posX < 0 || HoleMap.ArrayTileMap.GetLength(0) < (posX + 1) * 10 || + posY < 0 || HoleMap.ArrayTileMap.GetLength(1) < (posY + 1) * 8) + return; + + for (var y = 0; y < 8; y++) + for (var x = 0; x < 10; x++) + { + HoleMap.ArrayTileMap[posX * 10 + x, posY * 8 + y, 0] = -1; + } + } + + public void ResizeMap(int newWidth, int newHeight, int posX, int posY) + { + var newTileMap = new TileMap(); + newTileMap.SetTileset(TileMap.SprTileset, TileMap.TileSize); + newTileMap.TilesetPath = TileMap.TilesetPath; + + var depth = TileMap.ArrayTileMap.GetLength(2); + newTileMap.ArrayTileMap = new int[newWidth, newHeight, depth]; + + for (var z = 0; z < newTileMap.ArrayTileMap.GetLength(2); z++) + for (var y = 0; y < newTileMap.ArrayTileMap.GetLength(1); y++) + for (var x = 0; x < newTileMap.ArrayTileMap.GetLength(0); x++) + newTileMap.ArrayTileMap[x, y, z] = -1; + + for (var z = 0; z < TileMap.ArrayTileMap.GetLength(2); z++) + { + for (var y = 0; y < TileMap.ArrayTileMap.GetLength(1); y++) + { + for (var x = 0; x < TileMap.ArrayTileMap.GetLength(0); x++) + { + if (0 <= posX + x && posX + x < newWidth && + 0 <= posY + y && posY + y < newHeight && + 0 <= z && z < depth) + newTileMap.ArrayTileMap[posX + x, posY + y, z] = TileMap.ArrayTileMap[x, y, z]; + } + } + } + + TileMap = newTileMap; + + // @TODO: this does not set the new parts to "" + OffsetDigMap(newWidth, newHeight, posX, posY); + + // offset the objects + ObjectEditorScreen.OffsetObjects(this, posX * Values.TileSize, posY * Values.TileSize); + } + + private void OffsetDigMap(int newWidth, int newHeight, int posX, int posY) + { + var newDigMap = new string[newWidth, newHeight]; + + for (var y = 0; y < DigMap.GetLength(1); y++) + for (var x = 0; x < DigMap.GetLength(0); x++) + { + if (0 <= posX + x && posX + x < newWidth && + 0 <= posY + y && posY + y < newHeight) + newDigMap[posX + x, posY + y] = DigMap[x, y]; + } + + DigMap = newDigMap; + } + + public Vector2 GetRoomCenter(float x, float y) + { + return new Vector2( + ((int)((x - MapOffsetX * Values.TileSize) / Values.FieldWidth) + 0.5f) * Values.FieldWidth + MapOffsetX * Values.TileSize, + ((int)((y - MapOffsetY * Values.TileSize) / Values.FieldHeight) + 0.5f) * Values.FieldHeight + MapOffsetY * Values.TileSize); + } + + public Rectangle GetField(int x, int y, int margin) + { + return new Rectangle( + (x - MapOffsetX * Values.TileSize) / Values.FieldWidth * Values.FieldWidth + margin + MapOffsetX * Values.TileSize, + (y - MapOffsetY * Values.TileSize) / Values.FieldHeight * Values.FieldHeight + margin + MapOffsetY * Values.TileSize, + Values.FieldWidth - 2 * margin, Values.FieldHeight - 2 * margin); + } + + public Rectangle GetField(int x, int y) + { + return GetField(x, y, 0); + } + + public Box GetFieldBox(int x, int y, int height, int margin) + { + return new Box( + (x - MapOffsetX * Values.TileSize) / Values.FieldWidth * Values.FieldWidth + margin + MapOffsetX * Values.TileSize, + (y - MapOffsetY * Values.TileSize) / Values.FieldHeight * Values.FieldHeight + margin + MapOffsetY * Values.TileSize, 0, + Values.FieldWidth - 2 * margin, Values.FieldHeight - 2 * margin, height); + } + + public Box GetFieldBox(int x, int y, int height) + { + return GetFieldBox(x, y, height, 0); + } + + public bool CanDig(Point position) + { + // no grass or water? can dig? was already dug? + if (0 > position.X || position.X >= HoleMap.ArrayTileMap.GetLength(0) || + 0 > position.Y || position.Y >= HoleMap.ArrayTileMap.GetLength(1) || + (StateMap[position.X, position.Y] | MapStates.FieldStates.UpperLevel) != MapStates.FieldStates.UpperLevel || + HoleMap.ArrayTileMap[position.X, position.Y, 0] >= 0 || + position.X < DigMap.GetLength(0) && + position.Y < DigMap.GetLength(1) && + string.IsNullOrEmpty(DigMap[position.X, position.Y])) + { + return false; + } + else + { + // check if there is something blocking the digging + _digList.Clear(); + var digBox = new Box(position.X * 16 + 2, position.Y * 16 + 2, 0, 12, 12, 8); + Objects.GetComponentList(_digList, (int)digBox.X, (int)digBox.Y, 12, 12, CollisionComponent.Mask); + var collidingBox = Box.Empty; + foreach (var gameObject in _digList) + { + var collisionObject = gameObject.Components[CollisionComponent.Index] as CollisionComponent; + if (collisionObject.Owner.IsActive && + (collisionObject.CollisionType & (Values.CollisionTypes.Normal | Values.CollisionTypes.Hole)) != 0 && + collisionObject.Collision(digBox, 0, 0, ref collidingBox)) + { + return false; + } + } + } + + return true; + } + + public void Dig(Point position, Vector2 diggerPosition, int dir) + { + string strObject = null; + string strSaveKey = null; + + var digTileIndex = 0; + + var itemString = DigMap[position.X, position.Y]; + if (int.TryParse(itemString, out int result)) + { + var random = Game1.RandomNumber.Next(0, 100); + if (random < 6) + strObject = "ruby"; + else if (random < 9) + strObject = "heart"; + + digTileIndex = result - 1; + } + else if (!string.IsNullOrEmpty(itemString)) + { + var split = itemString.Split(':'); + strObject = split[0]; + if (split.Length >= 2) + strSaveKey = split[1]; + if (split.Length >= 3) + { + if (int.TryParse(split[2], out int tileIndex)) + digTileIndex = tileIndex - 1; + } + } + + // spawn a heart or a ruby + if (strObject != null) + { + // calculate the item hop direction + var itemPosition = new Vector2(position.X * Values.TileSize + 8, position.Y * Values.TileSize + 12); + var direction = itemPosition - diggerPosition; + if (direction != Vector2.Zero) + direction.Normalize(); + direction = direction * 0.75f + AnimationHelper.DirectionOffset[dir] * 0.75f; + + var objItem = new ObjItem(this, 0, 0, "j", strSaveKey, strObject, null, true); + if (!objItem.IsDead) + { + objItem.EntityPosition.Set(itemPosition); + objItem.SetVelocity(new Vector3(direction.X, direction.Y, 1.25f)); + Objects.SpawnObject(objItem); + } + } + + Game1.GameManager.StartDialogPath("dig_dialog"); + + HoleMap.ArrayTileMap[position.X, position.Y, 0] = digTileIndex; + } + } +} diff --git a/InGame/Map/MapManager.cs b/InGame/Map/MapManager.cs new file mode 100644 index 0000000..7082366 --- /dev/null +++ b/InGame/Map/MapManager.cs @@ -0,0 +1,240 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Map +{ + public class MapManager + { + public static Camera Camera; + public static ObjLink ObjLink; + + public static BlendState LightBlendState = new BlendState(); + + public Map CurrentMap; + public Map NextMap; + + public bool UpdateCameraX; + public bool UpdateCameraY; + + private Matrix blurMatrix; + + public MapManager() + { + CurrentMap = new Map(); + NextMap = new Map(); + Camera = new Camera(); + + LightBlendState.ColorBlendFunction = BlendFunction.Add; + LightBlendState.ColorDestinationBlend = Blend.InverseSourceAlpha; + LightBlendState.ColorSourceBlend = Blend.One; + + LightBlendState.AlphaBlendFunction = BlendFunction.Max; + LightBlendState.AlphaDestinationBlend = Blend.One; + LightBlendState.AlphaSourceBlend = Blend.One; + } + + public void Load() + { + ObjLink = new ObjLink(); + } + + public void Update(bool frozen) + { + // update the objects on the map + CurrentMap.Objects.Update(frozen); + + CurrentMap.UpdateMapUpdateState(); + + UpdateCamera(); + } + + public void UpdateAnimation() + { + CurrentMap.Objects.UpdateAnimations(); + } + + public Vector2 GetCameraTarget() + { + // update the camera + if (CurrentMap.CameraTarget.HasValue) + return CurrentMap.CameraTarget.Value * Camera.Scale; + + return GetCameraTargetLink(); + } + + public Vector2 GetCameraTargetLink() + { + return new Vector2(ObjLink.PosX, ObjLink.PosY - 4) * Camera.Scale; + } + + public void UpdateCamera() + { + //if (!UpdateCameraX) + //centerPosition.Y -= ObjLink.EntityPosition.Z; + + // center the map vertical if it is smaller than the screen + // not so sure about this + //if (CurrentMap.MapHeight * 16 * Camera.Scale < Game1.WindowHeight) + // centerPosition.Y = CurrentMap.MapHeight * 8 * Camera.Scale; + + if (UpdateCameraX || UpdateCameraY) + Camera.Center(GetCameraTarget(), UpdateCameraX, UpdateCameraY); + + UpdateCameraX = true; + UpdateCameraY = true; + } + + public void Draw(SpriteBatch spriteBatch) + { + // draw the objects under the tilemap + CurrentMap.Objects.DrawBottom(spriteBatch); + + //Game1.StopWatchTracker.Start("draw tile layers"); + + // draw the tile map + CurrentMap.TileMap.Draw(spriteBatch); + + //Game1.StopWatchTracker.Stop(); + + // draw the objects draw over the tileset + CurrentMap.Objects.DrawMiddle(spriteBatch); + + // draw the blured part of the tile map + DrawBlur(spriteBatch, Game1.GameManager.TempRT2, Game1.GameManager.TempRT0, Game1.GameManager.TempRT1); + + // draw the objects + CurrentMap.Objects.Draw(spriteBatch); + + spriteBatch.End(); + } + + public void DrawBegin(SpriteBatch spriteBatch, Effect spriteEffect) + { + if (!Game1.GameManager.UseShockEffect) + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, spriteEffect, blurMatrix); + else + ObjectManager.SpriteBatchBegin(spriteBatch, null); + } + + private void DrawBlur(SpriteBatch spriteBatch, RenderTarget2D blurRT0, RenderTarget2D blurRT1, RenderTarget2D blurRT2) + { + var matrixPosition = Vector2.Zero; + + if (!Game1.GameManager.UseShockEffect) + { + Game1.Graphics.GraphicsDevice.SetRenderTarget(blurRT0); + Game1.Graphics.GraphicsDevice.Clear(Color.Transparent); + + var cameraPosition = new Vector2(Camera.RoundX / Camera.Scale, Camera.RoundY / Camera.Scale); + // offset the position a little bit because we render a bigger region to avoid artefacts at the edges + matrixPosition = new Vector2((int)cameraPosition.X - 1, (int)cameraPosition.Y - 1); + + blurMatrix = Matrix.CreateScale(1) * + Matrix.CreateTranslation(new Vector3(-matrixPosition.X, -matrixPosition.Y, 0)) * + Matrix.CreateTranslation(new Vector3( + (int)(Game1.GameManager.SideBlurRenderTargetWidth * 0.5f), + (int)(Game1.GameManager.SideBlurRenderTargetHeight * 0.5f), 0)) * + Matrix.CreateScale(new Vector3( + (float)blurRT0.Width / Game1.GameManager.SideBlurRenderTargetWidth, + (float)blurRT0.Height / Game1.GameManager.SideBlurRenderTargetHeight, 0)); + } + + DrawBegin(spriteBatch, null); + + // draw object blur stuff + CurrentMap.Objects.DrawBlur(spriteBatch); + + // blur tile maps + CurrentMap.TileMap.DrawBlurLayer(spriteBatch); + + spriteBatch.End(); + + if (Game1.GameManager.UseShockEffect) + return; + + Resources.BBlurEffectH.Parameters["pixelX"].SetValue(1.0f / blurRT1.Width); + Resources.BBlurEffectV.Parameters["pixelY"].SetValue(1.0f / blurRT1.Height); + + // v blur + Game1.Graphics.GraphicsDevice.SetRenderTarget(blurRT1); + Game1.Graphics.GraphicsDevice.Clear(Color.Transparent); + // offset the render target so that we always sample at the same position + var blurX = -(matrixPosition.X % 2) / 2 + (blurRT1.Width % 2 * 0.5f); + var blurY = -(matrixPosition.Y % 2) / 2 + (blurRT1.Height % 2 * 0.5f); + spriteBatch.Begin(SpriteSortMode.Immediate, null, SamplerState.AnisotropicClamp, null, null, Resources.BBlurEffectV, null); + spriteBatch.Draw(blurRT0, new Vector2(blurX, blurY), + new Rectangle(0, 0, blurRT0.Width, blurRT0.Height), Color.White, 0, Vector2.Zero, 0.5f, SpriteEffects.None, 0); + spriteBatch.End(); + + // h blur + Game1.Graphics.GraphicsDevice.SetRenderTarget(blurRT2); + Game1.Graphics.GraphicsDevice.Clear(Color.Transparent); + spriteBatch.Begin(SpriteSortMode.Immediate, null, SamplerState.AnisotropicClamp, null, null, Resources.BBlurEffectH, null); + spriteBatch.Draw(blurRT1, Vector2.Zero, Color.White); + spriteBatch.End(); + + Game1.GameManager.SetActiveRenderTarget(); + + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.AnisotropicClamp, null, null, null, Camera.TransformMatrix); + + // calculate offset to make sure that the render target is at the correct position + var scale = new Vector2((float)Game1.GameManager.BlurRenderTargetWidth / blurRT1.Width * 2, (float)Game1.GameManager.BlurRenderTargetHeight / blurRT1.Height * 2); + spriteBatch.Draw(blurRT2, new Vector2( + matrixPosition.X + matrixPosition.X % 2 - (int)(Game1.GameManager.SideBlurRenderTargetWidth * 0.5f) - (int)(Game1.RenderWidth / (Camera.Scale * 2)) % 2, + matrixPosition.Y + matrixPosition.Y % 2 - (int)(Game1.GameManager.SideBlurRenderTargetHeight * 0.5f) - (int)(Game1.RenderHeight / (Camera.Scale * 2)) % 2), + new Rectangle(0, 0, blurRT2.Width, blurRT2.Height), Color.White, 0, Vector2.Zero, scale, SpriteEffects.None, 0); + + spriteBatch.End(); + } + + public void DrawLight(SpriteBatch spriteBatch) + { + Game1.Graphics.GraphicsDevice.Clear(CurrentMap.LightColor); + + spriteBatch.Begin(SpriteSortMode.Deferred, LightBlendState, SamplerState.AnisotropicClamp, null, null, null, Camera.TransformMatrix); + + CurrentMap.Objects.DrawLight(spriteBatch); + + spriteBatch.End(); + } + + public void ReloadMap() + { + // @Hack + var tempTm = CurrentMap; + CurrentMap = NextMap; + NextMap = tempTm; + + NextMap.Objects.ReloadObjects(); + NextMap.Objects.SpawnObject(ObjLink); + + // reset the hole map + SaveLoadMap.CreateEmptyHoleMap(NextMap.HoleMap, NextMap.MapWidth, NextMap.MapHeight); + + ObjLink.MapInit(); + + tempTm = CurrentMap; + CurrentMap = NextMap; + NextMap = tempTm; + + CurrentMap.Objects.TriggerKeyChange(); + } + + public void FinishLoadingMap(Map map) + { + ObjLink.Map.Objects.RemoveObject(ObjLink); + + // set the player to the correct position + ObjLink.FinishLoadingMap(map); + + // add the player to the map + map.Objects.SpawnObject(ObjLink); + + // call key change event for the newly added objects + map.Objects.TriggerKeyChange(); + } + } +} diff --git a/InGame/Map/ObjectManager.cs b/InGame/Map/ObjectManager.cs new file mode 100644 index 0000000..8af3e67 --- /dev/null +++ b/InGame/Map/ObjectManager.cs @@ -0,0 +1,983 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.InGame.GameObjects; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Base.Pools; +using ProjectZ.InGame.GameObjects.Base.Systems; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Map +{ + public class ObjectManager + { + // TODO_End check if everything is cleaned while loading a new map + public Map Owner; + + public List ObjectList = new List(); + private List SpawnObjects = new List(); + public List DeleteObjects = new List(); + + public Texture2D ShadowTexture; + public static Effect CurrentEffect; + + private List _poolSpawnedObjects = new List(); + + private ComponentPool _gameObjectPool; + private ComponentDrawPoolNew _drawPool; + + private SystemBody _systemBody = new SystemBody(); + private SystemAi _systemAi = new SystemAi(); + private SystemAnimation _systemAnimator = new SystemAnimation(); + + private List _keyChangeListeners = + new List(); + + // lists are used to not generate new ones every time + // one list object would probably be enough? + private readonly List _updateGameObject = new List(); + private readonly List _damageFieldObjects = new List(); + private readonly List _drawShadowObjects = new List(); + private readonly List _depthObjectList = new List(); + private readonly List _objectTypeList = new List(); + private readonly List _objectTagAllList = new List(); + private readonly List _collisionObjectList = new List(); + + private readonly List _collidingObjectList = new List(); + private readonly List _lightObjectList = new List(); + private readonly List _carriableObjectList = new List(); + private readonly List _hittableObjectList = new List(); + private readonly List _pushableObjectList = new List(); + private readonly List _interactableObjectList = new List(); + + private readonly List db_hittableList = new List(); + private readonly List db_damageList = new List(); + private readonly List db_bodyList = new List(); + private readonly List db_gameObjectList = new List(); + + private bool _keyChanged; + private bool _finishedLoading; + + public ObjectManager(Map owner) + { + Owner = owner; + } + + public void LoadObjects() + { + // TODO_End tweak the size for best performance for the finished game + // the size of the pools can be tweaked for faster update times + _gameObjectPool = new ComponentPool(Owner, Owner.MapWidth, Owner.MapHeight, 32, 32); + _drawPool = new ComponentDrawPoolNew(Owner.MapWidth, Owner.MapHeight, 32, 32); + + _systemAnimator.Pool = _gameObjectPool; + _systemAi.Pool = _gameObjectPool; + _systemBody.Pool = _gameObjectPool; + + ClearPools(); + + foreach (var gameObj in ObjectList) + { + var gameObject = GetGameObject(Owner, gameObj.Index, gameObj.Parameter); + AddObjectToMap(gameObject); + } + + // done after calling the constructors before the init methode + // stonespawner adds sprites that can be accessed in the init methode + // we make sure to not call the init methodes to not call it twice + AddSpawnedObjects(true); + + // okay so one problem are the dodongo snakes: + // a chest should get spawned after killing two of them + // but after reloading the chest should not be there + // so the snakes will reset a key on reload + // now the key condition setter sets the key + // and the position dialog spawns the chest + // so in the init method the key needs to be set correctly + // for this to work the key condition setter will need to be updated after the snakes are created + // for this we need to call the key listeners before calling the init method + UpdateKeyListeners(); + + foreach (var gameObject in _poolSpawnedObjects) + gameObject.Init(); + + // ensures key setters, key condition setter, etc are all set correctly after loading the objects + UpdateKeyListeners(); + + // done before and after init because ObjEnemyTrigger Init expects objects spawned in the constructor + AddSpawnedObjects(); + + _finishedLoading = true; + } + + public void Update(bool frozen) + { + // mode used for opened dialog + if (frozen) + { + // notify all key listener + UpdateKeyListeners(); + + UpdateDeleteObjects(); + + AddSpawnedObjects(); + + return; + } + + if (Game1.GameManager.FreezeWorldAroundPlayer) + { + Game1.GameManager.FreezeWorldAroundPlayer = false; + + // only update the player + var updateComponent = (UpdateComponent)MapManager.ObjLink.Components[UpdateComponent.Index]; + updateComponent?.UpdateFunction(); + + return; + } + + Game1.StopWatchTracker.Start("update gameobjects"); + + _systemAnimator.Update(false); + + UpdateGameObjects(); + + _systemAi.Update(); + + // notify all key listener + UpdateKeyListeners(); + + _systemBody.Update(0, 1); + + UpdatePlayerCollision(); + + UpdateDamageFields(); + + UpdateDeleteObjects(); + + AddSpawnedObjects(); + } + + public void UpdateAnimations() + { + _systemAnimator.Update(true); + } + + private void AddSpawnedObjects(bool suppressInit = false) + { + // add newly spawned objects + if (SpawnObjects.Count > 0) + { + // ObjChest is adding to the SpawnObjects list in it's init method + for (var index = 0; index < SpawnObjects.Count; index++) + { + if (!suppressInit) + SpawnObjects[index].Init(); + AddObjectToMap(SpawnObjects[index]); + } + + SpawnObjects.Clear(); + } + } + + private void UpdateGameObjects() + { + _updateGameObject.Clear(); + + // only update the objects that are in a tile that is visible + var updateFieldSize = new Vector2(Game1.RenderWidth, Game1.RenderHeight); + _gameObjectPool.GetComponentList(_updateGameObject, + (int)((MapManager.Camera.X - updateFieldSize.X / 2) / MapManager.Camera.Scale), + (int)((MapManager.Camera.Y - updateFieldSize.Y / 2) / MapManager.Camera.Scale), + (int)(updateFieldSize.X / MapManager.Camera.Scale), + (int)(updateFieldSize.Y / MapManager.Camera.Scale), UpdateComponent.Mask); + + foreach (var gameObject in _updateGameObject) + { + if (gameObject.IsActive) + (gameObject.Components[UpdateComponent.Index] as UpdateComponent)?.UpdateFunction(); + } + } + + private void UpdateKeyListeners() + { + // notify all key listeners + // repeat the process so key changes that depend on different key changes get processed in a single frame + // max is used to avoid an infinite loop in case of a bug + var max = 5; + while (_keyChanged && max > 0) + { + max--; + _keyChanged = false; + + // notify key listeners if a key value was changed + foreach (var listener in _keyChangeListeners) + listener(); + } + } + + private void UpdatePlayerCollision() + { + // player collides with stuff + var player = MapManager.ObjLink; + + _collidingObjectList.Clear(); + _gameObjectPool.GetComponentList(_collidingObjectList, + (int)player.BodyRectangle.X, (int)player.BodyRectangle.Y, + (int)player.BodyRectangle.Width, (int)player.BodyRectangle.Height, ObjectCollisionComponent.Mask); + + foreach (var gameObject in _collidingObjectList) + { + if (!gameObject.IsActive) + continue; + + var component = gameObject.Components[ObjectCollisionComponent.Index] as ObjectCollisionComponent; + if (component.TriggerOnCollision && component.CollisionRectangle.Rectangle.Intersects(player.BodyRectangle) || + !component.TriggerOnCollision && component.CollisionRectangle.Rectangle.Contains(player.BodyRectangle)) + component.OnCollision(player); + } + } + + private void UpdateDamageFields() + { + var player = MapManager.ObjLink; + var playerDamageBox = player.DamageCollider.Box; + + // get the objects that could potentially inflic damage + _damageFieldObjects.Clear(); + _gameObjectPool.GetComponentList(_damageFieldObjects, + (int)playerDamageBox.X, (int)playerDamageBox.Y, + (int)playerDamageBox.Width, (int)playerDamageBox.Height, DamageFieldComponent.Mask); + + foreach (var gameObject in _damageFieldObjects) + { + if (!gameObject.IsActive) + continue; + + var damageField = (gameObject.Components[DamageFieldComponent.Index] as DamageFieldComponent); + if (damageField.IsActive && damageField.CollisionBox.Box.Intersects(playerDamageBox)) + damageField.OnDamage?.Invoke(); + } + } + + private void UpdateDeleteObjects() + { + Game1.StopWatchTracker.Start("delete gameObjects"); + + if (DeleteObjects.Count > 0) + { + foreach (var deletable in DeleteObjects) + RemoveObject(deletable); + + DeleteObjects.Clear(); + } + + Game1.StopWatchTracker.Stop(); + } + + public static void SpriteBatchBegin(SpriteBatch spriteBatch, SpriteShader spriteShader) + { + SetSpriteShader(spriteShader); + + CurrentEffect = spriteShader?.Effect; + spriteBatch.Begin(SpriteSortMode.Deferred, null, + MapManager.Camera.Scale >= 1 ? SamplerState.PointWrap : SamplerState.AnisotropicWrap, + null, null, CurrentEffect, MapManager.Camera.TransformMatrix); + } + + public static void SetSpriteShader(SpriteShader spriteShader) + { + // update the parameters of the shader + if (spriteShader != null) + foreach (var parameter in spriteShader.FloatParameter) + spriteShader.Effect.Parameters[parameter.Key].SetValue(parameter.Value); + } + + public static void SpriteBatchBeginAnisotropic(SpriteBatch spriteBatch, Effect effect) + { + CurrentEffect = effect; + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.AnisotropicClamp, + null, null, effect, MapManager.Camera.TransformMatrix); + } + + public void DrawBottom(SpriteBatch spriteBatch) + { + if (!_finishedLoading) + return; + + Game1.StopWatchTracker.Start("2 draw sorted objects"); + + SpriteBatchBegin(spriteBatch, null); + + _drawPool.DrawPool(spriteBatch, + (int)((MapManager.Camera.X - Game1.RenderWidth / 2) / MapManager.Camera.Scale), + (int)((MapManager.Camera.Y - Game1.RenderHeight / 2) / MapManager.Camera.Scale), + (int)(Game1.RenderWidth / MapManager.Camera.Scale), + (int)(Game1.RenderHeight / MapManager.Camera.Scale), 0, 1); + + spriteBatch.End(); + } + + public void DrawMiddle(SpriteBatch spriteBatch) + { + if (!_finishedLoading) + return; + + Game1.StopWatchTracker.Start("2 draw sorted objects shadow"); + + SpriteBatchBegin(spriteBatch, null); + + _drawPool.DrawPool(spriteBatch, + (int)((MapManager.Camera.X - Game1.RenderWidth / 2) / MapManager.Camera.Scale), + (int)((MapManager.Camera.Y - Game1.RenderHeight / 2) / MapManager.Camera.Scale), + (int)(Game1.RenderWidth / MapManager.Camera.Scale), + (int)(Game1.RenderHeight / MapManager.Camera.Scale), 1, 2); + spriteBatch.End(); + + // draw the hole map + Owner.HoleMap.Draw(spriteBatch); + + Game1.StopWatchTracker.Start("3 draw the shadows"); + if (GameSettings.EnableShadows && Owner.UseShadows && !Game1.GameManager.UseShockEffect && ShadowTexture != null) + { + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.AnisotropicClamp);//, null, null, null, Game1.GameManager.GetMatrix); + spriteBatch.Draw(ShadowTexture, new Rectangle(0, 0, Game1.GameManager.CurrentRenderWidth, Game1.GameManager.CurrentRenderHeight), Color.Black * 0.55f); + spriteBatch.End(); + } + } + + public void Draw(SpriteBatch spriteBatch) + { + if (!_finishedLoading) + return; + + Game1.StopWatchTracker.Start("4 draw sorted objects"); + spriteBatch.Begin(SpriteSortMode.Deferred, null, + MapManager.Camera.Scale >= 1 ? SamplerState.PointWrap : SamplerState.AnisotropicWrap, + null, null, null, MapManager.Camera.TransformMatrix); + _drawPool.DrawPool(spriteBatch, + (int)((MapManager.Camera.X - Game1.RenderWidth / 2) / MapManager.Camera.Scale), + (int)((MapManager.Camera.Y - Game1.RenderHeight / 2) / MapManager.Camera.Scale), + (int)(Game1.RenderWidth / MapManager.Camera.Scale), + (int)(Game1.RenderHeight / MapManager.Camera.Scale), 2, 4); + spriteBatch.End(); + + // draw the body colliders + if (Game1.DebugMode) + { + Game1.StopWatchTracker.Start("5 debug draw"); + + spriteBatch.Begin(SpriteSortMode.Deferred, null, + MapManager.Camera.Scale >= 1 ? SamplerState.PointWrap : SamplerState.AnisotropicWrap, + null, null, null, MapManager.Camera.TransformMatrix); + + // draw entity size rectangle + if (Game1.DebugBoxMode == 0) + { + db_gameObjectList.Clear(); + _gameObjectPool.GetObjectList(db_gameObjectList, + (int)((MapManager.Camera.X - Game1.RenderWidth / 2) / MapManager.Camera.Scale), + (int)((MapManager.Camera.Y - Game1.RenderHeight / 2) / MapManager.Camera.Scale), + (int)(Game1.RenderWidth / MapManager.Camera.Scale), + (int)(Game1.RenderHeight / MapManager.Camera.Scale)); + foreach (var gameObject in db_gameObjectList) + { + if (gameObject.EntityPosition != null && !(gameObject is ObjLamp)) + { + var rectangle = new RectangleF( + gameObject.EntityPosition.X + gameObject.EntitySize.X, + gameObject.EntityPosition.Y + gameObject.EntitySize.Y, + gameObject.EntitySize.Width, gameObject.EntitySize.Height); + + DrawRectangle(spriteBatch, rectangle, Color.LightBlue); + } + } + } + + // draw the bodies + if (Game1.DebugBoxMode == 0 || Game1.DebugBoxMode == 1) + { + db_bodyList.Clear(); + _gameObjectPool.GetComponentList(db_bodyList, + (int)((MapManager.Camera.X - Game1.RenderWidth / 2) / MapManager.Camera.Scale), + (int)((MapManager.Camera.Y - Game1.RenderHeight / 2) / MapManager.Camera.Scale), + (int)(Game1.RenderWidth / MapManager.Camera.Scale), + (int)(Game1.RenderHeight / MapManager.Camera.Scale), BodyComponent.Mask); + foreach (var drawTile in db_bodyList) + { + var body = drawTile.Components[BodyComponent.Index] as BodyComponent; + DrawRectangle(spriteBatch, body.BodyBox.Box.Rectangle(), Color.Red); + } + } + + // draw the damage fields + if (Game1.DebugBoxMode == 0 || Game1.DebugBoxMode == 2) + { + db_damageList.Clear(); + _gameObjectPool.GetComponentList(db_damageList, + (int)((MapManager.Camera.X - Game1.RenderWidth / 2) / MapManager.Camera.Scale), + (int)((MapManager.Camera.Y - Game1.RenderHeight / 2) / MapManager.Camera.Scale), + (int)(Game1.RenderWidth / MapManager.Camera.Scale), + (int)(Game1.RenderHeight / MapManager.Camera.Scale), DamageFieldComponent.Mask); + foreach (var drawTile in db_damageList) + { + var damageComponent = drawTile.Components[DamageFieldComponent.Index] as DamageFieldComponent; + DrawRectangle(spriteBatch, damageComponent.CollisionBox.Box.Rectangle(), Color.Green); + } + } + + // draw the hittable fields + if (Game1.DebugBoxMode == 0 || Game1.DebugBoxMode == 3) + { + db_damageList.Clear(); + _gameObjectPool.GetComponentList(db_damageList, + (int)((MapManager.Camera.X - Game1.RenderWidth / 2) / MapManager.Camera.Scale), + (int)((MapManager.Camera.Y - Game1.RenderHeight / 2) / MapManager.Camera.Scale), + (int)(Game1.RenderWidth / MapManager.Camera.Scale), + (int)(Game1.RenderHeight / MapManager.Camera.Scale), HittableComponent.Mask); + foreach (var drawTile in db_damageList) + { + var hittableComponent = drawTile.Components[HittableComponent.Index] as HittableComponent; + DrawRectangle(spriteBatch, hittableComponent.HittableBox.Box.Rectangle(), Color.Yellow); + } + } + + // draw the push fields + if (Game1.DebugBoxMode == 0 || Game1.DebugBoxMode == 4) + { + db_damageList.Clear(); + _gameObjectPool.GetComponentList(db_damageList, + (int)((MapManager.Camera.X - Game1.RenderWidth / 2) / MapManager.Camera.Scale), + (int)((MapManager.Camera.Y - Game1.RenderHeight / 2) / MapManager.Camera.Scale), + (int)(Game1.RenderWidth / MapManager.Camera.Scale), + (int)(Game1.RenderHeight / MapManager.Camera.Scale), PushableComponent.Mask); + foreach (var drawTile in db_damageList) + { + var pushableComponent = drawTile.Components[PushableComponent.Index] as PushableComponent; + DrawRectangle(spriteBatch, pushableComponent.PushableBox.Box.Rectangle(), Color.Orange); + } + } + + // draw the interact rectangle + if (Game1.DebugBoxMode == 0 || Game1.DebugBoxMode == 5) + { + db_damageList.Clear(); + _gameObjectPool.GetComponentList(db_damageList, + (int)((MapManager.Camera.X - Game1.RenderWidth / 2) / MapManager.Camera.Scale), + (int)((MapManager.Camera.Y - Game1.RenderHeight / 2) / MapManager.Camera.Scale), + (int)(Game1.RenderWidth / MapManager.Camera.Scale), + (int)(Game1.RenderHeight / MapManager.Camera.Scale), InteractComponent.Mask); + foreach (var drawTile in db_damageList) + { + var pushableComponent = drawTile.Components[InteractComponent.Index] as InteractComponent; + DrawRectangle(spriteBatch, pushableComponent.BoxInteractabel.Box.Rectangle(), Color.Aqua); + } + } + + spriteBatch.End(); + } + + Game1.StopWatchTracker.Stop(); + + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, MapManager.Camera.TransformMatrix); + } + + private void DrawRectangle(SpriteBatch spriteBatch, RectangleF rectangle, Color color) + { + spriteBatch.Draw(Resources.SprWhite, + new Vector2(rectangle.X, rectangle.Y), + new Rectangle(0, 0, (int)rectangle.Width, (int)rectangle.Height), color * 0.25f); + + var thickness = 1 / (float)Game1.ScreenScale; + spriteBatch.Draw(Resources.SprWhite, + new Vector2(rectangle.X, rectangle.Y), + new Rectangle(0, 0, 1, (int)(rectangle.Height * Game1.ScreenScale)), + color * 0.75f, 0, Vector2.Zero, thickness, SpriteEffects.None, 0); + spriteBatch.Draw(Resources.SprWhite, + new Vector2(rectangle.X + rectangle.Width - thickness, rectangle.Y), + new Rectangle(0, 0, 1, (int)(rectangle.Height * Game1.ScreenScale)), + color * 0.75f, 0, Vector2.Zero, thickness, SpriteEffects.None, 0); + spriteBatch.Draw(Resources.SprWhite, + new Vector2(rectangle.X, rectangle.Y), + new Rectangle(0, 0, (int)(rectangle.Width * Game1.ScreenScale), 1), + color * 0.75f, 0, Vector2.Zero, thickness, SpriteEffects.None, 0); + spriteBatch.Draw(Resources.SprWhite, + new Vector2(rectangle.X, rectangle.Y + rectangle.Height - thickness), + new Rectangle(0, 0, (int)(rectangle.Width * Game1.ScreenScale), 1), + color * 0.75f, 0, Vector2.Zero, thickness, SpriteEffects.None, 0); + } + + public void DrawShadow(SpriteBatch spriteBatch) + { + DrawHelper.StartShadowDrawing(); + + // draw the shadows + _drawShadowObjects.Clear(); + _gameObjectPool.GetComponentList(_drawShadowObjects, + (int)((MapManager.Camera.X - Game1.RenderWidth / 2) / MapManager.Camera.Scale), + (int)((MapManager.Camera.Y - Game1.RenderHeight / 2) / MapManager.Camera.Scale), + (int)(Game1.RenderWidth / MapManager.Camera.Scale), + (int)(Game1.RenderHeight / MapManager.Camera.Scale), DrawShadowComponent.Mask); + + foreach (var gameObject in _drawShadowObjects) + if (gameObject.IsActive) + (gameObject.Components[DrawShadowComponent.Index] as DrawShadowComponent)?.Draw(spriteBatch); + + DrawHelper.EndShadowDrawing(); + } + + public void DrawLight(SpriteBatch spriteBatch) + { + // draw the shadows + _lightObjectList.Clear(); + _gameObjectPool.GetComponentList(_lightObjectList, + (int)((MapManager.Camera.X - Game1.RenderWidth / 2) / MapManager.Camera.Scale), + (int)((MapManager.Camera.Y - Game1.RenderHeight / 2) / MapManager.Camera.Scale), + (int)(Game1.RenderWidth / MapManager.Camera.Scale), + (int)(Game1.RenderHeight / MapManager.Camera.Scale), LightDrawComponent.Mask); + + _lightObjectList.Sort((obj0, obj1) => + { + var light0 = (LightDrawComponent)obj0.Components[LightDrawComponent.Index]; + var light1 = (LightDrawComponent)obj1.Components[LightDrawComponent.Index]; + + if (light0 != null && light1 != null) + { + if (light0.Layer == light1.Layer && + light0.Owner.EntityPosition != null && light1.Owner.EntityPosition != null) + return (int)light0.Owner.EntityPosition.Y - (int)light1.Owner.EntityPosition.Y; + + return light0.Layer - light1.Layer; + } + + return 0; + }); + + for (var i = 0; i < _lightObjectList.Count; i++) + { + if (_lightObjectList[i].IsActive) + (_lightObjectList[i].Components[LightDrawComponent.Index] as LightDrawComponent)?.Draw(spriteBatch); + } + } + + public void DrawBlur(SpriteBatch spriteBatch) + { + // draw the shadows + _drawShadowObjects.Clear(); + _gameObjectPool.GetComponentList(_drawShadowObjects, + (int)((MapManager.Camera.X - Game1.RenderWidth / 2) / MapManager.Camera.Scale), + (int)((MapManager.Camera.Y - Game1.RenderHeight / 2) / MapManager.Camera.Scale), + (int)(Game1.RenderWidth / MapManager.Camera.Scale), + (int)(Game1.RenderHeight / MapManager.Camera.Scale), BlurDrawComponent.Mask); + + foreach (var gameObject in _drawShadowObjects) + if (gameObject.IsActive) + (gameObject.Components[BlurDrawComponent.Index] as BlurDrawComponent)?.Draw(spriteBatch); + } + + public void Clear() + { + ObjectList.Clear(); + } + + private void ClearPools() + { + _keyChangeListeners.Clear(); + _poolSpawnedObjects.Clear(); + } + + private void AddObjectToMap(GameObject gameObject) + { + if (gameObject == null || gameObject.IsDead) + return; + + _poolSpawnedObjects.Add(gameObject); + + // order is important because the draw pool does not update the last position value + // add the object to the drawable pool + if ((gameObject.ComponentsMask & DrawComponent.Mask) == DrawComponent.Mask) + _drawPool.AddEntity(gameObject); + + // add the object to the pool + _gameObjectPool.AddEntity(gameObject); + + // add key listeners + if ((gameObject.ComponentsMask & KeyChangeListenerComponent.Mask) == KeyChangeListenerComponent.Mask) + { + var listener = (gameObject.Components[KeyChangeListenerComponent.Index] as KeyChangeListenerComponent).KeyChangeFunction; + _keyChangeListeners.Add(listener); + } + } + + public void RemoveObject(GameObject gameObject) + { + gameObject.Map = null; + + _poolSpawnedObjects.Remove(gameObject); + + // remove the object from the drawable pool + if ((gameObject.ComponentsMask & DrawComponent.Mask) == DrawComponent.Mask) + _drawPool.RemoveEntity(gameObject); + + // remove the object from the pool + _gameObjectPool.RemoveEntity(gameObject); + + // remove key listeners + if ((gameObject.ComponentsMask & KeyChangeListenerComponent.Mask) == KeyChangeListenerComponent.Mask) + { + var listener = (gameObject.Components[KeyChangeListenerComponent.Index] as KeyChangeListenerComponent).KeyChangeFunction; + _keyChangeListeners.Remove(listener); + } + } + + public void ReloadObjects() + { + LoadObjects(); + } + + public void TriggerKeyChange() + { + _keyChanged = true; + } + + public bool SpawnObject(GameObject newObject) + { + if (newObject == null || newObject.IsDead) + return false; + + SpawnObjects.Add(newObject); + return true; + } + + public bool SpawnObject(string objectId, object[] objectParameter) + { + if (objectId == null || !GameObjectTemplates.ObjectTemplates.ContainsKey(objectId)) + return false; + + return SpawnObject(GetGameObject(Owner, objectId, objectParameter)); + } + + public static GameObject GetGameObject(Map owner, string objectId, object[] objectParameter) + { + if (!GameObjectTemplates.ObjectSpawner.ContainsKey(objectId)) + return null; + + if (objectParameter == null) + { + objectParameter = MapData.GetParameter(objectId, null); + objectParameter[1] = 0; + objectParameter[2] = 0; + } + + objectParameter[0] = owner; + var constructor = GameObjectTemplates.ObjectSpawner[objectId]; + + return constructor(objectParameter); + } + + // TODO_End: be careful to not use this often + public List GetObjectsOfType(Type type) + { + _objectTypeList.Clear(); + + for (var i = 0; i < _poolSpawnedObjects.Count; i++) + if (_poolSpawnedObjects[i].GetType() == type) + _objectTypeList.Add(_poolSpawnedObjects[i]); + + return _objectTypeList; + } + + public List GetObjects(int left, int top, int width, int height) + { + // get possible candidates + _objectTagAllList.Clear(); + _gameObjectPool.GetObjectList(_objectTagAllList, left, top, width, height); + + var outputList = new List(); + foreach (var gameObject in _objectTagAllList) + { + if (gameObject.EntityPosition != null && + left <= gameObject.EntityPosition.X + gameObject.EntitySize.X && + gameObject.EntityPosition.X + gameObject.EntitySize.X + gameObject.EntitySize.Width <= left + width && + top <= gameObject.EntityPosition.Y + gameObject.EntitySize.Y && + gameObject.EntityPosition.Y + gameObject.EntitySize.Y + gameObject.EntitySize.Height <= top + height) + outputList.Add(gameObject); + } + return outputList; + } + + public void GetObjectsOfType(List outputList, Type type, int left, int top, int width, int height) + { + // get possible candidates + _objectTagAllList.Clear(); + _gameObjectPool.GetObjectList(_objectTagAllList, left, top, width, height); + + foreach (var gameObject in _objectTagAllList) + { + if (gameObject.GetType() == type && + left <= gameObject.EntityPosition.X + gameObject.EntitySize.X + gameObject.EntitySize.Width && + gameObject.EntityPosition.X + gameObject.EntitySize.X <= left + width && + top <= gameObject.EntityPosition.Y + gameObject.EntitySize.Y + gameObject.EntitySize.Height && + gameObject.EntityPosition.Y + gameObject.EntitySize.Y <= top + height) + outputList.Add(gameObject); + } + } + + public GameObject GetObjectOfType(int left, int top, int width, int height, Type type) + { + return _gameObjectPool.GetObjectOfType(left, top, width, height, type); + } + + public void GetGameObjectsWithTag(List outputList, Values.GameObjectTag tag, int left, int top, int width, int height) + { + // get possible candidates + _objectTagAllList.Clear(); + _gameObjectPool.GetObjectList(_objectTagAllList, left, top, width, height); + + outputList.Clear(); + + foreach (var gameObject in _objectTagAllList) + { + if ((gameObject.Tags & tag) != 0 && + left <= gameObject.EntityPosition.X && gameObject.EntityPosition.X <= left + width && + top <= gameObject.EntityPosition.Y && gameObject.EntityPosition.Y <= top + height) + outputList.Add(gameObject); + } + } + + public void GetComponentList(List gameObjectList, + int recLeft, int recTop, int recWidth, int recHeight, int componentMask) + { + _gameObjectPool.GetComponentList(gameObjectList, recLeft, recTop, recWidth, recHeight, componentMask); + } + + public bool Collision(Box box, Box oldBox, Values.CollisionTypes collisionTypes, Values.CollisionTypes ignoreTypes, int dir, int level, ref Box collidingBox) + { + // get all the near objects of the rectangle + _collisionObjectList.Clear(); + _gameObjectPool.GetComponentList(_collisionObjectList, (int)box.X, (int)box.Y, (int)box.Width, (int)box.Height, CollisionComponent.Mask); + + foreach (var gameObject in _collisionObjectList) + { + if (!gameObject.IsActive) + continue; + + var collisionObject = gameObject.Components[CollisionComponent.Index] as CollisionComponent; + if ((collisionObject.CollisionType & collisionTypes) != 0 && + (collisionObject.CollisionType & ignoreTypes) == 0 && + collisionObject.Collision(box, dir, level, ref collidingBox) && + (oldBox == Box.Empty || !collisionObject.Collision(oldBox, dir, level, ref collidingBox))) + return true; + } + + return false; + } + + public bool Collision(Box box, Box oldBox, Values.CollisionTypes collisionTypes, int dir, int level, ref Box collidingBox) + { + return Collision(box, oldBox, collisionTypes, Values.CollisionTypes.None, dir, level, ref collidingBox); + } + + public float GetDepth(Box box, Values.CollisionTypes collisionType, float maxDepth) + { + float outDepth = 0; + + // depth of holes + var center = new Vector2((box.X + box.Width / 2) / Values.TileSize, (box.Front - 1) / Values.TileSize); + if (Owner.HoleMap != null && Owner.HoleMap.ArrayTileMap != null && + 0 <= center.X && center.X < Owner.HoleMap.ArrayTileMap.GetLength(0) && + 0 <= center.Y && center.Y < Owner.HoleMap.ArrayTileMap.GetLength(1)) + { + var distance = new Vector2((int)center.X + 0.5f, (int)center.Y + 0.5f) - center; + outDepth = Owner.HoleMap.ArrayTileMap[(int)center.X, (int)center.Y, 0] < 0 ? 0 : -2 * Math.Clamp(1 - distance.Length() * 1.5f, 0, 1); + } + + _depthObjectList.Clear(); + _gameObjectPool.GetComponentList(_depthObjectList, (int)box.X, (int)box.Y, (int)box.Width, (int)box.Height, CollisionComponent.Mask); + + var clampDepth = outDepth; + + foreach (var gameObject in _depthObjectList) + { + if (!gameObject.IsActive) + continue; + + var newDepth = outDepth; + var lowestDepth = GetObjectDepth(gameObject, box, collisionType, ref newDepth); + + // floating point inaccuracy can lead to combined intersection areas greater than 100% + // to fix this problem the maxDepth value will need to be clamped to not exceed the max depth + if (lowestDepth < clampDepth) + clampDepth = lowestDepth; + + if (newDepth <= maxDepth) + outDepth = newDepth; + } + + return MathF.Max(outDepth, clampDepth); + } + + private float GetObjectDepth(GameObject gameObject, Box box, Values.CollisionTypes collisionType, ref float maxDepth) + { + var collisionObject = gameObject.Components[CollisionComponent.Index] as CollisionComponent; + var collidingBox = Box.Empty; + + // add the object to the list if it is in the mask and is colliding with the provided rectangle + if ((collisionObject.CollisionType & collisionType) != 0 && + collisionObject.Collision(box, 0, 0, ref collidingBox)) + { + var bottom = collidingBox.Z + collidingBox.Depth; + if (bottom < 0) + { + // combine the depth values lower than 0 to smoothly transition to lower floors + var bodyRec = box.Rectangle(); + var intersection = collidingBox.Rectangle().GetIntersection(bodyRec); + maxDepth += bottom * ((intersection.Width * intersection.Height) / (bodyRec.Width * bodyRec.Height)); + return bottom; + } + if (bottom > maxDepth) + { + maxDepth = bottom; + return maxDepth; + } + } + + return 0; + } + + public GameObject GetCarryableObjects(RectangleF rectangle) + { + _carriableObjectList.Clear(); + _gameObjectPool.GetComponentList(_carriableObjectList, (int)rectangle.X, (int)rectangle.Y, (int)rectangle.Width, (int)rectangle.Height, CarriableComponent.Mask); + + foreach (var gameObject in _carriableObjectList) + { + if (!gameObject.IsActive) + continue; + + var component = gameObject.Components[CarriableComponent.Index] as CarriableComponent; + + if (component.IsActive && component.Rectangle.Rectangle.Intersects(rectangle)) + return gameObject; + } + + return null; + } + + public Values.HitCollision Hit(GameObject originObject, Vector2 forceOrigin, Box hitBox, HitType type, int damage, bool doubleDamage, bool multidamage = true) + { + return Hit(originObject, forceOrigin, hitBox, type, damage, doubleDamage, out var direction, multidamage); + } + + public Values.HitCollision Hit(GameObject originObject, Vector2 forceOrigin, Box hitBox, HitType type, int damage, bool doubleDamage, out Vector2 direction, bool multidamage = true) + { + // get all the near objects of the rectangle + _hittableObjectList.Clear(); + _gameObjectPool.GetComponentList(_hittableObjectList, (int)hitBox.X, (int)hitBox.Y, (int)hitBox.Width, (int)hitBox.Height, HittableComponent.Mask); + + var hitCollision = Values.HitCollision.None; + direction = Vector2.Zero; + + foreach (var gameObject in _hittableObjectList) + { + if (!gameObject.IsActive) + continue; + + var hittableComponent = gameObject.Components[HittableComponent.Index] as HittableComponent; + + if (!hittableComponent.IsActive || !hittableComponent.HittableBox.Box.Intersects(hitBox)) + continue; + + // direction goes from the hitter towards the center of hittable box + direction = hittableComponent.HittableBox.Box.Center - forceOrigin; + if (direction != Vector2.Zero) + direction.Normalize(); + + hitCollision |= hittableComponent.Hit(originObject, direction, type, damage, doubleDamage); + + if (!multidamage && hitCollision != Values.HitCollision.None && hitCollision != Values.HitCollision.NoneBlocking) + return hitCollision; + } + + return hitCollision; + } + + public PushableComponent PushObject(Box box, Vector2 direction, PushableComponent.PushType type) + { + // get all the near objects of the rectangle + _pushableObjectList.Clear(); + _gameObjectPool.GetComponentList(_pushableObjectList, (int)box.X, (int)box.Y, (int)box.Width, (int)box.Height, PushableComponent.Mask); + + PushableComponent outPushComponent = null; + + foreach (var gameObject in _pushableObjectList) + { + if (!gameObject.IsActive) + continue; + + var pushableComponent = gameObject.Components[PushableComponent.Index] as PushableComponent; + + // check for collision and if cooldown time is met + if (pushableComponent.IsActive && + pushableComponent.LastPushTime + pushableComponent.CooldownTime < Game1.TotalGameTime && + box.Intersects(pushableComponent.PushableBox.Box)) + { + // object got inertia? + if (pushableComponent.InertiaTime > 0 && type == PushableComponent.PushType.Continues) + { + // the object was pushed the last frame? + if (pushableComponent.LastWaitTime >= Game1.TotalGameTimeLast) + { + pushableComponent.InertiaCounter -= Game1.DeltaTime; + if (pushableComponent.InertiaCounter <= 0 && pushableComponent.Push(direction, type)) + { + pushableComponent.InertiaCounter = pushableComponent.InertiaTime; + pushableComponent.LastPushTime = Game1.TotalGameTime; + outPushComponent = pushableComponent; + } + } + else + { + // reset inertia counter if pushing has just begone + pushableComponent.InertiaCounter = pushableComponent.InertiaTime; + } + + pushableComponent.LastWaitTime = Game1.TotalGameTime; + } + else if (pushableComponent.Push(direction, type)) + { + pushableComponent.LastPushTime = Game1.TotalGameTime; + outPushComponent = pushableComponent; + } + } + } + + return outPushComponent; + } + + public bool InteractWithObject(Box box) + { + // get the interactable objects at the given position + _interactableObjectList.Clear(); + _gameObjectPool.GetComponentList(_interactableObjectList, (int)box.X, (int)box.Y, (int)box.Width, (int)box.Height, InteractComponent.Mask); + + // go through all the interactable objects and check for collision before interacting with them + foreach (var gameObject in _interactableObjectList) + { + if (!gameObject.IsActive) + continue; + + var component = gameObject.Components[InteractComponent.Index] as InteractComponent; + if (component.IsActive && component.BoxInteractabel.Box.Intersects(box) && component.InteractFunction()) + return true; + } + + return false; + } + } +} \ No newline at end of file diff --git a/InGame/Map/TileMap.cs b/InGame/Map/TileMap.cs new file mode 100644 index 0000000..b82295b --- /dev/null +++ b/InGame/Map/TileMap.cs @@ -0,0 +1,86 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Map +{ + public class TileMap + { + public Texture2D SprTileset; + public Texture2D SprTilesetBlur; + + public string TilesetPath; + public int[,,] ArrayTileMap; + + public int TileSize; + public int TileCountX; + public int TileCountY; + + public bool BlurLayer = false; + + public void SetTileset(Texture2D sprTileset, int tileSize = 16) + { + SprTileset = sprTileset; + SprTilesetBlur = Resources.SprBlurTileset; + + TileSize = tileSize; + + // calculate how many tiles are horizontally and vertically + TileCountX = SprTileset.Width / TileSize; + TileCountY = SprTileset.Height / TileSize; + } + + public void Draw(SpriteBatch spriteBatch) + { + if (ArrayTileMap == null) + return; + + spriteBatch.Begin(SpriteSortMode.Deferred, null, MapManager.Camera.Scale >= 1 ? + SamplerState.PointWrap : SamplerState.AnisotropicWrap, null, null, null, MapManager.Camera.TransformMatrix); + + for (var i = 0; i < ArrayTileMap.GetLength(2) - (BlurLayer ? 1 : 0); i++) + DrawTileLayer(spriteBatch, SprTileset, i); + + spriteBatch.End(); + } + + // TODO_End: this could be optimized like in MonoGame.Extended + public void DrawTileLayer(SpriteBatch spriteBatch, Texture2D tileset, int layer, int padding = 0) + { + var halfWidth = Game1.RenderWidth / 2; + var halfHeight = Game1.RenderHeight / 2; + + var tileSize = Values.TileSize; + + var camera = MapManager.Camera; + var startX = Math.Max(0, (int)((camera.X - halfWidth) / (camera.Scale * tileSize)) - padding); + var startY = Math.Max(0, (int)((camera.Y - halfHeight) / (camera.Scale * tileSize)) - padding); + var endX = Math.Min(ArrayTileMap.GetLength(0), (int)((camera.X + halfWidth) / (camera.Scale * tileSize)) + 1 + padding); + var endY = Math.Min(ArrayTileMap.GetLength(1), (int)((camera.Y + halfHeight) / (camera.Scale * tileSize)) + 1 + padding); + + for (var y = startY; y < endY; y++) + for (var x = startX; x < endX; x++) + { + if (ArrayTileMap[x, y, layer] >= 0) + spriteBatch.Draw(tileset, + new Rectangle(x * tileSize, y * tileSize, tileSize, tileSize), + new Rectangle((ArrayTileMap[x, y, layer] % (tileset.Width / TileSize)) * TileSize, + ArrayTileMap[x, y, layer] / (tileset.Width / TileSize) * TileSize, TileSize, TileSize), + Color.White); + } + } + + // this should probably be at a different location + public void DrawBlurLayer(SpriteBatch spriteBatch) + { + if (ArrayTileMap == null) + return; + + //SprTilesetBlur.Dispose(); + //Resources.LoadTexture(out SprTilesetBlur, "D:\\Dev\\ProjectZ\\ProjectZ\\bin\\Data\\Maps\\Tilesets\\blur tileset.png"); + + DrawTileLayer(spriteBatch, SprTilesetBlur, ArrayTileMap.GetLength(2) - 1, 1); + } + } +} diff --git a/InGame/Overlay/DialogPath.cs b/InGame/Overlay/DialogPath.cs new file mode 100644 index 0000000..17c0cab --- /dev/null +++ b/InGame/Overlay/DialogPath.cs @@ -0,0 +1,858 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.GameSystems; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Overlay +{ + class DialogAction + { + public virtual void Init() { } + + public virtual bool Execute() + { + return true; + } + } + + class DialogActionStartDialog : DialogAction + { + private readonly string _key; + + public DialogActionStartDialog(string key) + { + _key = key; + } + + public override bool Execute() + { + if (Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen) + return false; + + Game1.GameManager.StartDialog(_key); + return true; + } + } + + class DialogActionStartPath : DialogAction + { + private readonly string _key; + + public DialogActionStartPath(string key) + { + _key = key; + } + + public override bool Execute() + { + if (Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen) + return false; + + // add the dialog path as the first element to be executed directly after this dialog + Game1.GameManager.AddFirstDialogPath(_key); + return true; + } + } + + class DialogActionDialog : DialogAction + { + private readonly string _key; + private readonly string _choiceKey; + private readonly string[] _choicesKeys; + + public DialogActionDialog(string key, string choiceKey, params string[] choices) + { + _key = key; + _choiceKey = choiceKey; + _choicesKeys = choices; + } + + public override bool Execute() + { + var choiceHeader = Game1.LanguageManager.GetString(_choiceKey, "error"); + + var choices = new string[_choicesKeys.Length]; + for (var i = 0; i < _choicesKeys.Length; i++) + choices[i] = Game1.LanguageManager.GetString(_choicesKeys[i], "error"); + + if (Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen) + return false; + + Game1.GameManager.InGameOverlay.TextboxOverlay.StartChoice(_key, choiceHeader, choices); + return true; + } + } + + class DialogActionSetVariable : DialogAction + { + private readonly string _key; + private readonly string _value; + + public DialogActionSetVariable(string key, string value) + { + _key = key; + _value = value; + } + + public override bool Execute() + { + Game1.GameManager.SaveManager.SetString(_key, _value); + return true; + } + } + + class DialogActionUpdateObjects : DialogAction + { + public override bool Execute() + { + Game1.GameManager.InGameOverlay.TextboxOverlay.UpdateObjects = true; + return true; + } + } + + class DialogActionWait : DialogAction + { + private readonly string _key; + private readonly string _value; + + public DialogActionWait(string key, string value) + { + _key = key; + _value = value; + } + + public override bool Execute() + { + return Game1.GameManager.SaveManager.GetString(_key) == _value; + } + } + + /// + /// DialogAction used to stop the dialog path for a certain amount of time. + /// + class DialogActionCountdown : DialogAction + { + private readonly float Time; + private float _counter; + + public DialogActionCountdown(float time) + { + Time = time; + } + + public override void Init() + { + _counter = Time; + } + + public override bool Execute() + { + _counter -= Game1.DeltaTime; + return _counter <= 0; + } + } + + class DialogActionFreezePlayer : DialogAction + { + private readonly string _key; + private readonly string _value; + + public DialogActionFreezePlayer(string key, string value) + { + _key = key; + _value = value; + } + + public override bool Execute() + { + MapManager.ObjLink.FreezePlayer(); + return Game1.GameManager.SaveManager.GetString(_key) == _value; + } + } + + class DialogActionFreezePlayerTime : DialogAction + { + private float _counter; + private readonly float _time; + + public DialogActionFreezePlayerTime(int time) + { + _time = time; + } + + public override void Init() + { + _counter = _time; + } + + public override bool Execute() + { + // freeze the player while the time is running + var finished = _counter <= 0; + _counter -= Game1.DeltaTime; + + MapManager.ObjLink.FreezePlayer(); + + return finished; + } + } + + class DialogActionLockPlayerTime : DialogAction + { + private float _counter; + private readonly float _time; + + public DialogActionLockPlayerTime(int time) + { + _time = time; + } + + public override void Init() + { + _counter = _time; + } + + public override bool Execute() + { + // freeze the player while the time is running + var finished = _counter <= 0; + _counter -= Game1.DeltaTime; + + MapManager.ObjLink.SeqLockPlayer(); + + return finished; + } + } + + /// + /// Lock the player as long as the key is not yet set to the value + /// + class DialogActionLockPlayer : DialogAction + { + private string _key; + private string _value; + + public DialogActionLockPlayer(string key, string value) + { + _key = key; + _value = value; + } + + public override bool Execute() + { + MapManager.ObjLink.SeqLockPlayer(); + return Game1.GameManager.SaveManager.GetString(_key) == _value; + } + } + + class DialogActionShake : DialogAction + { + private readonly int _time; + private readonly int _maxX; + private readonly int _maxY; + private readonly float _shakeSpeedX; + private readonly float _shakeSpeedY; + + public DialogActionShake(int time, int maxX, int maxY, float shakeSpeedX, float shakeSpeedY) + { + _time = time; + _maxX = maxX; + _maxY = maxY; + _shakeSpeedX = shakeSpeedX; + _shakeSpeedY = shakeSpeedY; + } + + public override bool Execute() + { + Game1.GameManager.ShakeScreen(_time, _maxX, _maxY, _shakeSpeedX, _shakeSpeedY); + return true; + } + } + + class DialogActionStopMusic : DialogAction + { + public override bool Execute() + { + Game1.GbsPlayer.Stop(); + return true; + } + } + + class DialogActionStopMusicTime : DialogAction + { + private readonly int _time; + private readonly int _priority; + + public DialogActionStopMusicTime(int time, int priority) + { + _time = time; + _priority = priority; + } + + public override bool Execute() + { + Game1.GameManager.StopMusic(_time, _priority); + return true; + } + } + + class DialogActionPlayMusic : DialogAction + { + private readonly int _songNr; + private readonly int _priority; + + public DialogActionPlayMusic(int songNr, int priority) + { + _songNr = songNr; + _priority = priority; + } + + public override bool Execute() + { + if (_priority < 0) + { + Game1.GameManager.StopMusic(); + return true; + } + + // play the music after the transition if the game is transitioning + if (MapManager.ObjLink.IsTransitioning) + Game1.GameManager.MapManager.NextMap.MapMusic[_priority] = _songNr; + else + { + Game1.GameManager.SetMusic(_songNr, _priority); + if (_songNr >= 0) + Game1.GbsPlayer.Play(); + } + + return true; + } + } + + class DialogActionMusicSpeed : DialogAction + { + private readonly float _playbackSpeed; + + public DialogActionMusicSpeed(float playbackSpeed) + { + _playbackSpeed = playbackSpeed; + } + + public override bool Execute() + { +#if WINDOWS + Game1.GbsPlayer.Cpu.SetPlaybackSpeed(_playbackSpeed); +#endif + return true; + } + } + + class DialogActionSoundEffect : DialogAction + { + private readonly string _soundEffect; + + public DialogActionSoundEffect(string soundEffect) + { + _soundEffect = soundEffect; + } + + public override bool Execute() + { + Game1.GameManager.PlaySoundEffect(_soundEffect); + return true; + } + } + + class DialogActionCheckItem : DialogAction + { + private readonly string _itemName; + private readonly string _resultKey; + private readonly int _count; + + public DialogActionCheckItem(string itemName, int count, string resultKey) + { + _itemName = itemName; + _count = count; + _resultKey = resultKey; + } + + public override bool Execute() + { + // get the item and check if enough are available + var item = Game1.GameManager.GetItem(_itemName); + var checkState = item != null && item.Count >= _count; + + Game1.GameManager.SaveManager.SetString(_resultKey, checkState ? "1" : "0"); + return true; + } + } + + class DialogActionCooldown : DialogAction + { + private readonly string _resultKey; + private readonly int _cooldownTime; + + private double _lastExecutionTime; + + public DialogActionCooldown(int cooldownTime, string resultKey) + { + _cooldownTime = cooldownTime; + _resultKey = resultKey; + _lastExecutionTime = -_cooldownTime; + } + + public override bool Execute() + { + // check when the last time the check was successful + // this does not work directly after loading the save if it was running shortly after the last save loading + if (_lastExecutionTime <= Game1.TotalGameTime && Game1.TotalGameTime < _lastExecutionTime + _cooldownTime) + { + Game1.GameManager.SaveManager.SetString(_resultKey, "0"); + return true; + } + + _lastExecutionTime = Game1.TotalGameTime; + + Game1.GameManager.SaveManager.SetString(_resultKey, "1"); + return true; + } + } + + class DialogActionAddItem : DialogAction + { + private readonly string _itemName; + private readonly int _amount; + + public DialogActionAddItem(string itemName, int amount) + { + _itemName = itemName; + _amount = amount; + } + + public override bool Execute() + { + if (Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen) + return false; + + var item = new GameItemCollected(_itemName); + + // use the set amount or that from the item description + if (_amount > 0) + item.Count = _amount; + else + item.Count = Game1.GameManager.ItemManager[_itemName].Count; + + MapManager.ObjLink.PickUpItem(item, true); + return true; + } + } + + class DialogActionSeqSetPosition : DialogAction + { + private string _animatorId; + private Vector2 _newPosition; + + public DialogActionSeqSetPosition(string animatorId, Vector2 newPosition) + { + _animatorId = animatorId; + _newPosition = newPosition; + } + + public override bool Execute() + { + var gameSequence = Game1.GameManager.InGameOverlay.GetCurrentGameSequence(); + + if (gameSequence == null) + return false; + + gameSequence.SetPosition(_animatorId, _newPosition); + return true; + } + } + + class DialogActionSeqLerp : DialogAction + { + private string _drawableId; + private Vector2 _targetPosition; + private float _moveSpeed; + + public DialogActionSeqLerp(string animatorId, Vector2 newPosition, float moveSpeed) + { + _drawableId = animatorId; + _targetPosition = newPosition; + _moveSpeed = moveSpeed; + } + + public override bool Execute() + { + var gameSequence = Game1.GameManager.InGameOverlay.GetCurrentGameSequence(); + + if (gameSequence == null) + return false; + + gameSequence.StartPositionTransition(_drawableId, _targetPosition, _moveSpeed); + return true; + } + } + + class DialogActionSeqColorLerp : DialogAction + { + private string _drawableId; + private Color _targetColor; + private int _transitionTime; + + public DialogActionSeqColorLerp(string animatorId, Color targetColor, int transitionTime) + { + _drawableId = animatorId; + _targetColor = targetColor; + _transitionTime = transitionTime; + } + + public override bool Execute() + { + var gameSequence = Game1.GameManager.InGameOverlay.GetCurrentGameSequence(); + + if (gameSequence == null) + return false; + + gameSequence.StartColorTransition(_drawableId, _targetColor, _transitionTime); + return true; + } + } + + class DialogActionSeqPlay : DialogAction + { + private string _animatorId; + private string _animationId; + + public DialogActionSeqPlay(string animatorId, string animationId) + { + _animatorId = animatorId; + _animationId = animationId; + } + + public override bool Execute() + { + var gameSequence = Game1.GameManager.InGameOverlay.GetCurrentGameSequence(); + + if (gameSequence == null) + return false; + + gameSequence.PlayAnimation(_animatorId, _animationId); + return true; + } + } + + class DialogActionFinishAnimation : DialogAction + { + private string _animatorId; + private int _stopFrameIndex; + + public DialogActionFinishAnimation(string animatorId, int stopFrameIndex) + { + _animatorId = animatorId; + _stopFrameIndex = stopFrameIndex; + } + + public override bool Execute() + { + var gameSequence = Game1.GameManager.InGameOverlay.GetCurrentGameSequence(); + + if (gameSequence == null) + return false; + + gameSequence.FinishAnimation(_animatorId, _stopFrameIndex); + return true; + } + } + + /// + /// Only add an amount to an existing item + /// + class DialogActionAddItemAmount : DialogAction + { + private readonly string _itemName; + private readonly int _amount; + + public DialogActionAddItemAmount(string itemName, int amount) + { + _itemName = itemName; + _amount = amount; + } + + public override bool Execute() + { + if (Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen) + return false; + + if (Game1.GameManager.GetItem(_itemName) == null) + return true; + + var item = new GameItemCollected(_itemName); + if (_amount > 0) + item.Count = _amount; + + MapManager.ObjLink.PickUpItem(item, false, false, false); + return true; + } + } + + class DialogActionRemoveItem : DialogAction + { + private readonly string _itemName; + private readonly string _resultKey; + private readonly int _count; + + public DialogActionRemoveItem(string itemName, int count, string resultKey) + { + _itemName = itemName; + _count = count; + _resultKey = resultKey; + } + + public override bool Execute() + { + // remove the item if possible + if (Game1.GameManager.RemoveItem(_itemName, _count)) + Game1.GameManager.SaveManager.SetString(_resultKey, "1"); + else + Game1.GameManager.SaveManager.SetString(_resultKey, "0"); + + return true; + } + } + + class DialogActionBuyItem : DialogAction + { + private readonly string _key; + + public DialogActionBuyItem(string key) + { + _key = key; + } + + public override bool Execute() + { + var itemName = Game1.GameManager.SaveManager.GetString("itemShopItem"); + var itemPriceString = Game1.GameManager.SaveManager.GetString("itemShopPrice"); + var itemPrice = int.Parse(itemPriceString); + var itemCountString = Game1.GameManager.SaveManager.GetString("itemShopCount"); + var itemCount = int.Parse(itemCountString); + + var baseItem = Game1.GameManager.ItemManager[itemName]; + var buyItem = Game1.GameManager.GetItem(baseItem.Name); + var rubyItem = Game1.GameManager.GetItem("ruby"); + + var ownedCount = 0; + var maxCount = 99; + + // check if the player has the mirror shield + if (itemName == "arrow") + buyItem = Game1.GameManager.GetItem("bow"); + if (itemName == "shield" && buyItem == null) + buyItem = Game1.GameManager.GetItem("mirrorShield"); + + if (itemName == "heart") + { + ownedCount = Game1.GameManager.CurrentHealth; + maxCount = Game1.GameManager.MaxHearths * 4; + } + else if (buyItem != null) + { + ownedCount = buyItem.Count; + maxCount = Game1.GameManager.ItemManager[buyItem.Name].MaxCount; + } + + if (buyItem != null && buyItem.Name == "powder" && Game1.GameManager.SaveManager.GetString("upgradePowder") == "1") + maxCount += 20; + if (buyItem != null && buyItem.Name == "bomb" && Game1.GameManager.SaveManager.GetString("upgradeBomb") == "1") + maxCount += 30; + if (buyItem != null && buyItem.Name == "bow" && Game1.GameManager.SaveManager.GetString("upgradeBow") == "1") + maxCount += 30; + + // does the player already own the item? + if (ownedCount >= maxCount) + { + Game1.GameManager.SaveManager.SetString(_key, "2"); + } + // does the player have enough money to buy this item? + else if (rubyItem != null && rubyItem.Count >= itemPrice) + { + var item = new GameItemCollected(itemName); + item.Count = itemCount; + + // gets picked up + MapManager.ObjLink.PickUpItem(item, false); + + rubyItem.Count -= itemPrice; + + Game1.GameManager.SaveManager.SetString(_key, "0"); + } + // player does not have enough money + else + { + Game1.GameManager.SaveManager.SetString(_key, "1"); + } + + return true; + } + } + + class DialogActionOpenBook : DialogAction + { + public override bool Execute() + { + Game1.GameManager.InGameOverlay.OpenPhotoOverlay(); + return true; + } + } + + class DialogActionStartSequence : DialogAction + { + private readonly string _sequenceName; + + public DialogActionStartSequence(string sequenceName) + { + _sequenceName = sequenceName; + } + + public override bool Execute() + { + Game1.GameManager.InGameOverlay.StartSequence(_sequenceName); + return true; + } + } + + class DialogActionCloseOverlay : DialogAction + { + public DialogActionCloseOverlay() { } + + public override bool Execute() + { + Game1.GameManager.InGameOverlay.CloseOverlay(); + return true; + } + } + + class DialogActionFillHearts : DialogAction + { + public DialogActionFillHearts() { } + + public override bool Execute() + { + var fullHearts = Game1.GameManager.CurrentHealth >= Game1.GameManager.MaxHearths * 4; + Game1.GameManager.SaveManager.SetString("fullHearts", fullHearts ? "1" : "0"); + Game1.GameManager.HealPlayer(99); + ItemDrawHelper.EnableHeartAnimationSound(); + return true; + } + } + + class DialogActionSpawnObject : DialogAction + { + private readonly string _positionKey; + private readonly string _objectId; + private readonly string _strParameter; + + public DialogActionSpawnObject(string positionKey, string objectId, string strParameter) + { + _positionKey = positionKey; + _objectId = objectId; + _strParameter = strParameter; + } + + public override bool Execute() + { + // @HACK: this is not really a good way and could lead to problems + // a better way would probably be a way to pass parameters into a dialog path so that the actions could read them + + // @HACK: some parameters need the '.' character + var parameters = _strParameter.Split('.'); + for (var i = 0; i < parameters.Length; i++) + parameters[i] = parameters[i].Replace("$", "."); + + var objectParameter = MapData.GetParameter(_objectId, parameters); + objectParameter[0] = ObjPositionDialog.CurrentMap; + objectParameter[1] = Game1.GameManager.SaveManager.GetInt(_positionKey + "posX"); + objectParameter[2] = Game1.GameManager.SaveManager.GetInt(_positionKey + "posY"); + + ObjPositionDialog.CurrentMap.Objects.SpawnObject(_objectId, objectParameter); + + return true; + } + } + + class DialogActionChangeMap : DialogAction + { + private readonly string _mapName; + private readonly string _entryName; + + public DialogActionChangeMap(string mapName, string entryName) + { + _mapName = mapName; + _entryName = entryName; + } + + public override bool Execute() + { + var transitionSystem = (MapTransitionSystem)Game1.GameManager.GameSystems[typeof(MapTransitionSystem)]; + transitionSystem.AppendMapChange(_mapName, _entryName, false, false, Color.White, true); + transitionSystem.SetColorMode(Color.White, 1); + + MapManager.ObjLink.MapTransitionStart = MapManager.ObjLink.EntityPosition.Position; + MapManager.ObjLink.MapTransitionEnd = MapManager.ObjLink.EntityPosition.Position; + MapManager.ObjLink.TransitionOutWalking = false; + + return true; + } + } + + class DialogActionSaveHistory : DialogAction + { + private readonly bool _enable; + + public DialogActionSaveHistory(bool enable) + { + _enable = enable; + } + + public override bool Execute() + { + if (_enable && !Game1.GameManager.SaveManager.HistoryEnabled) + { + SaveGameSaveLoad.FillSaveState(Game1.GameManager); + Game1.GameManager.SaveManager.EnableHistory(); + } + // the history will be cleared by the player + else if (!_enable && !MapManager.ObjLink.SavePreItemPickup) + { + SaveGameSaveLoad.ClearSaveState(); + Game1.GameManager.SaveManager.DisableHistory(); + } + + return true; + } + } + + class DialogPath + { + public string VariableKey; + public string Condition; + + public List Action = new List(); + + public DialogPath(string variableKey, string condition) + { + VariableKey = variableKey; + Condition = condition; + } + + public DialogPath(string variableKey) + { + VariableKey = variableKey; + } + } +} diff --git a/InGame/Overlay/DungeonOverlay.cs b/InGame/Overlay/DungeonOverlay.cs new file mode 100644 index 0000000..a506671 --- /dev/null +++ b/InGame/Overlay/DungeonOverlay.cs @@ -0,0 +1,240 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Overlay +{ + public class DungeonOverlay + { + private RenderTarget2D _renderTarget; + + private Animator _animationPlayer = new Animator(); + + private Rectangle _backgroundTop; + private Rectangle _backgroundBottom; + + private static readonly Point DungeonPoint = new Point(6, 0); + + private Rectangle _mapRectangle = new Rectangle(DungeonPoint.X, DungeonPoint.Y, 12, 20); + private Rectangle _compasRectangle = new Rectangle(DungeonPoint.X + 12, DungeonPoint.Y, 12, 20); + private Rectangle _stonebreakRectangle = new Rectangle(DungeonPoint.X + 24, DungeonPoint.Y, 12, 20); + private Rectangle _nightmareKeyPosition = new Rectangle(DungeonPoint.X + 36, DungeonPoint.Y, 12, 20); + private Rectangle _smallKeyPosition = new Rectangle(DungeonPoint.X + 48, DungeonPoint.Y, 24, 20); + + private Point _recMap = new Point(2, 160); + private Point _hintMap = new Point(2, 170); + private Point _mapPosition = new Point(6, 24); + + private int _tileWidth = 8; + private int _tileHeight = 8; + + private int _mapTile = 3; + private int _undiscoveredTile = 4; + + private int _width; + private int _height; + + public DungeonOverlay(int width, int height) + { + _width = width; + _height = height; + + _backgroundTop = new Rectangle(0, 0, width, 20); + _backgroundBottom = new Rectangle(0, 20 + 2, width, height - 20 - 2); + } + + public void UpdateRenderTarget() + { + if (_renderTarget == null || _renderTarget.Width != _width * Game1.UiScale || _renderTarget.Height != _height * Game1.UiScale) + _renderTarget = new RenderTarget2D(Game1.Graphics.GraphicsDevice, _width * Game1.UiScale, _height * Game1.UiScale); + } + + public void Load() + { + _animationPlayer = AnimatorSaveLoad.LoadAnimator("dungeonPlayer"); + _animationPlayer.Play("idle"); + } + + public void OnFocus() + { + var level = 0; + while (true) + { + var name = Game1.GameManager.MapManager.CurrentMap.LocationName + "_" + level; + if (!Game1.GameManager.DungeonMaps.TryGetValue(name, out var normalMap) || normalMap == null) + break; + + level++; + + if (normalMap.Overrides == null) + continue; + + var dungeonMap = GetAlternativeMap(name) ?? normalMap; + + // check the override map and override unlocked tiles + foreach (var map in normalMap.Overrides) + { + if (Game1.GameManager.SaveManager.GetString(map.SaveKey, "0") == "1") + dungeonMap.Tiles[map.PosX, map.PosY].TileIndex = map.TileIndex; + } + } + } + + public void Update() + { + if (!Game1.GameManager.MapManager.CurrentMap.DungeonMode) + return; + + _animationPlayer.Update(); + } + + public void Draw(SpriteBatch spriteBatch, Rectangle drawPosition, Color color) + { + if (!Game1.GameManager.MapManager.CurrentMap.DungeonMode) + return; + + spriteBatch.Draw(_renderTarget, drawPosition, color); + } + + public void DrawOnRenderTarget(SpriteBatch spriteBatch) + { + if (!Game1.GameManager.MapManager.CurrentMap.DungeonMode) + return; + + Game1.Graphics.GraphicsDevice.SetRenderTarget(_renderTarget); + Game1.Graphics.GraphicsDevice.Clear(Color.Transparent); + + // draw the background + spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, null, Resources.RoundedCornerEffect, Matrix.CreateScale(Game1.UiRtScale)); + + Resources.RoundedCornerEffect.Parameters["scale"].SetValue(Game1.UiRtScale); + Resources.RoundedCornerEffect.Parameters["radius"].SetValue(3f); + Resources.RoundedCornerEffect.Parameters["width"].SetValue(_width); + + Resources.RoundedCornerEffect.Parameters["height"].SetValue(_backgroundTop.Height); + spriteBatch.Draw(Resources.SprWhite, _backgroundTop, Values.InventoryBackgroundColor); + + Resources.RoundedCornerEffect.Parameters["height"].SetValue(_backgroundBottom.Height); + spriteBatch.Draw(Resources.SprWhite, _backgroundBottom, Values.InventoryBackgroundColor); + + if (Game1.GameManager.GetItem("dmap") == null) + DrawBackground(spriteBatch, Point.Zero, new Rectangle(_mapRectangle.X + _mapRectangle.Width / 2, _mapRectangle.Bottom - 5, 4, 2), 1); + if (Game1.GameManager.GetItem("compass") == null) + DrawBackground(spriteBatch, Point.Zero, new Rectangle(_compasRectangle.X + _compasRectangle.Width / 2, _compasRectangle.Bottom - 5, 4, 2), 1); + if (Game1.GameManager.GetItem("stonebeak") == null) + DrawBackground(spriteBatch, Point.Zero, new Rectangle(_stonebreakRectangle.X + _stonebreakRectangle.Width / 2, _stonebreakRectangle.Bottom - 5, 4, 2), 1); + if (Game1.GameManager.GetItem("nightmarekey") == null) + DrawBackground(spriteBatch, Point.Zero, new Rectangle(_nightmareKeyPosition.X + _nightmareKeyPosition.Width / 2, _nightmareKeyPosition.Bottom - 5, 4, 2), 1); + if (Game1.GameManager.GetItem("smallkey") == null) + DrawBackground(spriteBatch, Point.Zero, new Rectangle(_smallKeyPosition.X + _smallKeyPosition.Width / 2, _smallKeyPosition.Bottom - 5, 4, 2), 1); + + spriteBatch.End(); + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, null, null, null, Matrix.CreateScale(Game1.UiRtScale)); + + var offset = new Point(0, 0); + + ItemDrawHelper.DrawItemWithInfo(spriteBatch, Game1.GameManager.GetItem("dmap"), offset, _mapRectangle, 1, Color.White); + + ItemDrawHelper.DrawItemWithInfo(spriteBatch, Game1.GameManager.GetItem("compass"), offset, _compasRectangle, 1, Color.White); + + ItemDrawHelper.DrawItemWithInfo(spriteBatch, Game1.GameManager.GetItem("stonebeak"), offset, _stonebreakRectangle, 1, Color.White); + + ItemDrawHelper.DrawItemWithInfo(spriteBatch, Game1.GameManager.GetItem("nightmarekey"), offset, _nightmareKeyPosition, 1, Color.White); + + ItemDrawHelper.DrawItemWithInfo(spriteBatch, Game1.GameManager.GetItem("smallkey"), offset, _smallKeyPosition, 1, Color.White); + + // draw the dungeon maps + var level = 0; + var hasMap = Game1.GameManager.GetItem("dmap") != null; + var hasCompass = Game1.GameManager.GetItem("compass") != null; + + while (true) + { + // does the map exist? + var name = Game1.GameManager.MapManager.CurrentMap.LocationName + "_" + level; + if (!Game1.GameManager.DungeonMaps.TryGetValue(name, out var normalMap)) + break; + + var dungeonMap = GetAlternativeMap(name) ?? normalMap; + + var posX = _mapPosition.X + dungeonMap.OffsetX; + var posY = _mapPosition.Y + dungeonMap.OffsetY; + + // draw the map + for (var y = 0; y < dungeonMap.Tiles.GetLength(1); y++) + for (var x = 0; x < dungeonMap.Tiles.GetLength(0); x++) + { + int tileIndex; + // use the discovery state from the normal map + if (!normalMap.Tiles[x, y].DiscoveryState && dungeonMap.Tiles[x, y].TileIndex > 4) + tileIndex = hasMap ? _mapTile : _undiscoveredTile; + else + tileIndex = dungeonMap.Tiles[x, y].TileIndex; + + spriteBatch.Draw(Resources.SprMiniMap, + new Rectangle( + posX + x * _tileWidth, posY + y * _tileHeight, + _tileWidth, _tileHeight), + new Rectangle( + _recMap.X + (tileIndex - 1) * (_tileWidth + 2), + _recMap.Y, _tileWidth, _tileHeight), Color.White); + + // draw the hints on the map if the player has a compass + if (hasCompass) + { + tileIndex = dungeonMap.Tiles[x, y].HintTileIndex; + + if (tileIndex > 0) + { + // chest opened or boss defeated? + if (Game1.GameManager.SaveManager.GetString(dungeonMap.Tiles[x, y].HintKey) == "1") + continue; + //tileIndex += 1; + + spriteBatch.Draw(Resources.SprMiniMap, + new Rectangle( + posX + x * _tileWidth, posY + y * _tileHeight, + _tileWidth, _tileHeight), + new Rectangle( + _hintMap.X + (tileIndex - 1) * (_tileWidth + 2), + _hintMap.Y, _tileWidth, _tileHeight), Color.White); + } + } + } + + // draw the position indicator + if (Game1.GameManager.MapManager.CurrentMap.LocationFullName == name) + { + var position = new Vector2( + posX + Game1.GameManager.PlayerDungeonPosition.X * 8 + 1, + posY + Game1.GameManager.PlayerDungeonPosition.Y * 8 + 1); + _animationPlayer.Draw(spriteBatch, position, Color.White); + } + + level++; + } + + spriteBatch.End(); + } + + private GameManager.MiniMap GetAlternativeMap(string name) + { + // this allows for map file switching by adding a postfix to the dungeon name + var mapName = name + Game1.GameManager.SaveManager.GetString(name + "_map", ""); + Game1.GameManager.DungeonMaps.TryGetValue(mapName, out var altMap); + + return altMap; + } + + private void DrawBackground(SpriteBatch spriteBatch, Point offset, Rectangle rectangle, float radius) + { + Resources.RoundedCornerEffect.Parameters["radius"].SetValue(radius); + Resources.RoundedCornerEffect.Parameters["width"].SetValue(rectangle.Width); + Resources.RoundedCornerEffect.Parameters["height"].SetValue(rectangle.Height); + + spriteBatch.Draw(Resources.SprWhite, new Rectangle(offset.X + rectangle.X, offset.Y + rectangle.Y, rectangle.Width, rectangle.Height), Color.Black * 0.25f); + } + } +} \ No newline at end of file diff --git a/InGame/Overlay/HUDOverlay.cs b/InGame/Overlay/HUDOverlay.cs new file mode 100644 index 0000000..9a96558 --- /dev/null +++ b/InGame/Overlay/HUDOverlay.cs @@ -0,0 +1,116 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base.UI; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Overlay +{ + public class HudOverlay + { + private readonly ItemSlotOverlay _itemSlotOverlay = new ItemSlotOverlay(); + + private readonly UiRectangle _heartBackground; + private readonly UiRectangle _rubeeBackground; + + private readonly DictAtlasEntry _saveIcon; + + private Rectangle _gameUiWindow; + + private Point _heartPosition; + private Point _rubeePosition; + private Vector2 _saveIconPosition; + + private const int FadeOffsetBackground = 10; + private const int FadeOffset = 13; + + private const int SaveIconTime = 1000; + private float _saveIconTransparency; + private float _saveIconCounter; + + public HudOverlay() + { + _heartBackground = new UiRectangle(Rectangle.Empty, "heart", Values.ScreenNameGame, Values.OverlayBackgroundColor, Values.OverlayBackgroundBlurColor, null) { Radius = Values.UiBackgroundRadius }; + Game1.EditorUi.AddElement(_heartBackground); + + _rubeeBackground = new UiRectangle(Rectangle.Empty, "rubee", Values.ScreenNameGame, Values.OverlayBackgroundColor, Values.OverlayBackgroundBlurColor, null) { Radius = Values.UiBackgroundRadius }; + Game1.EditorUi.AddElement(_rubeeBackground); + + _saveIcon = Resources.GetSprite("save_icon"); + } + + public void Update(float fadePercentage, float transparency) + { + _saveIconCounter -= Game1.DeltaTime; + if (_saveIconCounter < 0) + _saveIconCounter = 0; + _saveIconTransparency = Math.Min(Math.Clamp(_saveIconCounter / 100, 0, 1), Math.Clamp((SaveIconTime - _saveIconCounter) / 100, 0, 1)); + + // TODO_Opt: maybe add settings for wide screen positioning + var scale = Math.Min(Game1.WindowWidth / (float)Values.MinWidth, Game1.WindowHeight / (float)Values.MinHeight); + + // not so gud + _gameUiWindow.Width = (int)(Values.MinWidth * scale); + _gameUiWindow.Height = (int)(Values.MinHeight * scale); + + var ar = MathHelper.Clamp(Game1.WindowWidth / (float)Game1.WindowHeight, 1, 2); + + _gameUiWindow.Width = MathHelper.Clamp((int)(Game1.WindowHeight * ar), 0, Game1.WindowWidth); + _gameUiWindow.Height = MathHelper.Clamp((int)(Game1.WindowWidth / ar), 0, Game1.WindowHeight); + _gameUiWindow.X = Game1.WindowWidth / 2 - _gameUiWindow.Width / 2; + _gameUiWindow.Y = Game1.WindowHeight / 2 - _gameUiWindow.Height / 2; + + // top left + _heartPosition = new Point(_gameUiWindow.X + 16 * Game1.UiScale, _gameUiWindow.Y + 16 * Game1.UiScale); + _heartBackground.Rectangle = ItemDrawHelper.GetHeartRectangle(_heartPosition, Game1.UiScale); + _heartBackground.Rectangle.X -= (int)(fadePercentage * FadeOffsetBackground * Game1.UiScale); + _heartBackground.BackgroundColor = Values.OverlayBackgroundColor * transparency; + _heartBackground.BlurColor = Values.OverlayBackgroundBlurColor * transparency; + + // top right + _rubeePosition = new Point( + _gameUiWindow.X + _gameUiWindow.Width - ItemDrawHelper.RubeeSize.X * Game1.UiScale - 16 * Game1.UiScale, + _gameUiWindow.Y + 16 * Game1.UiScale); + _rubeeBackground.Rectangle = ItemDrawHelper.GetRubeeRectangle(new Point(_rubeePosition.X, _rubeePosition.Y), Game1.UiScale); + _rubeeBackground.Rectangle.X += (int)(fadePercentage * FadeOffsetBackground * Game1.UiScale); + _rubeeBackground.BackgroundColor = Values.OverlayBackgroundColor * transparency; + _rubeeBackground.BlurColor = Values.OverlayBackgroundBlurColor * transparency; + + // bottom left + _itemSlotOverlay.UpdatePositions(_gameUiWindow, new Point(-(int)(fadePercentage * FadeOffsetBackground * Game1.UiScale), 0), Game1.UiScale); + _itemSlotOverlay.SetTransparency(transparency); + + // bottom right + _saveIconPosition = new Vector2( + _gameUiWindow.X + _gameUiWindow.Width - _saveIcon.SourceRectangle.Width * Game1.UiScale - 16 * Game1.UiScale, + _gameUiWindow.Y + _gameUiWindow.Height - _saveIcon.SourceRectangle.Height * Game1.UiScale - 16 * Game1.UiScale); + } + + public void DrawTop(SpriteBatch spriteBatch, float fadePercentage, float transparency) + { + // draw the item slots + ItemSlotOverlay.Draw(spriteBatch, _itemSlotOverlay.ItemSlotPosition - new Point((int)(fadePercentage * FadeOffset * Game1.UiScale), 0), Game1.UiScale, transparency); + + //DrawHelper.DrawSmallKeys(spriteBatch, _keyPosition, Game1.UiScale, Color.White * transparency); + + // draw the rubees + ItemDrawHelper.DrawRubee(spriteBatch, _rubeePosition + new Point((int)(fadePercentage * FadeOffset * Game1.UiScale), 0), Game1.UiScale, Color.Black * transparency); + + // draw the heart position + ItemDrawHelper.DrawHearts(spriteBatch, _heartPosition - new Point((int)(fadePercentage * FadeOffset * Game1.UiScale), 0), Game1.UiScale, Color.White * transparency); + } + + public void DrawBlur(SpriteBatch spriteBatch) + { + // draw the save icon + Resources.RoundedCornerBlurEffect.Parameters["blurColor"].SetValue((Values.OverlayBackgroundBlurColor * _saveIconTransparency).ToVector4()); + DrawHelper.DrawNormalized(spriteBatch, _saveIcon.Texture, _saveIconPosition, _saveIcon.ScaledRectangle, Values.OverlayBackgroundColor * _saveIconTransparency, Game1.UiScale); + } + + public void ShowSaveIcon() + { + _saveIconCounter = SaveIconTime; + } + } +} diff --git a/InGame/Overlay/InventoryOverlay.cs b/InGame/Overlay/InventoryOverlay.cs new file mode 100644 index 0000000..ce21d86 --- /dev/null +++ b/InGame/Overlay/InventoryOverlay.cs @@ -0,0 +1,502 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Overlay +{ + class InventoryOverlay + { + private const int Margin = 6; + + private RenderTarget2D _renderTarget; + + private readonly Rectangle _background0 = new Rectangle(0, 0, 268, 24); + private readonly Rectangle _background1 = new Rectangle(0, 26, 268, 182); + + private readonly Rectangle _keyRectangle = new Rectangle(94, 6, 20, 114); + private readonly Rectangle[] _keyPositions = new Rectangle[5]; + + private readonly Rectangle _relictsRectangle = new Rectangle(118, 6, 144, 22); + private readonly Point _relictPosition = new Point(123, 9); + private readonly Rectangle[] _relicOffsets = new Rectangle[8]; + + private readonly DictAtlasEntry[] _ocarinaFaces = new DictAtlasEntry[3]; + + private readonly Point _heartsPosition = new Point(6, 5); + private readonly Point _rubeePosition; + + private readonly Rectangle _flipperRectangle; + private readonly Rectangle _potionRectangle; + + private readonly Rectangle _tradeStuffRectangle = new Rectangle(6, 6, 84, 22); + private Rectangle _tradeRectangle; + private Rectangle _shellRectangle; + private Rectangle _leafRectangle; + + private readonly Point _skirtPosition; + private readonly Point _heartPiecePosition; + + private readonly Point _itemSlotsPosition = new Point(14, 41); + + private readonly Rectangle _skirtRectangle = new Rectangle(180, 31, 16, 15); + private readonly Rectangle _skirtColorRectangle = new Rectangle(198, 37, 14, 10); + private readonly Rectangle _heartPiecesRectangle = new Rectangle(4, 72, 16, 14); + + private const int ItemSlotWidth = 4; + + public static Rectangle RecItemselection = new Rectangle(0, 0, 30, 20); + + public const int DistX = 8; + public const int DistY = 5; + + private static string[] _itemSlotString = new[] { "A", "B", "X", "Y" }; + + // 3 + // 2 1 + // 0 + private static Rectangle[] _itemSlots = { + new Rectangle(RecItemselection.Width + DistX / 2 - RecItemselection.Width / 2, + RecItemselection.Height * 2 + DistY * 2, + RecItemselection.Width, RecItemselection.Height), + new Rectangle(RecItemselection.Width + DistX, RecItemselection.Height + DistY, + RecItemselection.Width, RecItemselection.Height), + new Rectangle(0, RecItemselection.Height + DistY, + RecItemselection.Width, RecItemselection.Height), + new Rectangle(RecItemselection.Width + DistX / 2 - RecItemselection.Width / 2, 0, + RecItemselection.Width, RecItemselection.Height) + }; + + + private int _selectedItemSlot; + + private readonly Point _itemRectangleSize = new Point(27, 26); + private readonly Point _itemRecMargin = new Point(0, 0); + + private readonly Point _equipmentPosition = new Point(6, 123); + private readonly Rectangle _itemsRectangle = new Rectangle(6, 124, 108, 52); + + private readonly int _width; + private readonly int _height; + + private float _selectionCounter; + private const int SelectionTime = 125; + private bool _selectionButtonPressed; + + public InventoryOverlay(int width, int height) + { + _width = width; + _height = height; + + _rubeePosition = new Point(width - ItemDrawHelper.RubeeSize.X - Margin, 10); + + var blockPosition = 97; + _skirtPosition = new Point(blockPosition, 5); + _heartPiecePosition = new Point(blockPosition += 34, 6); + _flipperRectangle = new Rectangle(blockPosition += 18, 0, 12, _background0.Height); + _potionRectangle = new Rectangle(blockPosition += 12, 0, 12, _background0.Height); + + // key positions + for (var i = 0; i < 5; i++) + _keyPositions[i] = new Rectangle(96, 12 + i * 21, 16, 16); + + // relict positions + for (var i = 0; i < 8; i++) + _relicOffsets[i] = new Rectangle(i * 17, 0, 16, 16); + + _ocarinaFaces[0] = Resources.GetSprite("ocarina1"); + _ocarinaFaces[1] = Resources.GetSprite("ocarina2"); + _ocarinaFaces[2] = Resources.GetSprite("ocarina3"); + } + + public void UpdateRenderTarget() + { + if (_renderTarget == null || _renderTarget.Width != _width * Game1.UiScale || _renderTarget.Height != _height * Game1.UiScale) + _renderTarget = new RenderTarget2D(Game1.Graphics.GraphicsDevice, _width * Game1.UiScale, _height * Game1.UiScale); + } + + public void UpdateMenu() + { + for (var i = 0; i < 4; i++) + { + if (ControlHandler.ButtonPressed((CButtons)((int)CButtons.A * Math.Pow(2, i)))) + { + Game1.GameManager.PlaySoundEffect("D360-19-13"); + Game1.GameManager.ChangeItem(i, _selectedItemSlot + Values.HandItemSlots); + } + } + + var selectionOffset = 0; + + var direction = ControlHandler.GetMoveVector2(); + if (direction.Length() > Values.ControllerDeadzone) + { + _selectionCounter -= Game1.DeltaTime; + if (_selectionCounter <= 0 || !_selectionButtonPressed) + { + _selectionCounter += SelectionTime; + + var dir = AnimationHelper.GetDirection(direction); + if (dir == 0) + selectionOffset -= 1; + else if (dir == 1) + selectionOffset -= ItemSlotWidth; + else if (dir == 2) + selectionOffset += 1; + else if (dir == 3) + selectionOffset += ItemSlotWidth; + } + + _selectionButtonPressed = true; + } + else + { + _selectionButtonPressed = false; + _selectionCounter = SelectionTime; + } + + // update the selected ocarina song + var selectedItem = Game1.GameManager.Equipment[Values.HandItemSlots + _selectedItemSlot]; + if (selectedItem != null && selectedItem.Name == "ocarina") + { + if ((selectionOffset == -1 || selectionOffset == 1) && + MoveOcarinaSelection(selectionOffset)) + selectionOffset = 0; + } + + _selectedItemSlot += selectionOffset; + + var slots = GameManager.EquipmentSlots - 4; + if (_selectedItemSlot < 0) + _selectedItemSlot += slots; + if (_selectedItemSlot >= slots) + _selectedItemSlot = _selectedItemSlot % slots; + } + + private bool MoveOcarinaSelection(int direction) + { + var previousSong = Game1.GameManager.SelectedOcarinaSong; + + for (var i = 0; i < Game1.GameManager.Equipment.Length; i++) + { + Game1.GameManager.SelectedOcarinaSong += direction; + if (Game1.GameManager.SelectedOcarinaSong < 0 || + Game1.GameManager.SelectedOcarinaSong >= _ocarinaFaces.Length) + { + Game1.GameManager.SelectedOcarinaSong = previousSong; + return false; + } + + if (Game1.GameManager.SelectedOcarinaSong != -1 && + Game1.GameManager.OcarinaSongs[Game1.GameManager.SelectedOcarinaSong] == 1) + return Game1.GameManager.SelectedOcarinaSong != previousSong; + } + + Game1.GameManager.SelectedOcarinaSong = -1; + return false; + } + + public void Draw(SpriteBatch spriteBatch, Rectangle drawPosition, Color color) + { + spriteBatch.Draw(_renderTarget, drawPosition, color); + } + + public void DrawRT(SpriteBatch spriteBatch) + { + Game1.Graphics.GraphicsDevice.SetRenderTarget(_renderTarget); + Game1.Graphics.GraphicsDevice.Clear(Color.Transparent); + + Resources.RoundedCornerEffect.Parameters["scale"].SetValue(Game1.UiRtScale); + Resources.RoundedCornerEffect.Parameters["radius"].SetValue(3f); + + // draw the background + spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, null, Resources.RoundedCornerEffect, Matrix.CreateScale(Game1.UiRtScale)); + + Resources.RoundedCornerEffect.Parameters["width"].SetValue(_background0.Width); + Resources.RoundedCornerEffect.Parameters["height"].SetValue(_background0.Height); + spriteBatch.Draw(Resources.SprWhite, _background0, Values.InventoryBackgroundColorTop); + + Resources.RoundedCornerEffect.Parameters["width"].SetValue(_background1.Width); + Resources.RoundedCornerEffect.Parameters["height"].SetValue(_background1.Height); + spriteBatch.Draw(Resources.SprWhite, _background1, Values.InventoryBackgroundColor); + + spriteBatch.End(); + + // draw the backgrounds of the items + { + spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, null, Resources.RoundedCornerEffect, Matrix.CreateScale(Game1.UiRtScale)); + + var offset = new Point(_background1.X, _background1.Y); + + for (var i = 0; i < _itemSlots.Length; i++) + DrawBackground(spriteBatch, offset + _itemSlotsPosition, _itemSlots[i]); + + DrawBackground(spriteBatch, offset, _keyRectangle); + DrawBackground(spriteBatch, offset, _relictsRectangle); + DrawBackground(spriteBatch, offset, _itemsRectangle); + DrawBackground(spriteBatch, offset, _tradeStuffRectangle); + + // draw the item selection + var selectionPosition = new Point( + (_itemsRectangle.X + _selectedItemSlot % ItemSlotWidth * (_itemRectangleSize.X + _itemRecMargin.X)), + (_itemsRectangle.Y + _selectedItemSlot / ItemSlotWidth * (_itemRectangleSize.Y + _itemRecMargin.Y))); + DrawBackground(spriteBatch, offset + selectionPosition, new Rectangle(0, 0, _itemRectangleSize.X, _itemRectangleSize.Y)); + + // draw the collected items + for (var i = 0; i < Game1.GameManager.Equipment.Length - Values.HandItemSlots; i++) + { + var slotRectangle = new Rectangle( + i % ItemSlotWidth * (_itemRectangleSize.X + _itemRecMargin.X) + _itemRectangleSize.X / 2 - 2, + i / ItemSlotWidth * (_itemRectangleSize.Y + _itemRecMargin.Y) + _itemRectangleSize.Y - 8, 4, 2); + + if (Game1.GameManager.Equipment[Values.HandItemSlots + i] == null) + DrawBackground(spriteBatch, offset + _equipmentPosition, slotRectangle, 1); + } + + // key background dots + for (var i = 0; i < 5; i++) + { + var slotRectangle = new Rectangle( + _keyPositions[i].X + _keyPositions[i].Width / 2 - 2, + _keyPositions[i].Y + _keyPositions[i].Height - 2, 4, 2); + + var itemKey = Game1.GameManager.GetItem("dkey" + (i + 1)); + if (itemKey == null) + DrawBackground(spriteBatch, offset, slotRectangle, 1); + } + + for (var i = 0; i < _relicOffsets.Length; i++) + { + var name = "instrument" + i; + var hasItem = Game1.GameManager.GetItem(name) != null; + + if (!hasItem) + { + var position = new Point(_relictPosition.X + _relicOffsets[i].X + _relicOffsets[i].Width / 2 - 2, _relictPosition.Y + _relicOffsets[i].Bottom - 2); + DrawBackground(spriteBatch, offset + position, new Rectangle(0, 0, 4, 2), 1); + } + } + + spriteBatch.End(); + } + + // draw the map + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, null, null, null, Matrix.CreateScale(Game1.UiRtScale)); + + { + var heartOffset = new Point(0, Game1.GameManager.MaxHearths > 7 ? 0 : 4); + ItemDrawHelper.DrawHearts(spriteBatch, _heartsPosition + heartOffset, 1, Color.White); + + // draw the skirt + DrawSkirt(spriteBatch, _skirtPosition); + + DrawHeartContainer(spriteBatch, _heartPiecePosition); + + ItemDrawHelper.DrawItemWithInfo(spriteBatch, Game1.GameManager.GetItem("flippers"), Point.Zero, _flipperRectangle, 1, Color.White); + + ItemDrawHelper.DrawItemWithInfo(spriteBatch, Game1.GameManager.GetItem("potion"), Point.Zero, _potionRectangle, 1, Color.White); + + ItemDrawHelper.DrawRubee(spriteBatch, _rubeePosition, 1, Color.Black); + + var offsetBottom = new Point(_background1.X, _background1.Y); + + // center the items + { + var width = 0; + var hasTradeItem = false; + for (var i = 0; i < 15; i++) + { + hasTradeItem = Game1.GameManager.GetItem("trade" + i) != null; + if (hasTradeItem) + { + width += 28; + break; + } + } + var itemShell = Game1.GameManager.GetItem("shell"); + var itemLeaf = Game1.GameManager.GetItem("goldLeaf"); + if (itemShell != null) + width += 28; + if (itemLeaf != null) + width += 28; + + var posX = _tradeStuffRectangle.Width / 2 - width / 2; + _tradeRectangle = new Rectangle(6 + posX, 6, 28, 22); + + if (hasTradeItem) + posX += 28; + _shellRectangle = new Rectangle(6 + posX, 6, 28, 22); + + if (itemShell != null) + posX += 28; + _leafRectangle = new Rectangle(6 + posX, 6, 28, 22); + + // draw the current trade item + DrawTradeItem(spriteBatch, offsetBottom, 1); + ItemDrawHelper.DrawItemWithInfo(spriteBatch, Game1.GameManager.GetItem("shell"), offsetBottom, _shellRectangle, 1, Color.White); + ItemDrawHelper.DrawItemWithInfo(spriteBatch, Game1.GameManager.GetItem("goldLeaf"), offsetBottom, _leafRectangle, 1, Color.White); + } + + // draw the collected equipment + DrawEquipment(spriteBatch, offsetBottom + _equipmentPosition); + + // draw the item slots + for (var i = 0; i < _itemSlots.Length; i++) + { + ItemDrawHelper.DrawItemWithInfo(spriteBatch, Game1.GameManager.Equipment[i], offsetBottom + _itemSlotsPosition, _itemSlots[i], 1, Color.White); + + spriteBatch.DrawString(Resources.GameFont, _itemSlotString[i], new Vector2( + offsetBottom.X + _itemSlotsPosition.X + _itemSlots[i].Right - 4, + offsetBottom.Y + _itemSlotsPosition.Y + _itemSlots[i].Bottom - 4), Color.Black); + } + + // draw the collected keys + for (var i = 0; i < 5; i++) + ItemDrawHelper.DrawItemWithInfo(spriteBatch, Game1.GameManager.GetItem("dkey" + (i + 1)), offsetBottom, _keyPositions[i], 1, Color.White); + + DrawRelicts(spriteBatch, offsetBottom + _relictPosition); + } + + spriteBatch.End(); + } + + private void DrawBackground(SpriteBatch spriteBatch, Point offset, Rectangle rectangle, float radius = 3f) + { + Resources.RoundedCornerEffect.Parameters["radius"].SetValue(radius); + Resources.RoundedCornerEffect.Parameters["width"].SetValue(rectangle.Width); + Resources.RoundedCornerEffect.Parameters["height"].SetValue(rectangle.Height); + + spriteBatch.Draw(Resources.SprWhite, new Rectangle(offset.X + rectangle.X, offset.Y + rectangle.Y, rectangle.Width, rectangle.Height), Color.Black * 0.15f); + } + + public void DrawEquipment(SpriteBatch spriteBatch, Point drawPosition) + { + // draw the collected items + for (var i = 0; i < Game1.GameManager.Equipment.Length - Values.HandItemSlots; i++) + { + var slotRectangle = new Rectangle( + i % ItemSlotWidth * (_itemRectangleSize.X + _itemRecMargin.X), + i / ItemSlotWidth * (_itemRectangleSize.Y + _itemRecMargin.Y), + _itemRectangleSize.X, _itemRectangleSize.Y); + + // draw the item + var itemIndex = i + Values.HandItemSlots; + var offsetY = _selectedItemSlot == i ? -1 : 0; + + if (_selectedItemSlot == i && + Game1.GameManager.Equipment[itemIndex] != null && + Game1.GameManager.Equipment[itemIndex].Name == "ocarina") + { + var hasSong = false; + for (var j = 0; j < Game1.GameManager.OcarinaSongs.Length; j++) + if (Game1.GameManager.OcarinaSongs[j] != 0) + { + hasSong = true; + break; + } + + if (hasSong) + continue; + } + + ItemDrawHelper.DrawItemWithInfo(spriteBatch, Game1.GameManager.Equipment[itemIndex], new Point(drawPosition.X, drawPosition.Y + offsetY + 1), slotRectangle, 1, Color.White); + } + + // draw the ocarina face selection + var selectedItem = Game1.GameManager.Equipment[4 + _selectedItemSlot]; + if (selectedItem != null && selectedItem.Name == "ocarina") + { + var selectedSong = Game1.GameManager.SelectedOcarinaSong; + if (selectedSong != -1) + { + var hasSong = Game1.GameManager.OcarinaSongs[selectedSong] == 1; + var position = new Vector2( + drawPosition.X + (_selectedItemSlot % ItemSlotWidth * (_itemRectangleSize.X + _itemRecMargin.X)) + + _itemRectangleSize.X / 2 - _ocarinaFaces[selectedSong].ScaledRectangle.Width / 2, + drawPosition.Y + (_selectedItemSlot / ItemSlotWidth * (_itemRectangleSize.Y + _itemRecMargin.Y)) + + _itemRectangleSize.Y / 2 - _ocarinaFaces[selectedSong].ScaledRectangle.Height / 2); + + DrawHelper.DrawNormalized(spriteBatch, _ocarinaFaces[selectedSong], position, hasSong ? Color.White : Color.Gray); + } + } + } + + public void DrawRelicts(SpriteBatch spriteBatch, Point drawPosition) + { + // draw the relicts + for (var i = 0; i < _relicOffsets.Length; i++) + { + var name = "instrument" + i; + var hasItem = Game1.GameManager.GetItem(name) != null; + var item = Game1.GameManager.ItemManager[name]; + + if (hasItem) + ItemDrawHelper.DrawInstrument(spriteBatch, item.Sprite, new Vector2( + drawPosition.X + _relicOffsets[i].X, drawPosition.Y + _relicOffsets[i].Y)); + } + } + + public void DrawHeartContainer(SpriteBatch spriteBatch, Point drawPosition) + { + // heartMeter + var item = Game1.GameManager.GetItem("heartMeter"); + var count = 0; + + if (item != null) + count = item.Count; + + // draw the heart container + spriteBatch.Draw(Resources.SprItem, new Rectangle( + drawPosition.X, drawPosition.Y, _heartPiecesRectangle.Width, _heartPiecesRectangle.Height), + new Rectangle(_heartPiecesRectangle.X + (_heartPiecesRectangle.Width + 2) * count, + _heartPiecesRectangle.Y, _heartPiecesRectangle.Width, _heartPiecesRectangle.Height), Color.White); + } + + public void DrawTradeItem(SpriteBatch spriteBatch, Point drawPosition, int scale) + { + // draw the current trade item + for (var i = 0; i < 15; i++) + { + var hasItem = Game1.GameManager.GetItem("trade" + i) != null; + + if (!hasItem) + continue; + + // draw the key + DrawHelper.DrawCenter(spriteBatch, Resources.SprItem, + drawPosition, _tradeRectangle, Game1.GameManager.ItemManager["trade" + i].SourceRectangle.Value, scale); + + break; + } + } + + public void DrawSkirt(SpriteBatch spriteBatch, Point drawPosition) + { + // draw GBR + spriteBatch.Draw(Resources.SprItem, new Rectangle( + drawPosition.X, + drawPosition.Y + 2, + _skirtColorRectangle.Width, _skirtColorRectangle.Height), + new Rectangle( + _skirtColorRectangle.X, + _skirtColorRectangle.Y + Game1.GameManager.CloakType * (_skirtColorRectangle.Height + 1), + _skirtColorRectangle.Width, _skirtColorRectangle.Height), Color.White); + + var skirtPosition = new Point(drawPosition.X + _skirtColorRectangle.Width + 1, drawPosition.Y); + + // draw the skirt + spriteBatch.Draw(Resources.SprItem, new Rectangle( + skirtPosition.X, skirtPosition.Y, + _skirtRectangle.Width, _skirtRectangle.Height), _skirtRectangle, Color.White); + + // draw the skirt color + spriteBatch.Draw(Resources.SprItem, new Rectangle( + skirtPosition.X, skirtPosition.Y, + _skirtRectangle.Width, _skirtRectangle.Height), + new Rectangle(_skirtRectangle.X, _skirtRectangle.Y + _skirtRectangle.Height, + _skirtRectangle.Width, _skirtRectangle.Height), Values.SkirtColors[Game1.GameManager.CloakType]); + } + } +} diff --git a/InGame/Overlay/ItemSlotOverlay.cs b/InGame/Overlay/ItemSlotOverlay.cs new file mode 100644 index 0000000..c544299 --- /dev/null +++ b/InGame/Overlay/ItemSlotOverlay.cs @@ -0,0 +1,79 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base.UI; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Overlay +{ + class ItemSlotOverlay + { + public static Rectangle RecItemselection = new Rectangle(6, 29, 30, 20); + + public static int DistX = 2; + public static int DistY = 2; + + public Point ItemSlotPosition; + + // 3 + // 2 1 + // 0 + private static Rectangle[] _itemSlots = { + new Rectangle(RecItemselection.Width + DistX / 2 - RecItemselection.Width / 2, + RecItemselection.Height * 2 + DistY * 2, + RecItemselection.Width, RecItemselection.Height), + new Rectangle(RecItemselection.Width + DistX, RecItemselection.Height + DistY, + RecItemselection.Width, RecItemselection.Height), + new Rectangle(0, RecItemselection.Height + DistY, + RecItemselection.Width, RecItemselection.Height), + new Rectangle(RecItemselection.Width + DistX / 2 - RecItemselection.Width / 2, 0, + RecItemselection.Width, RecItemselection.Height) + }; + + private static readonly UiRectangle[] _uiBackgroundBoxes = new UiRectangle[4]; + + public ItemSlotOverlay() + { + for (var i = 0; i < _itemSlots.Length; i++) + { + _uiBackgroundBoxes[i] = + new UiRectangle(_itemSlots[i], "itemBox" + i, Values.ScreenNameGame, Values.OverlayBackgroundColor, Values.OverlayBackgroundBlurColor, null) { Radius = Values.UiBackgroundRadius }; + Game1.EditorUi.AddElement(_uiBackgroundBoxes[i]); + } + } + + public void SetTransparency(float transparency) + { + for (var i = 0; i < _itemSlots.Length; i++) + { + _uiBackgroundBoxes[i].BackgroundColor = Values.OverlayBackgroundColor * transparency; + _uiBackgroundBoxes[i].BlurColor = Values.OverlayBackgroundBlurColor * transparency; + } + } + + public static void Draw(SpriteBatch spriteBatch, Point position, int scale, float transparency) + { + // draw the item slots + for (var i = 0; i < _itemSlots.Length; i++) + { + var slotRectangle = new Rectangle(_itemSlots[i].X, _itemSlots[i].Y, RecItemselection.Width, RecItemselection.Height); + ItemDrawHelper.DrawItemWithInfo(spriteBatch, Game1.GameManager.Equipment[i], position, slotRectangle, scale, Color.White * transparency); + } + } + + public void UpdatePositions(Rectangle uiWindow, Point offset, int scale) + { + // bottom left corner + ItemSlotPosition = new Point(uiWindow.X + 16 * scale, + uiWindow.Y + uiWindow.Height - (RecItemselection.Height * 3 + DistY * 2 + 16) * scale); + + // update the background rectangles + for (var i = 0; i < _itemSlots.Length; i++) + { + _uiBackgroundBoxes[i].Rectangle = new Rectangle( + ItemSlotPosition.X + _itemSlots[i].X * scale + offset.X, + ItemSlotPosition.Y + _itemSlots[i].Y * scale + offset.Y, + _itemSlots[i].Width * scale, _itemSlots[i].Height * scale); + } + } + } +} diff --git a/InGame/Overlay/MapOverlay.cs b/InGame/Overlay/MapOverlay.cs new file mode 100644 index 0000000..65541da --- /dev/null +++ b/InGame/Overlay/MapOverlay.cs @@ -0,0 +1,380 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Overlay +{ + public class MapOverlay + { + public bool IsSelected; + + private RenderTarget2D _renderTarget; + + private readonly Rectangle _recMap = new Rectangle(8, 0, 144, 144); + private readonly Rectangle _recHide = new Rectangle(167, 103, 9, 9); + private readonly Rectangle _recIcon = new Rectangle(161, 1, 30, 30); + + private Point _selectionPosition; + private Point _iconPosition; + + private Animator _animationPlayer = new Animator(); + private Animator _animationSelection = new Animator(); + + private readonly int[,] _mapIcons = new int[16, 16]; + + private readonly string[,] _mapDialog = new string[,] { + { "map_tal_tal", "map_tal_tal", "map_tal_tal", "map_tal_tal", "map_tal_tal", "map_tal_tal", "map_wind_fishs_egg", "map_mt_tamaranch", "map_owl_bridge", "map_tal_tal", "map_hen_house", "map_tal_tal", "map_tal_tal", "map_tal_tal", "map_level_7", "map_tal_tal" }, + { "map_level_8","map_telephone_booth","map_tal_tal","map_tal_tal","map_tal_tal","map_tal_tal","map_owl_fish","map_owl_mountain","map_tal_tal","map_tal_tal","map_tal_tal","map_tal_tal","map_tal_tal","map_tal_tal","map_tal_tal","map_tal_tal" }, + { "map_goponga_swamp","map_goponga_swamp","map_goponga_swamp","map_goponga_swamp","map_level_2","map_tal_tal_heights","map_tal_tal_heights","map_tal_tal_heights","map_tal_tal_heights","map_tal_tal_heights","map_tal_tal_heights","map_level_4","map_tal_tal_heights","map_tal_tal_heights","map_tal_tal_heights","map_tal_tal_heights" }, + { "map_weird_mr_write","map_telephone_booth","map_goponga_swamp","map_goponga_swamp","map_goponga_swamp","map_tal_tal_heights","map_owl_tal_tal_heights","map_photo_both","map_tal_tal_heights","map_tal_tal_heights","map_tal_tal_heights","map_tal_tal_heights","map_tal_tal_heights","map_tal_tal_heights","map_tal_tal_heights","map_raft_shop" }, + { "map_mysterious_woods","map_owl_woods","map_mysterious_woods","map_mysterious_woods","map_koholint_prairie","map_crazy_tracy","map_tabahl_wasteland","map_tabahl_wasteland","map_kanalet_castle","map_kanalet_castle","map_kanalet_castle","map_telephone_booth","map_rapids_ride","map_rapids_ride","map_rapids_ride","map_rapids_ride" }, + { "map_mysterious_woods","map_mysterious_woods","map_mysterious_woods","map_mysterious_woods","map_koholint_prairie","map_koholint_prairie","map_tabahl_wasteland","map_tabahl_wasteland","map_kanalet_castle","map_kanalet_castle","map_kanalet_castle","map_kanalet_castle","map_rapids_ride","map_rapids_ride","map_rapids_ride","map_rapids_ride" }, + { "map_mysterious_woods","map_mysterious_woods","map_mysterious_woods","map_mysterious_woods","map_owl_prairie","map_witchs_hut","map_cementry","map_cementry","map_kanalet_castle","map_kanalet_castle","map_kanalet_castle","map_kanalet_castle","map_rapids_ride","map_rapids_ride","map_rapids_ride","map_rapids_ride" }, + { "map_mysterious_woods","map_mysterious_woods","map_mysterious_woods","map_mysterious_woods","map_koholint_prairie","map_koholint_prairie","map_cementry","map_cementry","map_kanalet_castle","map_kanalet_castle","map_kanalet_castle","map_kanalet_castle","map_rapids_ride","map_rapids_ride","map_rapids_ride","map_rapids_ride" }, + { "map_owl_woods_entry","map_fishing_pond","map_quadruplets_house","map_dream_shrine","map_ukuku_prairie","map_ukuku_prairie","map_ukuku_prairie","map_ukuku_prairie","map_telephone_booth","map_ukuku_prairie","map_seashell_mansion","map_ukuku_prairie","map_level_6","map_face_shrine","map_rapids_ride","map_rapids_ride" }, + { "map_mysterious_woods","map_mysterious_woods","map_mabe_village","map_town_tool_shop","map_ukuku_prairie","map_ukuku_prairie","map_ukuku_prairie","map_ukuku_prairie","map_ukuku_prairie","map_ukuku_prairie","map_ukuku_prairie","map_ukuku_prairie","map_owl_level_6_post","map_owl_level_6","map_rapids_ride","map_rapids_ride"}, + { "map_mabe_village","map_madam_meow","map_marin_tarin","map_mabe_village","map_telephone_booth","map_ukuku_prairie","map_ukuku_prairie","map_ukuku_prairie","map_ukuku_prairie","map_ukuku_prairie","map_ukuku_prairie","map_ukuku_prairie","map_owl_shrine","map_face_shrine","map_face_shrine","map_face_shrine" }, + { "map_village_library","map_old_man_house","map_telephone_booth","map_trendy_game","map_ukuku_prairie","map_level_3","map_owl_level_3","map_ukuku_prairie","map_ukuku_prairie","map_ukuku_prairie","map_ukuku_prairie","map_ukuku_prairie","map_face_shrine","map_face_shrine","map_face_shrine","map_face_shrine"}, + { "map_south_village","map_south_village","map_south_village","map_south_village","map_signpost_maze","map_signpost_maze","map_pothole_field","map_pothole_field","map_maraths_bay","map_maraths_bay","map_maraths_bay","map_maraths_bay","map_animal_village","map_animal_village","map_yarna_desert","map_yarna_desert"}, + { "map_south_village","map_south_village","map_owl_level_1","map_level_1","map_signpost_maze","map_signpost_maze","map_richards_villa","map_pothole_field","map_maraths_bay","map_level_5","map_maraths_bay","map_telephone_booth","map_animal_village","map_animal_village","map_yarna_desert","map_yarna_desert"}, + { "map_toronbo_shores","map_toronbo_shores","map_toronbo_shores","map_banana_house","map_toronbo_shores","map_toronbo_shores","map_maraths_bay","map_maraths_bay","map_telephone_booth","map_maraths_bay","map_maraths_bay","map_maraths_bay","map_bay_east","map_bay_east","map_owl_desert","map_yarna_desert"}, + { "map_toronbo_shores","map_toronbo_shores","map_owl_shore","map_toronbo_shores","map_toronbo_shores","map_toronbo_shores","map_house_bay","map_maraths_bay","map_maraths_bay","map_maraths_bay","map_maraths_bay","map_maraths_bay","map_bay_east","map_bay_east","map_yarna_desert","map_yarna_desert"}}; + + private float _animationCount; + private float _animationState; + + private int _width; + private int _height; + private int _margin; + + private int _iconAnimationDirection; + private int _shownSelection; + + private double _buttonDownCounter; + + private bool _iconAnimationRunning; + private bool _fullMap; + + public MapOverlay(int width, int height, int margin, bool fullMap) + { + _width = width; + _height = height; + _margin = margin; + + _fullMap = fullMap; + + // 1 shop + // 2 ? + // 3 cave + // 4 owl + _mapIcons[6, 0] = 2; + _mapIcons[8, 0] = 4; + _mapIcons[10, 0] = 2; + _mapIcons[14, 0] = 3; + + _mapIcons[0, 1] = 3; + _mapIcons[1, 1] = 2; + _mapIcons[6, 1] = 4; + _mapIcons[7, 1] = 4; + + _mapIcons[4, 2] = 3; + _mapIcons[11, 2] = 3; + + _mapIcons[0, 3] = 2; + _mapIcons[1, 3] = 2; + _mapIcons[6, 3] = 4; + _mapIcons[7, 3] = 1; + _mapIcons[15, 3] = 3; + + _mapIcons[1, 4] = 4; + _mapIcons[5, 4] = 1; + _mapIcons[11, 4] = 2; + + _mapIcons[4, 6] = 4; + _mapIcons[5, 6] = 1; + + _mapIcons[0, 8] = 4; + _mapIcons[1, 8] = 1; + _mapIcons[2, 8] = 2; + _mapIcons[3, 8] = 2; + _mapIcons[8, 8] = 2; + _mapIcons[10, 8] = 2; + _mapIcons[12, 8] = 3; + + _mapIcons[3, 9] = 2; + _mapIcons[12, 9] = 4; + _mapIcons[13, 9] = 4; + + _mapIcons[1, 10] = 2; + _mapIcons[2, 10] = 2; + _mapIcons[4, 10] = 2; + _mapIcons[12, 10] = 4; + + _mapIcons[0, 11] = 2; + _mapIcons[1, 11] = 2; + _mapIcons[2, 11] = 2; + _mapIcons[3, 11] = 1; + _mapIcons[5, 11] = 3; + _mapIcons[6, 11] = 4; + + _mapIcons[2, 13] = 4; + _mapIcons[3, 13] = 3; + _mapIcons[6, 13] = 2; + _mapIcons[9, 13] = 3; + _mapIcons[11, 13] = 2; + + _mapIcons[3, 14] = 2; + _mapIcons[8, 14] = 2; + _mapIcons[14, 14] = 4; + + _mapIcons[2, 15] = 4; + _mapIcons[6, 15] = 2; + } + + public void Load() + { + _animationPlayer = AnimatorSaveLoad.LoadAnimator("mapPlayer"); + _animationSelection = AnimatorSaveLoad.LoadAnimator("mapSelector"); + + _animationPlayer.Play("idle"); + _animationSelection.Play("idle"); + } + + public void UpdateRenderTarget() + { + if (_renderTarget == null || _renderTarget.Width != _width * Game1.UiScale || _renderTarget.Height != _height * Game1.UiScale) + _renderTarget = new RenderTarget2D(Game1.Graphics.GraphicsDevice, _width * Game1.UiScale, _height * Game1.UiScale); + } + + public void Update() + { + _animationPlayer.Update(); + + var mapIcon = _mapIcons[_selectionPosition.X, _selectionPosition.Y]; + + // for owl icons we only show the icon if the owl key was already set + if (mapIcon == 4 && Game1.GameManager.SaveManager.GetString(_mapDialog[_selectionPosition.Y, _selectionPosition.X], "0") != "1") + mapIcon = 0; + + if ((mapIcon != _shownSelection || (mapIcon != 0 && !IsSelected)) && !_iconAnimationRunning) + { + if (mapIcon != 0 && _shownSelection == 0 && IsSelected) + PlayStartAnimation(); + else + PlayStopAnimation(); + } + + // update the icon run animation + if (_iconAnimationRunning) + { + _animationCount += Game1.DeltaTime / 100f * _iconAnimationDirection; + + if (_animationCount >= Math.PI / 2) + { + _iconAnimationRunning = false; + _animationCount = (float)(Math.PI / 2); + } + else if (_animationCount < 0) + { + _iconAnimationRunning = false; + _shownSelection = 0; + } + + _animationState = (float)Math.Sin(_animationCount); + } + + if (!IsSelected) + return; + + _animationSelection.Update(); + + if (!Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen) + UpdateInput(); + } + + private void UpdateInput() + { + if (ControlHandler.ButtonDown(CButtons.Left) || ControlHandler.ButtonDown(CButtons.Right) || + ControlHandler.ButtonDown(CButtons.Up) || ControlHandler.ButtonDown(CButtons.Down)) + _buttonDownCounter -= Game1.DeltaTime; + else + _buttonDownCounter = 225; + + if (ControlHandler.ButtonPressed(CButtons.Left) || (ControlHandler.ButtonDown(CButtons.Left) && _buttonDownCounter < 0)) + { + _buttonDownCounter += 50; + MoveSelection(_selectionPosition + new Point(-1, 0)); + } + if (ControlHandler.ButtonPressed(CButtons.Right) || (ControlHandler.ButtonDown(CButtons.Right) && _buttonDownCounter < 0)) + { + _buttonDownCounter += 50; + MoveSelection(_selectionPosition + new Point(1, 0)); + } + if (ControlHandler.ButtonPressed(CButtons.Up) || (ControlHandler.ButtonDown(CButtons.Up) && _buttonDownCounter < 0)) + { + _buttonDownCounter += 50; + MoveSelection(_selectionPosition + new Point(0, -1)); + } + if (ControlHandler.ButtonPressed(CButtons.Down) || (ControlHandler.ButtonDown(CButtons.Down) && _buttonDownCounter < 0)) + { + _buttonDownCounter += 50; + MoveSelection(_selectionPosition + new Point(0, 1)); + } + + if (ControlHandler.ButtonPressed(CButtons.A)) + { + if (0 <= _selectionPosition.X && _selectionPosition.X < _mapDialog.GetLength(1) && + 0 <= _selectionPosition.Y && _selectionPosition.Y < _mapDialog.GetLength(0)) + Game1.GameManager.RunDialog(_mapDialog[_selectionPosition.Y, _selectionPosition.X]); + } + } + + public void PlayStartAnimation() + { + _iconPosition = new Point(8, 8); + + _iconPosition.X += _selectionPosition.X >= _mapIcons.GetLength(0) / 2 ? 8 : _mapIcons.GetLength(0) * 8 - _recIcon.Width - 8; + _iconPosition.Y += _selectionPosition.Y >= _mapIcons.GetLength(1) / 2 ? _mapIcons.GetLength(1) * 8 - _recIcon.Height - 8 : 8; + + _animationCount = 0; + _iconAnimationDirection = 1; + _iconAnimationRunning = true; + _shownSelection = _mapIcons[_selectionPosition.X, _selectionPosition.Y]; + } + + public void PlayStopAnimation() + { + _animationCount = (float)(Math.PI / 2); + _iconAnimationDirection = -1; + _iconAnimationRunning = true; + } + + public void OnFocus() + { + _shownSelection = 0; + _animationState = 0; + + if (Game1.GameManager.PlayerMapPosition != null) + _selectionPosition = Game1.GameManager.PlayerMapPosition.Value; + } + + public void MoveSelection(Point newPosition) + { + if (newPosition.X < 0) + newPosition.X += Game1.GameManager.MapVisibility.GetLength(0); + if (newPosition.X >= Game1.GameManager.MapVisibility.GetLength(0)) + newPosition.X -= Game1.GameManager.MapVisibility.GetLength(0); + if (newPosition.Y < 0) + newPosition.Y += Game1.GameManager.MapVisibility.GetLength(1); + if (newPosition.Y >= Game1.GameManager.MapVisibility.GetLength(1)) + newPosition.Y -= Game1.GameManager.MapVisibility.GetLength(1); + + // only move the selection if the new position is visible + if (newPosition.X >= 0 && newPosition.Y >= 0 && + newPosition.X < Game1.GameManager.MapVisibility.GetLength(0) && + newPosition.Y < Game1.GameManager.MapVisibility.GetLength(1) && + (_fullMap || Game1.GameManager.MapVisibility[newPosition.X, newPosition.Y])) + { + _selectionPosition = newPosition; + + _animationSelection.Stop(); + _animationSelection.Play("idle"); + } + } + + public void Draw(SpriteBatch spriteBatch, Rectangle drawPosition, Color color, Matrix? matrix = null) + { + Resources.RoundedCornerEffect.Parameters["scale"].SetValue(Game1.UiRtScale); + Resources.RoundedCornerEffect.Parameters["radius"].SetValue(2f); + Resources.RoundedCornerEffect.Parameters["width"].SetValue(_width); + Resources.RoundedCornerEffect.Parameters["height"].SetValue(_height); + + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, null, null, Resources.RoundedCornerEffect, matrix); + + spriteBatch.Draw(_renderTarget, drawPosition, color); + + spriteBatch.End(); + + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, null, null, null, matrix); + + if (Game1.GameManager.PlayerMapPosition != null) + { + var mapRectangle = new Point(drawPosition.X + _margin, drawPosition.Y + _margin); + // draw the player + var position = new Vector2( + mapRectangle.X + (8 + Game1.GameManager.PlayerMapPosition.Value.X * 8 + 2) * Game1.UiRtScale, + mapRectangle.Y + (8 + Game1.GameManager.PlayerMapPosition.Value.Y * 8 + 2) * Game1.UiRtScale); + _animationPlayer.DrawBasic(spriteBatch, position, color, Game1.UiRtScale); + + // draw the selection + if (IsSelected) + { + position = new Vector2( + mapRectangle.X + (8 + _selectionPosition.X * 8 + 1) * Game1.UiRtScale, + mapRectangle.Y + (8 + _selectionPosition.Y * 8 + 1) * Game1.UiRtScale); + _animationSelection.DrawBasic(spriteBatch, position, color, Game1.UiRtScale); + } + } + + spriteBatch.End(); + } + + public void DrawRenderTarget(SpriteBatch spriteBatch) + { + Game1.Graphics.GraphicsDevice.SetRenderTarget(_renderTarget); + Game1.Graphics.GraphicsDevice.Clear(Color.Transparent); + + // draw the map + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, null, null, null, Matrix.CreateScale(Game1.UiRtScale)); + DrawMap(spriteBatch); + spriteBatch.End(); + } + + public void DrawMap(SpriteBatch spriteBatch) + { + var mapRectangle = new Point(_margin, _margin); + + // draw the map + spriteBatch.Draw(Resources.SprMiniMap, + new Rectangle(mapRectangle.X, mapRectangle.Y, _recMap.Width, _recMap.Height), _recMap, Color.White); + + // overlay the not discovered parts of the map + if (!_fullMap) + for (var x = 0; x < 16; x++) + { + for (var y = 0; y < 16; y++) + { + if (!Game1.GameManager.MapVisibility[x, y]) + spriteBatch.Draw(Resources.SprMiniMap, new Rectangle( + mapRectangle.X + 8 + x * 8, + mapRectangle.Y + 8 + y * 8, + _recHide.Width, _recHide.Height), _recHide, Color.White); + } + } + + // draw icon of the selection + if (_shownSelection > 0) + { + DrawIcon(spriteBatch, new Point( + mapRectangle.X + _iconPosition.X, + mapRectangle.Y + _iconPosition.Y), _shownSelection, 1, _animationState); + } + } + + public void DrawIcon(SpriteBatch spriteBatch, Point position, int icon, int scale, float animationPercentage) + { + var width = (int)(_recIcon.Width * animationPercentage) / 2; + var height = (int)(_recIcon.Height * animationPercentage) / 2; + var posX = position.X + (_recIcon.Width / 2 - width); + var posY = position.Y + (_recIcon.Height / 2 - height); + + spriteBatch.Draw(Resources.SprMiniMap, new Rectangle(posX, posY, width * 2, height * 2), + new Rectangle(_recIcon.X + _recIcon.Width * (icon - 1), + _recIcon.Y, _recIcon.Width, _recIcon.Height), Color.White); + } + } +} \ No newline at end of file diff --git a/InGame/Overlay/OverlayManager.cs b/InGame/Overlay/OverlayManager.cs new file mode 100644 index 0000000..3e3569d --- /dev/null +++ b/InGame/Overlay/OverlayManager.cs @@ -0,0 +1,481 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.Base.UI; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.Overlay.Sequences; +using ProjectZ.InGame.Pages; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Overlay +{ + public class OverlayManager + { + public float HudTransparency = 1; + public bool DisableOverlayToggle; + public bool DisableInventoryToggle; + + enum MenuState + { + None, Menu, Inventory, PhotoBook, GameSequence + } + + private MenuState _currentMenuState = MenuState.None; + private MenuState _lastMenuState = MenuState.None; + + public TextboxOverlay TextboxOverlay; + public HudOverlay InGameHud; + + private InventoryOverlay _inventoryOverlay; + private MapOverlay _mapOverlay; + private DungeonOverlay _dungeonOverlay; + private PhotoOverlay _photoOverlay; + + private Dictionary _gameSequences = new Dictionary(); + private string _currentSequenceName; + + private RenderTarget2D _menuRenderTarget2D; + + private UiRectangle _blurRectangle; + + private Rectangle _recInventory; + private Rectangle _recMap; + private Rectangle _recMapCenter; + private Rectangle _recDungeon; + + private Vector2 _menuPosition; + + private Point _inventorySize; + private Point _mapSize; + private Point _dungeonSize; + private Point _overlaySize; + + private double _fadeCount; + private float _fadeAnimationPercentage; + + private float _hudState = 1; + private float _hudPercentage; + private bool _hideHud; + + private readonly int _marginMap = 0; + private readonly int _margin = 2; + private readonly int _fadeTime = 200; + private const int ChangeTime = 125; + private int _fadeDir; + private int _scale; + private float _changeCount; + + private int _overlayWidth; + private int _overlayHeight; + + private bool _fading; + private bool _updateInventory = true; + private bool _isChanging; + + public OverlayManager() + { + // setup blurry overlay + _blurRectangle = (UiRectangle)Game1.EditorUi.AddElement( + new UiRectangle(Rectangle.Empty, "background", Values.ScreenNameGame, Color.Transparent, Color.Transparent, null)); + } + + public void Load(ContentManager content) + { + _gameSequences.Add("map", new MapOverlaySequence()); + _gameSequences.Add("marinBeach", new MarinBeachSequence()); + _gameSequences.Add("marinCliff", new MarinCliffSequence()); + _gameSequences.Add("towerCollapse", new TowerCollapseSequence()); + _gameSequences.Add("shrine", new ShrineSequence()); + _gameSequences.Add("picture", new PictureSequence()); + _gameSequences.Add("photo", new PhotoSequence()); + _gameSequences.Add("bowWow", new BowWowSequence()); + _gameSequences.Add("castle", new CastleSequence()); + _gameSequences.Add("gravestone", new GravestoneSequence()); + _gameSequences.Add("weatherBird", new WeatherBirdSequence()); + _gameSequences.Add("final", new FinalSequence()); + + _mapSize = new Point(144 + 2 * _marginMap, 144 + 2 * _marginMap); + _dungeonSize = new Point(80, 106); + _inventorySize = new Point(268, 208); + _overlaySize = new Point(_inventorySize.X + _margin + _dungeonSize.X, _inventorySize.Y); + + TextboxOverlay = new TextboxOverlay(); + InGameHud = new HudOverlay(); + _mapOverlay = new MapOverlay(_mapSize.X, _mapSize.Y, _marginMap, false); + _inventoryOverlay = new InventoryOverlay(_inventorySize.X, _inventorySize.Y); + _dungeonOverlay = new DungeonOverlay(_dungeonSize.X, _dungeonSize.Y); + _photoOverlay = new PhotoOverlay(); + + _mapOverlay.Load(); + _dungeonOverlay.Load(); + _photoOverlay.Load(); + } + + public void OnLoad() + { + CloseOverlay(); + _hideHud = false; + _fadeCount = 0; + TextboxOverlay.Init(); + } + + public void Update() + { + // toggle game menu + if ((_currentMenuState == MenuState.None || _currentMenuState == MenuState.Menu) && + ControlHandler.ButtonPressed(CButtons.Start)) + ToggleState(MenuState.Menu); + + // toggle inventory/map + if ((_currentMenuState == MenuState.None || _currentMenuState == MenuState.Inventory) && + ControlHandler.ButtonPressed(CButtons.Select) && !DisableInventoryToggle && !_hideHud && !TextboxOverlay.IsOpen) + ToggleState(MenuState.Inventory); + + if (_currentMenuState == MenuState.None) + { + // update the textbox + TextboxOverlay.Update(); + } + else if (_currentMenuState == MenuState.Menu) + { + Game1.UpdateGame = false; + } + else if (_currentMenuState == MenuState.Inventory) + { + Game1.UpdateGame = false; + + if (_isChanging) + { + _changeCount += (_updateInventory ? 1 : -1) * Game1.DeltaTime; + if (_changeCount >= ChangeTime || _changeCount < 0) + { + _isChanging = false; + _changeCount = _updateInventory ? ChangeTime : 0; + _updateInventory = !_updateInventory; + } + } + else + { + if (ControlHandler.ButtonPressed(CButtons.Start) && !TextboxOverlay.IsOpen) + ToggleInventoryMap(); + + if (_updateInventory) + _inventoryOverlay.UpdateMenu(); + + _mapOverlay.IsSelected = !_updateInventory; + _mapOverlay.Update(); + // update the text box + TextboxOverlay.Update(); + + _dungeonOverlay.Update(); + } + } + else if (_currentMenuState == MenuState.PhotoBook) + { + Game1.UpdateGame = false; + + // update the text box + TextboxOverlay.Update(); + _photoOverlay.Update(); + } + else if (_currentMenuState == MenuState.GameSequence) + { + Game1.ForceDialogUpdate = true; + Game1.UpdateGame = false; + + // update the text box + TextboxOverlay.Update(); + _gameSequences[_currentSequenceName].Update(); + } + + UpdateFade(); + + InGameHud.Update(_hudPercentage, (1 - _hudPercentage) * HudTransparency); + + DisableOverlayToggle = false; + DisableInventoryToggle = false; + } + + public void Draw(SpriteBatch spriteBatch) + { + // draw the game ui; fade out with overlay fadein + InGameHud.DrawTop(spriteBatch, _hudPercentage, (1 - _hudPercentage) * HudTransparency); + + // draw the text box + TextboxOverlay.DrawTop(spriteBatch); + + // draw the inventory/map/photo overlay/gamesequence + if (_fadeAnimationPercentage > 0) + { + if (_currentMenuState == MenuState.Inventory || _lastMenuState == MenuState.Inventory) + { + // draw the menu on the screen + var menuY = 25 * _scale * (1 - _fadeAnimationPercentage); + var menuColor = Color.White * _fadeAnimationPercentage; + + int dungeonOffset; + if (!Game1.GameManager.MapManager.CurrentMap.DungeonMode) + dungeonOffset = (_margin + _dungeonSize.X) * _scale / 2; + else + { + // try to align the inventory while the dungeon panel is on the side of it + // when the resololution is not wide enough move the inventory to the left + dungeonOffset = Math.Clamp((_margin + _dungeonSize.X) * _scale / 2, -16, (Game1.WindowWidth - _overlayWidth) / 2 - 8); + } + + spriteBatch.Draw(_menuRenderTarget2D, new Rectangle( + (int)_menuPosition.X + dungeonOffset, (int)(_menuPosition.Y - menuY), _overlayWidth, _overlayHeight), menuColor); + } + else if (_currentMenuState == MenuState.PhotoBook || _lastMenuState == MenuState.PhotoBook) + _photoOverlay.Draw(spriteBatch, _fadeAnimationPercentage); + else if (_currentMenuState == MenuState.GameSequence || _lastMenuState == MenuState.GameSequence) + _gameSequences[_currentSequenceName].Draw(spriteBatch, _fadeAnimationPercentage); + + if (_currentMenuState == MenuState.Inventory) + { + var selectStr = ""; + if (ControlHandler.LastKeyboardDown && ControlHandler.ButtonDictionary[CButtons.Start].Keys.Length > 0) + selectStr = ControlHandler.ButtonDictionary[CButtons.Start].Keys[0].ToString(); + if (!ControlHandler.LastKeyboardDown && ControlHandler.ButtonDictionary[CButtons.Start].Buttons.Length > 0) + selectStr = ControlHandler.ButtonDictionary[CButtons.Start].Buttons[0].ToString(); + + var strType = Game1.LanguageManager.GetString((_updateInventory ? "overlay_map" : "overlay_inventory"), "error"); + var inputHelper = selectStr + ": " + strType; + + //var selectTextSize = Resources.GameFont.MeasureString(inputHelper); + spriteBatch.DrawString(Resources.GameFont, inputHelper, + new Vector2(8 * Game1.UiScale, Game1.WindowHeight - 16 * Game1.UiScale), Color.White * _fadeAnimationPercentage, 0, Vector2.Zero, Game1.UiScale, SpriteEffects.None, 0); + } + } + } + + public void DrawRenderTarget(SpriteBatch spriteBatch) + { + if (_fadeAnimationPercentage > 0 && (_currentMenuState == MenuState.GameSequence || _lastMenuState == MenuState.GameSequence)) + _gameSequences[_currentSequenceName].DrawRT(spriteBatch); + + if (_currentMenuState == MenuState.Inventory) + { + _mapOverlay.DrawRenderTarget(spriteBatch); + _inventoryOverlay.DrawRT(spriteBatch); + _dungeonOverlay.DrawOnRenderTarget(spriteBatch); + + // draw the inventory on a separate rendertarget + Game1.Graphics.GraphicsDevice.SetRenderTarget(_menuRenderTarget2D); + Game1.Graphics.GraphicsDevice.Clear(Color.Transparent); + + DrawInventory(spriteBatch); + } + } + + private void DrawInventory(SpriteBatch spriteBatch) + { + spriteBatch.Begin(SpriteSortMode.Immediate, null, SamplerState.PointClamp, null, null, null, null); + + var percentage = MathF.Sin(-MathF.PI / 2 + (_changeCount / ChangeTime) * MathF.PI) * 0.5f + 0.5f; + + // draw the inventory + _inventoryOverlay.Draw(spriteBatch, _recInventory, Color.White * (1 - percentage)); + + spriteBatch.End(); + + // draw the map + var mapRectangle = new Rectangle( + (int)MathHelper.Lerp(_recMap.X, _recMapCenter.X, percentage), + (int)MathHelper.Lerp(_recMap.Y, _recMapCenter.Y, percentage), _recMap.Width, _recMap.Height); + _mapOverlay.Draw(spriteBatch, mapRectangle, Color.White); + + spriteBatch.Begin(SpriteSortMode.Immediate, null, SamplerState.PointClamp); + + // draw the dungeon stuff + _dungeonOverlay.Draw(spriteBatch, _recDungeon, Color.White * (1 - percentage)); + + spriteBatch.End(); + } + + public void ResolutionChanged() + { + TextboxOverlay.ResolutionChange(); + + _blurRectangle.Rectangle.Width = Game1.WindowWidth; + _blurRectangle.Rectangle.Height = Game1.WindowHeight; + + _scale = Game1.UiScale; + + _overlayWidth = _overlaySize.X * _scale; + _overlayHeight = _overlaySize.Y * _scale; + + _menuPosition = new Vector2( + Game1.WindowWidth / 2 - _overlayWidth / 2, Game1.WindowHeight / 2 - _overlayHeight / 2); + } + + public void UpdateRenderTarget() + { + if (_menuRenderTarget2D == null || _menuRenderTarget2D.Width != _overlayWidth || _menuRenderTarget2D.Height != _overlayHeight) + _menuRenderTarget2D = new RenderTarget2D(Game1.Graphics.GraphicsDevice, _overlayWidth, _overlayHeight); + + _inventoryOverlay.UpdateRenderTarget(); + + _mapOverlay.UpdateRenderTarget(); + + _dungeonOverlay.UpdateRenderTarget(); + + // 144 = size of the map + _recInventory = new Rectangle(0, 0, _inventorySize.X * _scale, _inventorySize.Y * _scale); + + _recMap = new Rectangle( + _recInventory.Right - 6 * _scale - _mapSize.X * _scale, + _recInventory.Bottom - 6 * _scale - _mapSize.Y * _scale, _mapSize.X * _scale, _mapSize.Y * _scale); + + _recMapCenter = new Rectangle( + _recInventory.Width / 2 - _mapSize.X / 2 * _scale, + _recInventory.Height / 2 - _mapSize.Y / 2 * _scale, _mapSize.X * _scale, _mapSize.Y * _scale); + + _recDungeon = new Rectangle( + _recInventory.Right + _margin * _scale, + _recInventory.Bottom - _dungeonSize.Y * _scale, + _dungeonSize.X * _scale, _dungeonSize.Y * _scale); + } + + public void OpenPhotoOverlay() + { + _photoOverlay.OnOpen(); + SetState(MenuState.PhotoBook); + } + + public void StartSequence(string name) + { + if (!_gameSequences.ContainsKey(name)) + return; + + _currentSequenceName = name; + _gameSequences[_currentSequenceName].OnStart(); + SetState(MenuState.GameSequence); + } + + public GameSequence GetCurrentGameSequence() + { + if (_currentSequenceName != null && _gameSequences.ContainsKey(_currentSequenceName)) + return _gameSequences[_currentSequenceName]; + + return null; + } + + public void ToggleInventoryMap() + { + _isChanging = true; + } + + public bool UpdateCameraAndAnimation() + { + return (_currentMenuState != MenuState.Inventory && TextboxOverlay.IsOpen) || _currentMenuState == MenuState.GameSequence; + } + + public void HideHud(bool hidden) + { + _hideHud = hidden; + } + + private void UpdateFade() + { + // update the fading effect + if (_fading) + { + _fadeCount += Game1.DeltaTime * _fadeDir; + + // finished closing/opening + if (_fadeCount <= 0 || _fadeCount >= _fadeTime) + { + _fading = false; + _fadeCount = MathHelper.Clamp((float)_fadeCount, 0, _fadeTime); + } + } + + var fadePercentage = (float)_fadeCount / _fadeTime; + _fadeAnimationPercentage = (float)Math.Sin(Math.PI / 2 * fadePercentage); + _blurRectangle.BackgroundColor = Color.Black * 0.5f * _fadeAnimationPercentage; + _blurRectangle.BlurColor = Values.GameMenuBackgroundColor * _fadeAnimationPercentage; + + if (_fadeAnimationPercentage <= 0 && _currentSequenceName != null && _currentMenuState == MenuState.None) + _currentSequenceName = null; + + // hide the hud + if (TextboxOverlay.IsOpen || _currentMenuState != MenuState.None || _hideHud) + { + _hudState = AnimationHelper.MoveToTarget(_hudState, 1, 0.1f * Game1.TimeMultiplier); + } + else if (!Game1.GameManager.DialogIsRunning() && (Game1.UpdateGame || Game1.ForceDialogUpdate)) + { + _hudState = AnimationHelper.MoveToTarget(_hudState, 0, 0.1f * Game1.TimeMultiplier); + } + + _hudPercentage = (float)Math.Sin(Math.PI / 2 * _hudState); + } + + private void ToggleState(MenuState newState) + { + if (_currentMenuState == MenuState.None) + SetState(newState); + else + CloseOverlay(); + } + + private void SetState(MenuState newState) + { + // don't change the state if a textbox is open + if (TextboxOverlay.IsOpen || DisableOverlayToggle) + return; + + // pause the currently playing soundeffects + if (newState == MenuState.Inventory || newState == MenuState.Menu) + Game1.GameManager.PauseSoundEffects(); + + if (newState == MenuState.Inventory || newState == MenuState.Menu) + Game1.GameManager.PlaySoundEffect("D360-17-11"); + + if (newState == MenuState.Inventory) + { + _isChanging = false; + _changeCount = 0; + _updateInventory = true; + + _mapOverlay.OnFocus(); + _dungeonOverlay.OnFocus(); + } + else if (newState == MenuState.Menu) + { + // don't open the menu while closing it + Game1.UiPageManager.ChangePage(typeof(GameMenuPage), null, PageManager.TransitionAnimation.TopToBottom, PageManager.TransitionAnimation.TopToBottom); + } + + _fading = true; + _fadeDir = 1; + _lastMenuState = _currentMenuState; + _currentMenuState = newState; + } + + public void CloseOverlay() + { + if (_currentMenuState == MenuState.Inventory || _currentMenuState == MenuState.Menu) + Game1.GameManager.PlaySoundEffect("D360-18-12"); + + _fading = true; + _fadeDir = -1; + _lastMenuState = _currentMenuState; + _currentMenuState = MenuState.None; + + InputHandler.ResetInputState(); + Game1.UiPageManager.PopAllPages(PageManager.TransitionAnimation.TopToBottom, PageManager.TransitionAnimation.TopToBottom); + + Game1.GameManager.ContinueSoundEffects(); + } + + public bool MenuIsOpen() + { + return _currentMenuState == MenuState.Menu; + } + } +} diff --git a/InGame/Overlay/PhotoOverlay.cs b/InGame/Overlay/PhotoOverlay.cs new file mode 100644 index 0000000..8170fd9 --- /dev/null +++ b/InGame/Overlay/PhotoOverlay.cs @@ -0,0 +1,200 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Overlay +{ + // TODO: add button hints and maybe dialog box with the original text? + class PhotoOverlay + { + private DictAtlasEntry _spriteBook; + private DictAtlasEntry _spriteCursor; + private DictAtlasEntry _spriteNop; + private DictAtlasEntry _spriteOk; + + private DictAtlasEntry[] _spritePhotos = new DictAtlasEntry[12]; + private bool[] _unlockState = new bool[12]; + + private int _cursorIndex; + + private float _transitionValue; + private float _transitionCounter; + private const float TransitionTimeOpen = 125; + private const float TransitionTimeClose = 125; + private bool _isShowingImage; + + private float _cursorState; + private float _cursorCounter; + private float _cursorTime = 200f; + private bool _cursorPressed; + + public void Load() + { + _spriteBook = Resources.GetSprite("photo_book"); + _spriteCursor = Resources.GetSprite("photo_cursor"); + _spriteNop = Resources.GetSprite("photo_no"); + _spriteOk = Resources.GetSprite("photo_ok"); + + for (var i = 0; i < 12; i++) + _spritePhotos[i] = Resources.GetSprite("photo_" + (i + 1)); + } + + public void OnOpen() + { + // check the state of the discovered photos + _isShowingImage = false; + _transitionCounter = 0; + _transitionValue = 0; + + for (var i = 0; i < 12; i++) + _unlockState[i] = !string.IsNullOrEmpty(Game1.GameManager.SaveManager.GetString("photo_" + (i + 1))); + + // set to alt image or not? + var altPhoto = Game1.GameManager.SaveManager.GetString("photo_1_alt"); + var useAltPhoto = !string.IsNullOrEmpty(altPhoto); + _spritePhotos[0] = Resources.GetSprite(useAltPhoto ? "photo_1_alt" : "photo_1"); + } + + public void Update() + { + // convert the index into a 2d position + var cursorPoint = CursorPosition(_cursorIndex); + + if (!_isShowingImage) + { + if (ControlHandler.ButtonPressed(CButtons.A)) + { + _cursorPressed = true; + + // very important if the player is spamming the a button to have a nice animation + if (_cursorCounter > _cursorTime / 2) + _cursorCounter = _cursorTime - _cursorCounter; + + if (_unlockState[_cursorIndex]) + _isShowingImage = true; + } + else + { + if (ControlHandler.ButtonPressed(CButtons.Left)) + cursorPoint.X--; + if (ControlHandler.ButtonPressed(CButtons.Right)) + cursorPoint.X++; + if (ControlHandler.ButtonPressed(CButtons.Up)) + cursorPoint.Y--; + if (ControlHandler.ButtonPressed(CButtons.Down)) + cursorPoint.Y++; + + if (cursorPoint.X < 0) + cursorPoint.X += 4; + if (cursorPoint.X > 3) + cursorPoint.X -= 4; + if (cursorPoint.Y < 0) + cursorPoint.Y += 3; + if (cursorPoint.Y > 2) + cursorPoint.Y -= 3; + } + + // close the page + if (ControlHandler.ButtonPressed(CButtons.B)) + Game1.GameManager.InGameOverlay.CloseOverlay(); + } + else + { + if (ControlHandler.ButtonPressed(CButtons.B)) + { + _isShowingImage = false; + _transitionCounter = TransitionTimeClose; + } + } + + if (_isShowingImage && _transitionCounter < TransitionTimeOpen) + { + _transitionCounter += Game1.DeltaTime; + if (_transitionCounter > TransitionTimeOpen) + _transitionCounter = TransitionTimeOpen; + + _transitionValue = Math.Clamp(_transitionCounter / TransitionTimeOpen, 0, 1); + } + else if (!_isShowingImage && _transitionCounter > 0) + { + _transitionCounter -= Game1.DeltaTime; + if (_transitionCounter < 0) + _transitionCounter = 0; + + _transitionValue = _transitionCounter / TransitionTimeClose; + _cursorState = MathF.Sin(_transitionValue * MathF.PI * 0.5f); + } + + // cursor animation + if (_cursorPressed) + { + _cursorCounter += Game1.DeltaTime; + if (_cursorCounter >= _cursorTime) + { + _cursorCounter = 0; + _cursorPressed = false; + } + + _cursorState = MathF.Sin(_cursorCounter / _cursorTime * MathF.PI); + } + + // converts back into index space + _cursorIndex = CursorIndex(cursorPoint); + + } + + private Point CursorPosition(int index) + { + return new Point(index % 2 + (index / 6) * 2, (index % 6) / 2); + } + + private int CursorIndex(Point position) + { + return position.X % 2 + position.X / 2 * 6 + position.Y * 2; + } + + public void Draw(SpriteBatch spriteBatch, float transparency) + { + // draw the book + var bookPosition = new Vector2( + Game1.WindowWidth / 2 - (_spriteBook.SourceRectangle.Width * Game1.UiScale) / 2, + Game1.WindowHeight / 2 - (_spriteBook.SourceRectangle.Height * Game1.UiScale) / 2); + spriteBatch.Draw(_spriteBook.Texture, bookPosition, _spriteBook.SourceRectangle, + Color.White * transparency, 0, Vector2.Zero, new Vector2(Game1.UiScale), SpriteEffects.None, 0); + + // draw the images + for (var i = 0; i < 12; i++) + { + var imageSprite = _unlockState[i] ? _spriteOk : _spriteNop; + var position = bookPosition + + new Vector2(27 + (i % 2) * 32 + (i / 6) * 88, 19 + ((i % 6) / 2) * 32) * Game1.UiScale - + new Vector2(imageSprite.SourceRectangle.Width / 2, 0) * Game1.UiScale; + spriteBatch.Draw(imageSprite.Texture, position, imageSprite.SourceRectangle, + Color.White * transparency, 0, Vector2.Zero, new Vector2(Game1.UiScale), SpriteEffects.None, 0); + } + + // draw the cursor + var cursorPosition = bookPosition + + new Vector2(12 + (_cursorIndex % 2) * 32 + (_cursorIndex / 6) * 88, 8 + ((_cursorIndex % 6) / 2) * 32) * Game1.UiScale + + new Vector2(21, 21) * Game1.UiScale - + new Vector2(2, 2) * Game1.UiScale * _cursorState; + spriteBatch.Draw(_spriteCursor.Texture, cursorPosition, _spriteCursor.SourceRectangle, + Color.White * transparency, 0, Vector2.Zero, new Vector2(Game1.UiScale), SpriteEffects.None, 0); + + // draw the selected image + if (_transitionValue != 0) + { + var pictureStartPosition = bookPosition + new Vector2(27 + (_cursorIndex % 2) * 32 + (_cursorIndex / 6) * 88, 27 + ((_cursorIndex % 6) / 2) * 32) * Game1.UiScale; + var picturePosition = Vector2.Lerp(pictureStartPosition, new Vector2(Game1.WindowWidth / 2, Game1.WindowHeight / 2), _transitionValue); + + spriteBatch.Draw(_spritePhotos[_cursorIndex].Texture, picturePosition, _spritePhotos[_cursorIndex].SourceRectangle, + Color.White * transparency * _transitionValue, 0, + new Vector2(_spritePhotos[_cursorIndex].SourceRectangle.Width / 2, _spritePhotos[_cursorIndex].SourceRectangle.Height / 2f), + new Vector2(Game1.UiScale * (0.1f + _transitionValue * 0.9f)), SpriteEffects.None, 0); + } + } + } +} diff --git a/InGame/Overlay/Sequences/BowWowSequence.cs b/InGame/Overlay/Sequences/BowWowSequence.cs new file mode 100644 index 0000000..baf89d1 --- /dev/null +++ b/InGame/Overlay/Sequences/BowWowSequence.cs @@ -0,0 +1,330 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.Overlay.Sequences +{ + class BowWowSequence : GameSequence + { + private SeqAnimation _aniLink; + private SeqAnimation _aniBowWow; + private SeqSprite _spriteParticle; + private SeqSprite _spriteSmoke0; + private SeqSprite _spriteSmoke1; + + private SeqSprite _spritePhoto; + + private SeqColor _spritePhotoFlash; + private float _flashPercentage = 0; + + private Vector2 _bowWowVelocity; + private int _bowWowDirection; + + private Vector2 _chainStartPosition; + private float _linkVelocity; + + private SeqSprite[] _chain = new SeqSprite[5]; + + private bool _isWalking; + private bool _blocked; + private bool _ending; + private bool _showPicture; + private bool _attack; + + private int _blockCount; + + private float _bowWowAttackPosition; + + private double _counter; + private int _sequenceIndex; + + private double _particleCounter; + + public BowWowSequence() + { + _sequenceWidth = 160; + _sequenceHeight = 144; + } + + public override void OnStart() + { + Sprites.Clear(); + SpriteDict.Clear(); + + var position = Vector2.Zero; + + _isWalking = false; + _blocked = false; + _ending = false; + _attack = false; + _showPicture = false; + + _blockCount = 0; + _linkVelocity = 0; + _particleCounter = 0; + + _counter = 0; + _sequenceIndex = 0; + + _flashPercentage = 0; + + // background + Sprites.Add(new SeqSprite("bowWow_background", position, 0)); + Sprites.Add(_spritePhoto = new SeqSprite("photo_6", position, 5) { Color = Color.Transparent }); + + _chainStartPosition = new Vector2(position.X + 90, position.Y + 103 - 6); + for (var i = 0; i < _chain.Length; i++) + Sprites.Add(_chain[i] = new SeqSprite("seqBowWowChain", _chainStartPosition, 1) { Color = Color.White * 0.75f }); + + // link and marin + Sprites.Add(_aniLink = new SeqAnimation("Sequences/bowWow link", "stand", new Vector2(position.X + 134, position.Y + 104), 3) { Shader = Resources.ColorShader, Color = Game1.GameManager.CloakColor }); + Sprites.Add(_aniBowWow = new SeqAnimation("Sequences/bowWow", "idle_-1", new Vector2(position.X + 95, position.Y + 103), 2)); + + // block particle + Sprites.Add(_spriteParticle = new SeqSprite("seqBowWowParticle", _chainStartPosition, 4) { Color = Color.Transparent }); + Sprites.Add(_spriteSmoke0 = new SeqSprite("seqBowWowSmoke", _chainStartPosition, 4) { Color = Color.Transparent }); + Sprites.Add(_spriteSmoke1 = new SeqSprite("seqBowWowSmoke", _chainStartPosition, 4) { Color = Color.Transparent, SpriteEffect = SpriteEffects.FlipHorizontally }); + + Sprites.Add(_spritePhotoFlash = new SeqColor(new Rectangle((int)position.X, (int)position.Y, 160, 144), Color.Transparent, 5)); + + // start the sequence path + Game1.GameManager.StartDialogPath("photo_sequence_3"); + + _bowWowDirection = -1; + _bowWowVelocity.X = 0.75f * _bowWowDirection; + + base.OnStart(); + } + + public override void Update() + { + if (_flashPercentage > 0 && _counter > 125) + _flashPercentage = AnimationHelper.MoveToTarget(_flashPercentage, 0, Game1.TimeMultiplier * 0.075f); + _spritePhotoFlash.Color = Color.White * _flashPercentage; + + // do not update the sceen while the dialog box is open + if (Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen) + return; + + if (_showPicture) + { + _counter += Game1.DeltaTime; + if (_counter > 2500) + Game1.GameManager.InGameOverlay.CloseOverlay(); + + return; + } + + base.Update(); + + _counter += Game1.DeltaTime; + if (_sequenceIndex == 0 && _counter > 1000) + { + _sequenceIndex = 1; + _counter -= 1000; + Game1.GameManager.StartDialogPath("photo_sequence_3"); + } + else if (_sequenceIndex == 1 && _counter > 250) + { + _sequenceIndex = 2; + _counter -= 250; + _isWalking = true; + _aniLink.Animator.Play("walk"); + } + + // draw the particle? + if (_particleCounter > 0) + _particleCounter -= Game1.DeltaTime; + _spriteParticle.Color = _particleCounter <= 0 ? Color.Transparent : Color.White; + + if (_attack) + { + if (_counter > 250) + { + _spriteSmoke0.Position = new Vector2(_aniBowWow.Position.X - 17, _aniBowWow.Position.Y - 30); + _spriteSmoke1.Position = new Vector2(_aniBowWow.Position.X + 17, _aniBowWow.Position.Y - 30); + } + if (_counter > 500) + { + _flashPercentage = 1; + _spritePhotoFlash.Color = Color.White * _flashPercentage; + Game1.GameManager.PlaySoundEffect("D378-63-40"); + + _showPicture = true; + _spritePhoto.Color = Color.White; + _counter = 0; + } + + return; + } + + if (_ending) + { + if (_counter > 1500) + _aniLink.Animator.Play("piece"); + else if (_counter > 500) + _aniLink.Animator.Play("stand"); + + // move BowWow up + if (_counter > 2500) + { + // move up + _aniBowWow.Position.X = _bowWowAttackPosition + MathF.Sin(((float)_counter - 2500) / 75); + _aniBowWow.Position.Y -= 0.25f * Game1.TimeMultiplier; + + if (_aniBowWow.Animator.CurrentAnimation.Id != "pre_attack") + _aniBowWow.Animator.Play("pre_attack"); + else if (!_aniBowWow.Animator.IsPlaying) + { + _attack = true; + _counter = 0; + _aniBowWow.Animator.Play("attack"); + _spriteSmoke0.Color = Color.White; + _spriteSmoke0.Position = new Vector2(_aniBowWow.Position.X - 15, _aniBowWow.Position.Y - 28); + _spriteSmoke1.Color = Color.White; + _spriteSmoke1.Position = new Vector2(_aniBowWow.Position.X + 15, _aniBowWow.Position.Y - 28); + } + } + else + { + _bowWowAttackPosition = _aniBowWow.Position.X; + } + + return; + } + + // BowWow movement (do not move after getting blocked and falling on the floor) + _aniBowWow.Position += _bowWowVelocity * Game1.TimeMultiplier; + _bowWowVelocity.Y += 0.15f * Game1.TimeMultiplier; + + // BowWow jump + if (_aniBowWow.Position.Y > 103) + { + _bowWowVelocity.X = 0; + _aniBowWow.Position.Y = 103; + + if (_blockCount < 3) + { + if (!_blocked) + { + _bowWowVelocity.X = 0.75f * _bowWowDirection; + + if (Game1.RandomNumber.Next(0, 3) == 0) + _bowWowVelocity.Y = -1.75f; + else + _bowWowVelocity.Y = -1.0f; + } + else if (_aniBowWow.Animator.CurrentAnimation.Id != "open_-1") + { + // open the mouth after landing after a block + _aniBowWow.Animator.Play("open_-1"); + } + } + else + { + _ending = true; + } + } + + // update link walking towards BowWow + if (_isWalking) + { + if (!_blocked && _blockCount < 3) + { + _aniLink.Animator.Play("walk"); + _aniLink.Position.X -= 0.125f * Game1.TimeMultiplier; + } + else + _aniLink.Position.X += _linkVelocity * Game1.TimeMultiplier; + + _linkVelocity = AnimationHelper.MoveToTarget(_linkVelocity, 0, 0.065f * Game1.TimeMultiplier); + + if (_blocked && _aniBowWow.Position.Y == 103 && !_aniBowWow.Animator.IsPlaying && _blockCount <= 3) + { + _blocked = false; + Game1.GameManager.StartDialogPath("photo_sequence_3"); + } + + // collision with BowWow + if (_aniBowWow.Position.X + 12 > _aniLink.Position.X) + { + if (_blockCount < 3) + { + _blockCount++; + + Game1.GameManager.PlaySoundEffect("D360-07-07"); + + // show block particle + _particleCounter = 175; + _spriteParticle.Position = new Vector2(_aniLink.Position.X - 12, _aniLink.Position.Y - 14); + + _aniBowWow.Animator.Play("idle_-1"); + if (_blockCount < 3) + { + _bowWowVelocity.X = -_bowWowVelocity.X; + _bowWowVelocity.Y = -1; + _bowWowDirection = -_bowWowDirection; + } + else if (!_blocked) + { + _counter = 0; + _bowWowVelocity.Y = -1; + } + + _blocked = true; + _aniLink.Animator.Play("blocked"); + _linkVelocity += 1; + } + } + } + + if (_aniBowWow.Position.X < 56 && _bowWowDirection < 0) + { + _bowWowVelocity.X = -_bowWowVelocity.X; + _bowWowDirection = -_bowWowDirection; + _aniBowWow.Animator.Play("idle_1"); + } + else if (_aniBowWow.Position.X > 118 && _bowWowDirection > 0) + { + _bowWowVelocity.X = -_bowWowVelocity.X; + _bowWowDirection = -_bowWowDirection; + _aniBowWow.Animator.Play("idle_-1"); + } + + // update the chain position + for (var i = 0; i < _chain.Length; i++) + { + if (_chain[i].Position.Y < _chainStartPosition.Y) + _chain[i].Position.Y += 0.25f * Game1.TimeMultiplier; + + if (_chain[i].Position.Y > _chainStartPosition.Y) + _chain[i].Position.Y = _chainStartPosition.Y; + } + + var lastPosition = new Vector2(_aniBowWow.Position.X + _bowWowDirection * 4, _aniBowWow.Position.Y - 8); + for (var i = _chain.Length - 1; i > 0; i--) + { + var direction = _chain[i].Position - lastPosition; + if (direction.Length() > 8) + { + direction.Normalize(); + _chain[i].Position = lastPosition + direction * 8; + } + lastPosition = _chain[i].Position; + } + + lastPosition = _chainStartPosition; + for (var i = 0; i < _chain.Length; i++) + { + var direction = _chain[i].Position - lastPosition; + if (direction.Length() > 8) + { + direction.Normalize(); + _chain[i].Position = lastPosition + direction * 8; + } + lastPosition = _chain[i].Position; + } + } + } +} diff --git a/InGame/Overlay/Sequences/CastleSequence.cs b/InGame/Overlay/Sequences/CastleSequence.cs new file mode 100644 index 0000000..4e44c08 --- /dev/null +++ b/InGame/Overlay/Sequences/CastleSequence.cs @@ -0,0 +1,36 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Overlay.Sequences +{ + class CastleSequence : GameSequence + { + public CastleSequence() + { + _sequenceWidth = 160; + _sequenceHeight = 144; + } + + public override void OnStart() + { + Sprites.Clear(); + SpriteDict.Clear(); + + var position = Vector2.Zero; + + // background + Sprites.Add(new SeqSprite("seqCastleBackground", position, 0)); + + // characters + AddDrawable("castleLink", new SeqAnimation("Sequences/link castle", "stand", new Vector2(position.X - 24, position.Y + 155), 1) { Shader = Resources.ColorShader, Color = Game1.GameManager.CloakColor }); + AddDrawable("castleMouse", new SeqAnimation("NPCs/photo_mouse", "stand_0", new Vector2(position.X + 91, position.Y + 119), 1)); + AddDrawable("castleBoy", new SeqAnimation("Sequences/castle frog boy", "walk", new Vector2(position.X + 176, position.Y + 145), 2)); + AddDrawable("castleFlash", new SeqColor(new Rectangle((int)position.X, (int)position.Y, 160, 144), Color.Transparent, 3)); + + // start the sequence path + Game1.GameManager.StartDialogPath("castle_sequence"); + + base.OnStart(); + } + } +} diff --git a/InGame/Overlay/Sequences/FinalSequence.cs b/InGame/Overlay/Sequences/FinalSequence.cs new file mode 100644 index 0000000..fdcc3df --- /dev/null +++ b/InGame/Overlay/Sequences/FinalSequence.cs @@ -0,0 +1,818 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.Overlay.Sequences +{ + class FinalSequence : GameSequence + { + private int _screenIndex; + + private float _screenFadeCounter; + private float _screenFadeWaitCounter; + private float ScreenFadeTime = 250; + private float ScreenFadeTimeWait = 500; + + // screen 0 (island) + private float _screen0Counter; + private bool _playedIslandSound; + + // screen 1 + private SeqAnimation _s1Seagull0; + private SeqAnimation _s1Seagull1; + + private float _screen1Counter; + private float _fadeCounter; + private float _segullSoundCounter; + private float _waveSoundCounter = 5000; + private const int FadeTime = 1600; + + private SeqColor _screen1FadeColor; + + // screen 2 + private SeqAnimation _s2Link; + private SeqSprite _s2Log0; + private SeqSprite _s2Log1; + + private float _s2LinkPosY; + private float _s2Log0PosY; + private float _s2Log1PosY; + + private float _screen2Counter; + + // screen 3 + private SeqAnimation _s3Link; + private SeqAnimation _s3Shadow; + private SeqAnimation _s3Seagull; + + private SeqSprite _s3Log; + private SeqSprite _s3Barrel0; + private SeqSprite _s3Barrel1; + + private float _screen3Counter; + + private float _s3LogPosY; + private float _s3Barrel0PosY; + private float _s3Barrel1PosY; + + private float _s3LinkPosY; + + private bool _s3LinkAwoken; + + // screen 4 + private SeqAnimation _s4Link; + + private SeqAnimation[] _s4Water = new SeqAnimation[24]; + private SeqSprite _s4Background; + private SeqSprite _s4Wale; + + private SeqSprite _s4Sun0; + private SeqSprite _s4Sun1; + private SeqSprite _s4Sun2; + + private float _screen4Counter; + private float _s4CameraPosition; + private float _s4LinkPosY; + private float _s4Brightness; + + private bool _playedWaleSound0; + private bool _playedWaleSound1; + private bool _s4MoveCamera; + private bool _s4LookedUp; + + // screen 5 + private SeqAnimation _s5Link; + private SeqSprite _s5Background; + + private float _screen5Counter; + private bool _screen5Smile; + + // screen 6 + private SeqAnimation _s6Link; + private SeqAnimation _s6Wale; + + private SeqSprite _s6Marin; + private float _s6MarinTransparency; + + private float _screen6Counter; + + private float _s6LinkPosition; + private float _s6CameraPosition; + + private float _creditCounter; + + private int _creditsHeaderIndex; + private int _creditsContentIndex; + + private bool _finishedCredits; + private bool _marinEnding; + private bool _marinEndingTriggered; + + private string _creditsHeader; + private string _creditsContent; + + public FinalSequence() + { + _useUiScale = false; + _textBoxOffset = false; + + // 16/9 + _sequenceWidth = 360; + _sequenceHeight = 180; + } + + public override void OnStart() + { + var finalState = Game1.GameManager.SaveManager.GetString("final_state"); + + if (!string.IsNullOrEmpty(finalState) && finalState == "1") + InitScreen1(); + else + InitScreen0(); + + base.OnStart(); + } + + private void InitScreen0() + { + Sprites.Clear(); + SpriteDict.Clear(); + _cameraPosition = Vector2.Zero; + + _screenIndex = 0; + _screen0Counter = 0; + _playedIslandSound = false; + + var position = new Vector2(_sequenceWidth / 2 - 80, _sequenceHeight / 2 + 144 / 2 - 128); + + // background + Sprites.Add(new SeqColor(new Rectangle(0, 0, _sequenceWidth, (int)position.Y + 80), new Color(122, 156, 253), 1)); + Sprites.Add(new SeqColor(new Rectangle(0, (int)position.Y + 80, _sequenceWidth, _sequenceHeight - (int)position.Y - 80), new Color(24, 33, 154), 1)); + + Sprites.Add(new SeqSprite("final_island_background", position, 2)); + Sprites.Add(new SeqSprite("final_island", new Vector2(position.X + 8, position.Y + 16), 3) { Shader = Resources.ThanosSpriteShader1 }); + + for (int i = 0; i < 8; i++) + { + Sprites.Add(new SeqAnimation("Sequences/water", "idle", new Vector2(position.X - 16 * i, position.Y + 80), 3)); + Sprites.Add(new SeqAnimation("Sequences/water", "idle", new Vector2(position.X + 144 + 16 * i, position.Y + 80), 3)); + } + } + + private void InitScreen1() + { + Sprites.Clear(); + SpriteDict.Clear(); + _cameraPosition = Vector2.Zero; + + _screenIndex = 1; + _screen1Counter = 0; + + var position = Vector2.Zero; + var screenPosition = new Vector2(_sequenceWidth / 2 - 80, _sequenceHeight / 2 - 144 / 2); + + // background + Sprites.Add(new SeqSprite("final_sky", position, 0)); + + Sprites.Add(_screen1FadeColor = new SeqColor(new Rectangle(0, 0, _sequenceWidth, _sequenceHeight), Color.White, 2)); + + Sprites.Add(_s1Seagull0 = new SeqAnimation("Sequences/seagull final", "fly_1", new Vector2(screenPosition.X + 16, screenPosition.Y + 8), 1)); + Sprites.Add(_s1Seagull1 = new SeqAnimation("Sequences/seagull final", "fly_-1", new Vector2(screenPosition.X + 128, screenPosition.Y + 104), 1)); + + _s1Seagull0.Animator.SetFrame(Game1.RandomNumber.Next(1, 4)); + _s1Seagull0.Animator.SetTime(Game1.RandomNumber.Next(0, 500)); + _s1Seagull1.Animator.SetTime(Game1.RandomNumber.Next(0, 500)); + + _fadeCounter = FadeTime; + } + + private void InitScreen2() + { + Sprites.Clear(); + SpriteDict.Clear(); + _cameraPosition = Vector2.Zero; + + _screenIndex = 2; + _screen2Counter = 0; + + var position = new Vector2(_sequenceWidth / 2 - 80, _sequenceHeight / 2 - 144 / 2 + 8); + + // background + Sprites.Add(new SeqColor(new Rectangle(0, 0, _sequenceWidth, (int)position.Y + 56), new Color(66, 89, 254), 0)); + Sprites.Add(new SeqColor(new Rectangle(0, (int)position.Y + 56, _sequenceWidth, _sequenceHeight - (int)position.Y - 56), new Color(24, 33, 154), 0)); + + // background + Sprites.Add(new SeqSprite("final_lay", new Vector2(0, position.Y), 1)); + + for (int i = 0; i < 24; i++) + Sprites.Add(new SeqAnimation("Sequences/water", "idle", new Vector2(position.X + 16 * (i - 7), position.Y + 48), 2)); + + _s2LinkPosY = position.Y + 82; + Sprites.Add(_s2Link = new SeqAnimation("Sequences/link final", "idle", new Vector2(position.X + 64, _s2LinkPosY), 1)); + + _s2Log0PosY = position.Y + 90; + Sprites.Add(_s2Log0 = new SeqSprite("final_log", new Vector2(position.X + 32, _s2Log0PosY), 1)); + _s2Log1PosY = position.Y + 80; + Sprites.Add(_s2Log1 = new SeqSprite("final_log", new Vector2(position.X + 112, _s2Log1PosY), 1)); + } + + private void InitScreen3() + { + Sprites.Clear(); + SpriteDict.Clear(); + _cameraPosition = Vector2.Zero; + + Game1.GameManager.SetMusic(60, 2); + + _screenIndex = 3; + _screen3Counter = 0; + _s3LinkAwoken = false; + + var position = new Vector2(_sequenceWidth / 2 - 80, _sequenceHeight / 2 - 144 / 2); + + // background + Sprites.Add(new SeqColor(new Rectangle(0, 0, _sequenceWidth, (int)position.Y + 56), new Color(66, 89, 254), 0)); + Sprites.Add(new SeqColor(new Rectangle(0, (int)position.Y + 56, _sequenceWidth, _sequenceHeight - (int)position.Y - 56), new Color(24, 33, 154), 0)); + + // background + Sprites.Add(new SeqSprite("final_sky_1", new Vector2(0, position.Y), 1)); + + for (int i = 0; i < 24; i++) + Sprites.Add(new SeqAnimation("Sequences/water", "idle", new Vector2(position.X + 16 * (i - 7), position.Y + 48), 1)); + + _s3LinkPosY = position.Y + 130; + Sprites.Add(_s3Shadow = new SeqAnimation("Sequences/link awake", "shadow", new Vector2(position.X + 16, _s3LinkPosY), 2)); + Sprites.Add(_s3Link = new SeqAnimation("Sequences/link awake", "sleep", new Vector2(position.X + 16, _s3LinkPosY), 2)); + + Sprites.Add(_s3Seagull = new SeqAnimation("Sequences/seagull big final", "idle", new Vector2(position.X + 16, position.Y + 72), 2)); + + _s3LogPosY = position.Y + 72; + Sprites.Add(_s3Log = new SeqSprite("final_log_2", new Vector2(position.X + 16, _s3LogPosY), 1)); + _s3Barrel0PosY = position.Y + 70; + Sprites.Add(_s3Barrel0 = new SeqSprite("final_barrel", new Vector2(position.X + 116, _s3Barrel0PosY), 1) { SpriteEffect = SpriteEffects.FlipHorizontally }); + _s3Barrel1PosY = position.Y + 78; + Sprites.Add(_s3Barrel1 = new SeqSprite("final_barrel", new Vector2(position.X + 148, _s3Barrel1PosY), 1)); + } + + private void InitScreen4() + { + Sprites.Clear(); + SpriteDict.Clear(); + _cameraPosition = Vector2.Zero; + + _screenIndex = 4; + _screen4Counter = 0; + _s4CameraPosition = 720; + _s4Brightness = 255; + _s4MoveCamera = false; + _s4LookedUp = false; + + var position = new Vector2(_sequenceWidth / 2 - 80, _sequenceHeight / 2 - 144 / 2); + + // background + Sprites.Add(_s4Background = new SeqSprite("final_sky", Vector2.Zero, 0)); + + var sunPosition = new Vector2(position.X + 64, position.Y + 48); + Sprites.Add(new SeqSprite("sun", sunPosition, 1)); + Sprites.Add(_s4Sun0 = new SeqSprite("sun_0", new Vector2(sunPosition.X + 29, sunPosition.Y + 29), 1) { Color = Color.Transparent }); + Sprites.Add(_s4Sun1 = new SeqSprite("sun_1", new Vector2(sunPosition.X + 34, sunPosition.Y + 34), 2) { Color = Color.Transparent }); + Sprites.Add(_s4Sun2 = new SeqSprite("sun_2", new Vector2(sunPosition.X + 38, sunPosition.Y + 38), 3) { Color = Color.Transparent }); + + Sprites.Add(_s4Link = new SeqAnimation("Sequences/link awake", "sit", new Vector2(position.X + 56, _s4LinkPosY = position.Y + 16 * 49 + 4), 2)); + + Sprites.Add(_s4Wale = new SeqSprite("wale_sky", new Vector2(position.X + 80, position.Y + 56), 2) { RoundPosition = true }); + + // animated water + for (int i = 0; i < _s4Water.Length; i++) + Sprites.Add(_s4Water[i] = new SeqAnimation("Sequences/water", "idle", new Vector2(position.X + 16 * (i - 7), position.Y + 16 * 50), 1)); + } + + private void InitScreen5() + { + Sprites.Clear(); + SpriteDict.Clear(); + _cameraPosition = Vector2.Zero; + + _screenIndex = 5; + + _screen5Counter = 0; + _screen5Smile = false; + + var position = new Vector2(_sequenceWidth / 2 - 80, _sequenceHeight / 2 - 144 / 2); + + Sprites.Add(_s5Link = new SeqAnimation("Sequences/link awake", "pre_smile", new Vector2(position.X + 48, position.Y + 64 + 18), 2)); + var brighness = 100; + _s5Link.Color = new Color(brighness, brighness, brighness); + + // background + Sprites.Add(_s5Background = new SeqSprite("final_sky_2", Vector2.Zero, 0)); + } + + private void InitScreen6() + { + Sprites.Clear(); + SpriteDict.Clear(); + _cameraPosition = Vector2.Zero; + + _marinEndingTriggered = false; + _s6MarinTransparency = 0; + _marinEnding = Game1.GameManager.DeathCount == 0; + + _finishedCredits = false; + _creditCounter = -2500; + _creditsHeaderIndex = -1; + _creditsContentIndex = 0; + + _screenIndex = 6; + _s6CameraPosition = 144; + + _screen6Counter = 0; + + _creditsHeader = null; + _creditsContent = null; + + var position = new Vector2(_sequenceWidth / 2 - 80, _sequenceHeight / 2 - 144 / 2); + + // background + Sprites.Add(new SeqSprite("final_s6", Vector2.Zero, 0)); + Sprites.Add(_s6Marin = new SeqSprite("final_marin_ending", new Vector2(155, 58), 0) { Color = Color.Transparent }); + + for (int i = 0; i < 24; i++) + Sprites.Add(new SeqAnimation("Sequences/water", "idle", new Vector2(position.X + 16 * (i - 7), position.Y + 16 * 15), 1)); + + _s6LinkPosition = position.Y + 16 * 15 + 7; + Sprites.Add(_s6Link = new SeqAnimation("Sequences/link final", "sitting", new Vector2(position.X + 64, _s6LinkPosition), 2)); + Sprites.Add(_s6Wale = new SeqAnimation("Sequences/wale", "idle", new Vector2(32, 80), 2) { RoundPosition = true }); + } + + public override void Update() + { + _scale = MathHelper.Min(Game1.WindowWidth / 160, Game1.WindowHeight / 144); + + // fade out and wait in the middle + if (_screenFadeCounter > ScreenFadeTime) + { + _screenFadeCounter -= Game1.DeltaTime; + if (_screenFadeCounter <= ScreenFadeTime) + { + _screenFadeCounter = ScreenFadeTime; + _screenFadeWaitCounter = ScreenFadeTimeWait; + } + } + else if (_screenFadeCounter == ScreenFadeTime) + { + _screenFadeWaitCounter -= Game1.DeltaTime; + if (_screenFadeWaitCounter <= 0) + _screenFadeCounter -= Game1.DeltaTime; + } + else if (_screenFadeCounter > 0) + _screenFadeCounter -= Game1.DeltaTime; + else + _screenFadeCounter = 0; + + if (_screenIndex == 0) + UpdateScreen0(); + else if (_screenIndex == 1) + UpdateScreen1(); + else if (_screenIndex == 2) + UpdateScreen2(); + else if (_screenIndex == 3) + UpdateScreen3(); + else if (_screenIndex == 4) + UpdateScreen4(); + else if (_screenIndex == 5) + UpdateScreen5(); + else if (_screenIndex == 6) + UpdateScreen6(); + + base.Update(); + } + + private void UpdateScreen0() + { + // show the next screen + _screen0Counter += Game1.DeltaTime; + + if (_screen0Counter > 3000 && !_playedIslandSound) + { + _playedIslandSound = true; + Game1.GameManager.PlaySoundEffect("D378-53-35"); + } + + var percentage = MathHelper.Clamp((float)(_screen0Counter - 3000) / 3000, 0, 1); + // start slow and speed up + var sinPercentage = 1 - MathF.Sin(-MathF.PI * 0.45f + percentage * MathF.PI * 0.45f) / MathF.Sin(-MathF.PI * 0.45f); + Resources.ThanosSpriteShader1.FloatParameter["Percentage"] = sinPercentage; + + // start fade out + if (_screen0Counter > 8000 - ScreenFadeTime && _screenFadeCounter == 0) + _screenFadeCounter = ScreenFadeTime * 2; + + if (_screen0Counter > 8000) + { + Game1.GameManager.SaveManager.SetString("final_state", "1"); + Game1.GameManager.SaveManager.SetString("activate_fountain", "1"); + Game1.GameManager.InGameOverlay.CloseOverlay(); + + Game1.GameManager.StopMusic(); + + MapManager.ObjLink.InitEnding(); + } + } + + private void UpdateSeaSounds() + { + // seagull sound + _segullSoundCounter -= Game1.DeltaTime; + if (_segullSoundCounter < 0) + { + _segullSoundCounter += Game1.RandomNumber.Next(1500, 2500); + Game1.GameManager.PlaySoundEffect("D360-33-21"); + } + + _waveSoundCounter -= Game1.DeltaTime; + if (_waveSoundCounter < 0) + { + _waveSoundCounter += 3500; + Game1.GameManager.PlaySoundEffect("D378-15-0F"); + } + } + + private void UpdateScreen1() + { + UpdateSeaSounds(); + + _screen1Counter += Game1.DeltaTime; + + // start fade out + if (_screen1Counter > 10000 - ScreenFadeTime && _screenFadeCounter == 0) + _screenFadeCounter = ScreenFadeTime * 2; + + // show the next screen + if (_screen1Counter > 10000 && _screenFadeCounter <= ScreenFadeTime) + { + InitScreen2(); + return; + } + + _fadeCounter -= Game1.DeltaTime; + if (_fadeCounter < 0) + _fadeCounter = 0; + + float percentage = MathF.Sin(_fadeCounter / FadeTime); + _screen1FadeColor.Color = Color.White * percentage; + + _s1Seagull0.Position.X += 1 / 5.5f * Game1.TimeMultiplier; + _s1Seagull1.Position.X -= 1 / 5.5f * Game1.TimeMultiplier; + } + + private void UpdateScreen2() + { + UpdateSeaSounds(); + + _screen2Counter += Game1.DeltaTime; + + // start fade out + if (_screen2Counter > 10000 - ScreenFadeTime && _screenFadeCounter == 0) + _screenFadeCounter = ScreenFadeTime * 2; + + // show the next screen + if (_screen2Counter > 10000 && _screenFadeCounter <= ScreenFadeTime) + { + InitScreen3(); + return; + } + + _s2Link.Position.Y = _s2LinkPosY + MathF.Round(MathF.Sin((float)_screen2Counter / 2000 * MathF.PI * 2)); + _s2Log0.Position.Y = _s2Log0PosY + MathF.Round(0.5f + MathF.Sin((float)(_screen2Counter - 450) / 2000 * MathF.PI * 2) * 0.5f); + _s2Log1.Position.Y = _s2Log1PosY + MathF.Round(0.5f + MathF.Sin((float)(_screen2Counter + 350) / 2000 * MathF.PI * 2) * 0.5f); + } + + private void UpdateScreen3() + { + UpdateSeaSounds(); + + _screen3Counter += Game1.DeltaTime; + + if (_screen3Counter > 5000 && !_s3LinkAwoken) + { + _s3LinkAwoken = true; + _s3Link.Animator.Play("awake"); + } + + // start fade out + if (_screen3Counter > 17500 - ScreenFadeTime && _screenFadeCounter == 0) + _screenFadeCounter = ScreenFadeTime * 2; + + // show the next screen + if (_screen3Counter > 17500 && _screenFadeCounter <= ScreenFadeTime) + { + InitScreen4(); + } + + _s3Shadow.Position.Y = _s3LinkPosY + MathF.Round(MathF.Sin((float)_screen3Counter / 3300 * MathF.PI * 2) * 6); + _s3Link.Position.Y = _s3LinkPosY + MathF.Round(MathF.Sin((float)_screen3Counter / 3300 * MathF.PI * 2) * 6); + + _s3Log.Position.Y = _s3LogPosY + MathF.Round(0.5f + MathF.Sin((float)(_screen3Counter + 250) / 3300 * MathF.PI * 2) * 1.5f); + _s3Barrel0.Position.Y = _s3Barrel0PosY + MathF.Round(MathF.Sin((float)(_screen3Counter + 750 + 0) / 3300 * MathF.PI * 2) * 2); + _s3Barrel1.Position.Y = _s3Barrel1PosY + MathF.Round(MathF.Sin((float)(_screen3Counter + 750 + 200) / 3300 * MathF.PI * 2) * 2); + + _s3Seagull.Position.X += 1 / 2f * Game1.TimeMultiplier; + _s3Seagull.Position.Y -= 1 / 2.75f * Game1.TimeMultiplier; + } + + private void UpdateScreen4() + { + _screen4Counter += Game1.DeltaTime; + + // start fade out + if (_screen4Counter > 25500 - ScreenFadeTime && _screenFadeCounter == 0) + _screenFadeCounter = ScreenFadeTime * 2; + + // show the next screen + if (_screen4Counter > 25500 && _screenFadeCounter <= ScreenFadeTime) + InitScreen5(); + + // shadow + if (!_s4MoveCamera && _screen4Counter > 7500) + _s4Brightness = AnimationHelper.MoveToTarget(_s4Brightness, 155, 6f * Game1.TimeMultiplier); + + // move the camera up + if (_screen4Counter > 10500) + _s4MoveCamera = true; + if (_s4MoveCamera) + { + var cameraPercentage = 0.5f + MathF.Sin(-MathF.PI / 2 + MathHelper.Clamp((float)(_screen4Counter - 10500) / 4500, 0, 1) * MathF.PI) / 2; + _s4CameraPosition = MathHelper.Lerp(720f, 0, cameraPercentage); + } + + _cameraPosition = new Vector2(0, _s4CameraPosition); + + // move the wale up + if (_s4CameraPosition < 144) + _s4Wale.Position.Y -= 1 / 8f * Game1.TimeMultiplier; + + if (!_s4LookedUp && _screen4Counter > 8800) + { + _s4LookedUp = true; + _s4Link.Animator.Play("look_up"); + } + + if (!_playedWaleSound0 && _s4Wale.Position.Y < 62) + { + _playedWaleSound0 = true; + Game1.GameManager.PlaySoundEffect("D370-23-17"); + } + if (!_playedWaleSound1 && _s4Wale.Position.Y < 32) + { + _playedWaleSound1 = true; + Game1.GameManager.PlaySoundEffect("D370-23-17"); + } + + if (_s4Wale.Position.Y < 24) + { + _s4Sun0.Color = Color.White; + // wale blocks the sunlight + _s4Brightness = AnimationHelper.MoveToTarget(_s4Brightness, 255, 2f * Game1.TimeMultiplier); + } + if (_s4Wale.Position.Y < 20 - 5) + _s4Sun1.Color = Color.White; + if (_s4Wale.Position.Y < 20 - 10) + _s4Sun2.Color = Color.White; + + _s4Link.Position.Y = _s4LinkPosY + MathF.Round(MathF.Sin((float)_screen4Counter / 3300 * MathF.PI * 2) * 4f); + + var colorBrightness = new Color((int)_s4Brightness, (int)_s4Brightness, (int)_s4Brightness); + _s4Link.Color = colorBrightness; + _s4Background.Color = colorBrightness; + for (int i = 0; i < _s4Water.Length; i++) + _s4Water[i].Color = colorBrightness; + } + + private void UpdateScreen5() + { + _screen5Counter += Game1.DeltaTime; + if (_screen5Counter > 3500 && !_screen5Smile) + { + _screen5Smile = true; + _s5Link.Animator.Play("smile"); + } + + // start fade out + if (_screen5Counter > 14000 - ScreenFadeTime && _screenFadeCounter == 0) + _screenFadeCounter = ScreenFadeTime * 2; + + // show the next screen + if (_screen5Counter > 14000 && _screenFadeCounter <= ScreenFadeTime) + { + InitScreen6(); + } + + // brighten up the sprite + var brighness = 155 + (int)(100 * MathHelper.Clamp((_screen5Counter - 750) / 500, 0, 1)); + _s5Link.Color = new Color(brighness, brighness, brighness); + + // offset the position of the link animation to not cut off the sprite + var posY = (int)MathF.Ceiling((Game1.WindowHeight - _sequenceHeight * _scale) / 2) / _scale; + if (posY > 0) + posY = 0; + + _s5Link.Position.Y = _sequenceHeight + posY + MathF.Round(2 + MathF.Sin(_screen5Counter / 3000 * MathF.PI * 2) * 2); + _s5Background.Position.Y = posY; + } + + private void UpdateScreen6() + { + if (_finishedCredits) + { + if (_marinEndingTriggered) + { + _screen6Counter += Game1.DeltaTime; + + if (_screen6Counter > 13000) + { + // hide marin + _s6MarinTransparency = AnimationHelper.MoveToTarget(_s6MarinTransparency, 0, 0.025f * Game1.TimeMultiplier); + + var musicVolume = Math.Clamp(((_s6MarinTransparency - 13000) / 1000), 0, 1); + Game1.GbsPlayer.SetVolumeMultiplier(musicVolume); + } + // fade the singing out + else + { + // show marin + _s6MarinTransparency = AnimationHelper.MoveToTarget(_s6MarinTransparency, 1, 0.025f * Game1.TimeMultiplier); + + Game1.GbsPlayer.SetVolumeMultiplier(0); + } + + _s6Marin.Color = Color.White * _s6MarinTransparency; + + if (_screen6Counter > 16000) + ExitToIntro(); + } + + // return to the intro screen + if (ControlHandler.ButtonPressed(CButtons.Start) || + ControlHandler.ButtonPressed(CButtons.A)) + { + if (_marinEnding) + { + _creditsHeader = null; + _creditsContent = null; + _marinEndingTriggered = true; + + Game1.GameManager.SetMusic(46, 2); + } + else + { + ExitToIntro(); + } + } + + return; + } + + _screen6Counter += Game1.DeltaTime; + + // move the camera up + if (_screen6Counter > 72500) + { + _s6CameraPosition -= 1 / 8f * Game1.TimeMultiplier; + if (_s6CameraPosition < 0) + _s6CameraPosition = 0; + } + _cameraPosition = new Vector2(0, _s6CameraPosition); + + // link move up and down + _s6Link.Position.Y = _s6LinkPosition + MathF.Round(MathF.Sin(_screen6Counter / 3000 * MathF.PI * 2) * 2); + + if (_s6CameraPosition < 128) + { + _s6Wale.Position.X += 1 / 8f * Game1.TimeMultiplier; + _s6Wale.Position.Y -= 1 / 4f / 8f * Game1.TimeMultiplier; + } + + // credits + { + _creditCounter += Game1.DeltaTime; + if (_creditCounter > 3450) + { + _creditCounter -= 3450; + if (!NextCredits()) + { + _screen6Counter = 0; + _finishedCredits = true; + } + } + } + } + + private void ExitToIntro() + { + Game1.ScreenManager.ChangeScreen(Values.ScreenNameIntro); + Game1.GameManager.InGameOverlay.CloseOverlay(); + } + + private bool NextCredits() + { + _creditsContentIndex++; + var newContent = Game1.LanguageManager.GetString("credits_" + _creditsHeaderIndex + "_" + _creditsContentIndex, null); + + if (newContent == null) + { + _creditsHeaderIndex++; + var newHeader = Game1.LanguageManager.GetString("credits_" + _creditsHeaderIndex, null); + + if (newHeader != null) + { + _creditsHeader = newHeader; + + _creditsContentIndex = 0; + _creditsContent = Game1.LanguageManager.GetString("credits_" + _creditsHeaderIndex + "_" + _creditsContentIndex, null); + } + // finished credits? + else + return false; + } + else + { + _creditsContent = newContent; + } + + return true; + } + + public override void Draw(SpriteBatch spriteBatch, float transparency) + { + base.Draw(spriteBatch, transparency); + + if (_screenIndex == 6) + DrawCredits(spriteBatch); + + DrawSidebars(spriteBatch); + + if (_screenFadeCounter > 0) + { + var percentage = MathF.Sin((_screenFadeCounter / (ScreenFadeTime * 2)) * MathF.PI); + spriteBatch.Draw(Resources.SprWhite, new Rectangle(0, 0, Game1.WindowWidth, Game1.WindowHeight), Color.White * percentage); + } + } + + private void DrawCredits(SpriteBatch spriteBatch) + { + var creditOffset = new Vector3( + MathF.Round((-_sequenceWidth / 2 - _cameraPosition.X) * _scale) / _scale, + MathF.Round((-_sequenceHeight / 2 - _cameraPosition.Y) * _scale) / _scale, 0); + + // round the camera position to align with pixels + var matrix = + Matrix.CreateTranslation(creditOffset) * + Matrix.CreateScale(_scale) * + Matrix.CreateTranslation(new Vector3((int)(Game1.WindowWidth * 0.5f), (int)(Game1.WindowHeight * 0.5f), 0)) * + Game1.GetMatrix; + + spriteBatch.End(); + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, matrix); + + if (_creditsHeader != null) + { + // draw the header centered + var textSize = Resources.FontCreditsHeader.MeasureString(_creditsHeader); + var position = new Vector2(_sequenceWidth / 2 - textSize.X / 2, _cameraPosition.Y + (18 + 48)); + spriteBatch.DrawString(Resources.FontCreditsHeader, _creditsHeader, position, Color.White); + } + + if (_creditsContent != null) + { + // draw the content centered + var textSize = Resources.FontCreditsHeader.MeasureString(_creditsContent); + var position = new Vector2(_sequenceWidth / 2 - textSize.X / 2, _cameraPosition.Y + (18 + 70)); + spriteBatch.DrawString(Resources.FontCredits, _creditsContent, position, Color.White); + } + + spriteBatch.End(); + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, Game1.GetMatrix); + } + + private void DrawSidebars(SpriteBatch spriteBatch) + { + var width = (int)MathF.Ceiling((Game1.WindowWidth - _sequenceWidth * _scale) / 2); + if (width > 0) + { + spriteBatch.Draw(Resources.SprWhite, new Rectangle(0, 0, width, Game1.WindowHeight), Color.Black); + spriteBatch.Draw(Resources.SprWhite, new Rectangle(Game1.WindowWidth / 2 + _sequenceWidth / 2 * _scale, 0, width + 1, Game1.WindowHeight), Color.Black); + } + + var height = (int)MathF.Ceiling((Game1.WindowHeight - _sequenceHeight * _scale) / 2); + if (height > 0) + { + spriteBatch.Draw(Resources.SprWhite, new Rectangle(0, 0, Game1.WindowWidth, height), Color.Black); + spriteBatch.Draw(Resources.SprWhite, new Rectangle(0, Game1.WindowHeight / 2 + _sequenceHeight / 2 * _scale, Game1.WindowWidth, height + 1), Color.Black); + } + } + } +} diff --git a/InGame/Overlay/Sequences/GameSequence.cs b/InGame/Overlay/Sequences/GameSequence.cs new file mode 100644 index 0000000..9627ccf --- /dev/null +++ b/InGame/Overlay/Sequences/GameSequence.cs @@ -0,0 +1,343 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Overlay.Sequences +{ + public class SeqDrawable + { + public SpriteShader Shader; + public Color Color = Color.White; + + public Vector2 Position; + + // position transition + public Vector2 PositionStart; + public Vector2 PositionEnd; + + public float PositionTransitionTime; + public float PositionTransitionCounter; + + // color transition + public Color ColorStart; + public Color ColorEnd; + + public float ColorTransitionTime; + public float ColorTransitionCounter; + + public int Layer; + + public virtual void Draw(SpriteBatch spriteBatch) { } + } + + public class SeqColor : SeqDrawable + { + public Rectangle Rect; + + public SeqColor(Rectangle rect, Color color, int layer) + { + Rect = rect; + Color = color; + Layer = layer; + } + + public override void Draw(SpriteBatch spriteBatch) + { + spriteBatch.Draw(Resources.SprWhite, Rect, Color); + } + } + + public class SeqSprite : SeqDrawable + { + public DictAtlasEntry Sprite; + public SpriteEffects SpriteEffect = SpriteEffects.None; + public bool RoundPosition; + + public SeqSprite(string spriteId, Vector2 position, int layer) + { + Sprite = Resources.GetSprite(spriteId); + Position = position; + Layer = layer; + } + + public override void Draw(SpriteBatch spriteBatch) + { + var drawPosition = Position; + if (RoundPosition) + { + drawPosition.X = (int)drawPosition.X; + drawPosition.Y = (int)drawPosition.Y; + } + + // flip around the origin + if ((SpriteEffect & SpriteEffects.FlipHorizontally) != 0) + drawPosition.X += -Sprite.ScaledRectangle.Width + Sprite.Origin.X * Sprite.Scale; + else + drawPosition.X -= Sprite.Origin.X * Sprite.Scale; + + if ((SpriteEffect & SpriteEffects.FlipVertically) != 0) + drawPosition.Y += -Sprite.ScaledRectangle.Height + Sprite.Origin.Y * Sprite.Scale; + else + drawPosition.Y -= Sprite.Origin.Y * Sprite.Scale; + + spriteBatch.Draw(Sprite.Texture, drawPosition, Sprite.ScaledRectangle, + Color, 0, Vector2.Zero, new Vector2(Sprite.Scale), SpriteEffect, 0); + } + } + + public class SeqAnimation : SeqDrawable + { + public Animator Animator; + public bool RoundPosition; + + public SeqAnimation(string animatorId, string animationId, Vector2 position, int layer) + { + Animator = AnimatorSaveLoad.LoadAnimator(animatorId); + Animator.Play(animationId); + + Position = position; + Layer = layer; + } + + public override void Draw(SpriteBatch spriteBatch) + { + var drawPosition = Position; + if (RoundPosition) + { + drawPosition.X = (int)drawPosition.X; + drawPosition.Y = (int)drawPosition.Y; + } + + Animator.DrawBasic(spriteBatch, drawPosition, Color); + } + } + + public class GameSequence + { + protected RenderTarget2D _renderTarget; + + protected List Sprites = new List(); + protected Dictionary SpriteDict = new Dictionary(); + + protected Vector2 _cameraPosition; + + protected int _sequenceWidth = 160; + protected int _sequenceHeight = 144; + + protected double _sequenceCounter; + + protected int _scale; + protected bool _useUiScale = true; + protected bool _textBoxOffset = true; + + public virtual void OnStart() + { + _sequenceCounter = 0; + } + + public void AddDrawable(string key, SeqDrawable drawable) + { + Sprites.Add(drawable); + SpriteDict.TryAdd(key, drawable); + } + + public void PlayAnimation(string key, string animationId) + { + SpriteDict.TryGetValue(key, out SeqDrawable drawable); + + if (drawable == null) + return; + + var animator = (SeqAnimation)drawable; + if (animator != null) + animator.Animator.Play(animationId); + } + + /// + /// Finish the animation that is currently playing; This will not directly stop the animation but continue it till the end and even start the next animation that is set + /// + /// + public void FinishAnimation(string key, int stopFrameIndex) + { + SpriteDict.TryGetValue(key, out SeqDrawable drawable); + + if (drawable == null) + return; + + var animator = (SeqAnimation)drawable; + if (animator != null) + animator.Animator.FinishAnimation(stopFrameIndex); + } + + public void SetPosition(string key, Vector2 newPosition) + { + SpriteDict.TryGetValue(key, out SeqDrawable drawable); + + if (drawable != null) + drawable.Position = newPosition; + } + + public void StartPositionTransition(string drawableId, Vector2 positionOffset, float speed) + { + SpriteDict.TryGetValue(drawableId, out SeqDrawable drawable); + + if (drawable != null) + { + drawable.PositionStart = drawable.Position; + drawable.PositionEnd = drawable.Position + positionOffset; + drawable.PositionTransitionCounter = 0; + + // calculate the time needed to finishe the transition + var length = drawable.PositionStart - drawable.PositionEnd; + drawable.PositionTransitionTime = ((length.Length() / speed) / 60) * 1000; + + Game1.GameManager.SaveManager.SetString(drawableId + "Moving", "1"); + } + } + + public void StartColorTransition(string drawableId, Color targetColor, int time) + { + SpriteDict.TryGetValue(drawableId, out SeqDrawable drawable); + + if (drawable != null) + { + if (time == 0) + { + drawable.Color = targetColor; + return; + } + + drawable.ColorStart = drawable.Color; + drawable.ColorEnd = targetColor; + drawable.ColorTransitionTime = time; + drawable.ColorTransitionCounter = 0; + } + } + + public virtual void Update() + { + _sequenceCounter += Game1.DeltaTime; + + for (var i = 0; i < Sprites.Count; i++) + { + if (Sprites[i] is SeqAnimation animator) + animator.Animator.Update(); + + } + + foreach (var spriteEntry in SpriteDict) + { + var sprite = spriteEntry.Value; + + // update position transition + if (sprite.PositionTransitionTime != 0) + { + sprite.PositionTransitionCounter += Game1.DeltaTime; + if (sprite.PositionTransitionCounter > sprite.PositionTransitionTime) + { + sprite.PositionTransitionTime = 0; + sprite.Position = sprite.PositionEnd; + Game1.GameManager.SaveManager.SetString(spriteEntry.Key + "Moving", "0"); + continue; + } + + var percentage = sprite.PositionTransitionCounter / sprite.PositionTransitionTime; + sprite.Position = Vector2.Lerp(sprite.PositionStart, sprite.PositionEnd, percentage); + } + + // update color transition + if (sprite.ColorTransitionTime != 0) + { + sprite.ColorTransitionCounter += Game1.DeltaTime; + if (sprite.ColorTransitionCounter > sprite.ColorTransitionTime) + { + sprite.ColorTransitionTime = 0; + sprite.Color = sprite.ColorEnd; + continue; + } + + var percentage = sprite.ColorTransitionCounter / sprite.ColorTransitionTime; + sprite.Color = Color.Lerp(sprite.ColorStart, sprite.ColorEnd, percentage); + } + } + } + + private void UpdateRenderTarget() + { + if (_renderTarget != null && + _sequenceWidth * _scale == _renderTarget.Width && _sequenceHeight * _scale == _renderTarget.Height) + return; + + _renderTarget = new RenderTarget2D(Game1.Graphics.GraphicsDevice, _sequenceWidth * _scale, _sequenceHeight * _scale); + } + + public virtual void DrawRT(SpriteBatch spriteBatch) + { + if (_useUiScale) + _scale = Game1.UiScale; + + UpdateRenderTarget(); + + // sort the sprites + Sprites.Sort((sprite0, sprite1) => sprite0.Layer - sprite1.Layer); + + // round the camera position to align with pixels + var matrix = + Matrix.CreateTranslation(new Vector3( + MathF.Round((-_cameraPosition.X) * _scale) / _scale, + MathF.Round((-_cameraPosition.Y) * _scale) / _scale, 0)) * + Matrix.CreateScale(_scale); + + spriteBatch.GraphicsDevice.SetRenderTarget(_renderTarget); + spriteBatch.GraphicsDevice.Clear(Color.Transparent); + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, matrix); + + for (var i = 0; i < Sprites.Count; i++) + { + // change the draw effect + if (Sprites[i].Shader != null) + { + spriteBatch.End(); + + ObjectManager.SetSpriteShader(Sprites[i].Shader); + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, Sprites[i].Shader.Effect, matrix); + } + + Sprites[i].Draw(spriteBatch); + + // change the draw effect + // this would not be very efficient if a lot of sprite used effects + if (Sprites[i].Shader != null) + { + spriteBatch.End(); + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, matrix); + } + } + + DrawScaled(spriteBatch); + + spriteBatch.End(); + spriteBatch.GraphicsDevice.SetRenderTarget(null); + } + + public virtual void Draw(SpriteBatch spriteBatch, float transparency) + { + var position = new Vector2( + Game1.WindowWidth / 2 - _renderTarget.Width / 2 + MapManager.Camera.ShakeOffsetX * _scale, + Game1.WindowHeight / 2 - _renderTarget.Height / 2 + MapManager.Camera.ShakeOffsetY * _scale); + + // push the sequence rt up if the textbox would overlap + if (_textBoxOffset) + position.Y = Math.Min(position.Y, Game1.GameManager.InGameOverlay.TextboxOverlay.DialogBoxTextBox.Y - _renderTarget.Height - 12 * _scale); + + spriteBatch.Draw(_renderTarget, position, Color.White * transparency); + } + + public virtual void DrawScaled(SpriteBatch spriteBatch) { } + } +} diff --git a/InGame/Overlay/Sequences/GravestoneSequence.cs b/InGame/Overlay/Sequences/GravestoneSequence.cs new file mode 100644 index 0000000..62b0b29 --- /dev/null +++ b/InGame/Overlay/Sequences/GravestoneSequence.cs @@ -0,0 +1,36 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Overlay.Sequences +{ + class GravestoneSequence : GameSequence + { + public GravestoneSequence() + { + _sequenceWidth = 160; + _sequenceHeight = 144; + } + + public override void OnStart() + { + Sprites.Clear(); + SpriteDict.Clear(); + + var position = Vector2.Zero; + + // background + Sprites.Add(new SeqSprite("seqGravestoneBackground", position, 0)); + + // characters + AddDrawable("graveLink", new SeqAnimation("Sequences/link grave", "look", new Vector2(position.X + 75, position.Y + 101), 1) { Shader = Resources.ColorShader, Color = Game1.GameManager.CloakColor }); + AddDrawable("graveMouse", new SeqAnimation("NPCs/photo_mouse", "stand_0", new Vector2(position.X + 173, position.Y + 102), 1)); + + AddDrawable("gravePhotoFlash", new SeqColor(new Rectangle((int)position.X, (int)position.Y, 160, 144), Color.Transparent, 2)); + AddDrawable("gravePhoto", new SeqSprite("photo_11", position, 1) { Color = Color.Transparent }); + + Game1.GameManager.StartDialogPath("seq_gravestone"); + + base.OnStart(); + } + } +} diff --git a/InGame/Overlay/Sequences/MapOverlaySequence.cs b/InGame/Overlay/Sequences/MapOverlaySequence.cs new file mode 100644 index 0000000..dcb6dad --- /dev/null +++ b/InGame/Overlay/Sequences/MapOverlaySequence.cs @@ -0,0 +1,76 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Overlay.Sequences +{ + class MapOverlaySequence : GameSequence + { + private MapOverlay _mapOverlay; + + public MapOverlaySequence() + { + _sequenceWidth = 144; + _sequenceHeight = 144; + + _mapOverlay = new MapOverlay(_sequenceWidth, _sequenceHeight, 0, true); + _mapOverlay.Load(); + _mapOverlay.IsSelected = true; + _mapOverlay.UpdateRenderTarget(); + } + + public override void OnStart() + { + base.OnStart(); + + _mapOverlay.OnFocus(); + } + + public override void Update() + { + base.Update(); + + _mapOverlay.UpdateRenderTarget(); + _mapOverlay.Update(); + + // can close the overlay if the dialog isn't running anymore + if (ControlHandler.ButtonPressed(CButtons.B) && + !Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen) + Game1.GameManager.InGameOverlay.CloseOverlay(); + } + + public override void DrawRT(SpriteBatch spriteBatch) + { + _mapOverlay.DrawRenderTarget(spriteBatch); + Game1.Graphics.GraphicsDevice.SetRenderTarget(null); + } + + public override void Draw(SpriteBatch spriteBatch, float transparency) + { + spriteBatch.End(); + + var width = _sequenceWidth * Game1.UiScale; + var height = _sequenceHeight * Game1.UiScale; + + _mapOverlay.Draw(spriteBatch, new Rectangle( + Game1.WindowWidth / 2 - width / 2, + Game1.WindowHeight / 2 - height / 2, width, height), Color.White * transparency, Game1.GetMatrix); + + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, null, null, null, null); + + // draw close text + { + var selectStr = ""; + if (ControlHandler.LastKeyboardDown && ControlHandler.ButtonDictionary[CButtons.B].Keys.Length > 0) + selectStr = ControlHandler.ButtonDictionary[CButtons.B].Keys[0].ToString(); + if (!ControlHandler.LastKeyboardDown && ControlHandler.ButtonDictionary[CButtons.B].Buttons.Length > 0) + selectStr = ControlHandler.ButtonDictionary[CButtons.B].Buttons[0].ToString(); + var inputHelper = selectStr + ": " + Game1.LanguageManager.GetString("map_overlay_close", "error"); + + spriteBatch.DrawString(Resources.GameFont, inputHelper, + new Vector2(8 * Game1.UiScale, Game1.WindowHeight - 16 * Game1.UiScale), Color.White * transparency, 0, Vector2.Zero, Game1.UiScale, SpriteEffects.None, 0); + } + } + } +} diff --git a/InGame/Overlay/Sequences/MariaBeachSequence.cs b/InGame/Overlay/Sequences/MariaBeachSequence.cs new file mode 100644 index 0000000..1b2840e --- /dev/null +++ b/InGame/Overlay/Sequences/MariaBeachSequence.cs @@ -0,0 +1,182 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.Things; +using System; + +namespace ProjectZ.InGame.Overlay.Sequences +{ + class MarinBeachSequence : GameSequence + { + struct Seagull + { + public SeqAnimation Animation; + public Vector2 Position; + public Vector2 Direction; + public float GlideCounter; + } + + private readonly Seagull[] _seagulls = new Seagull[2]; + private readonly Seagull[] _smallSeagulls = new Seagull[5]; + + private SeqAnimation _aniLink; + private SeqAnimation _aniMarin; + + private Vector2 _seagullCenter; + + private float _shoreSoundCounter; + private float _birdSoundCounter; + + public MarinBeachSequence() + { + _sequenceWidth = 320; + _sequenceHeight = 128 + 48; + } + + public override void OnStart() + { + Sprites.Clear(); + SpriteDict.Clear(); + + var top = 48; + var center = 160; + + // sky background + Sprites.Add(new SeqColor(new Rectangle(0, 0, _sequenceWidth, top), new Color(66, 89, 254), 0)); + + // beach + Sprites.Add(new SeqSprite("beach_background", new Vector2(0, top), 0)); + Sprites.Add(new SeqSprite("beach_palm", new Vector2(56, top + 32), 2)); + Sprites.Add(new SeqSprite("beach_palm", new Vector2(208, top + 32), 2)); + + // waves + for (int i = 0; i < 20; i++) + { + Sprites.Add(new SeqAnimation("Sequences/beach_water", "top", new Vector2(i * 16, top + 56), 1)); + Sprites.Add(new SeqAnimation("Sequences/beach_water", "bottom", new Vector2(i * 16, top + 72), 1)); + } + + // link and marin + _aniLink = new SeqAnimation("link0", "ocean_sit", new Vector2(center - 14, top + 92), 1) { Shader = Resources.ColorShader, Color = Game1.GameManager.CloakColor }; + AddDrawable("link", _aniLink); + _aniMarin = new SeqAnimation("NPCs/marin", "ocean_sit", new Vector2(center + 1, top + 92), 1); + AddDrawable("marin", _aniMarin); + + _seagulls[0] = new Seagull() + { + Position = new Vector2(center - 90, top - 48), + Direction = new Vector2(0.5f, 0.25f), + GlideCounter = 1500, + }; + _seagulls[1] = new Seagull() + { + Position = new Vector2(center + 64, top), + Direction = new Vector2(-0.5f, 0.2f), + GlideCounter = 2500, + }; + + Sprites.Add(_seagulls[0].Animation = new SeqAnimation("Sequences/seagull", "glide", _seagulls[0].Position, 1)); + Sprites.Add(_seagulls[1].Animation = new SeqAnimation("Sequences/seagull", "glide", _seagulls[1].Position, 1)); + + _seagullCenter = new Vector2(center, top + 38); + + for (int i = 0; i < _smallSeagulls.Length; i++) + { + var posX = Game1.RandomNumber.Next(0, 32) - 16; + var posY = Game1.RandomNumber.Next(0, 12); + + _smallSeagulls[i] = new Seagull() + { + Position = new Vector2(_seagullCenter.X + posX, _seagullCenter.Y + posY), + Direction = new Vector2(0.5f, 0.25f), + //GlideCounter = Game1.RandomNumber.Next(0, 5000), + }; + + Sprites.Add(_smallSeagulls[i].Animation = new SeqAnimation("Sequences/seagull small", "idle", _smallSeagulls[i].Position, i + 1) { RoundPosition = true }); + _smallSeagulls[i].Animation.Animator.SetTime(Game1.RandomNumber.Next(0, _smallSeagulls[i].Animation.Animator.CurrentFrame.FrameTime)); + } + + // start the sequence path + Game1.GameManager.SaveManager.SetString("seq_beach", "0"); + Game1.GameManager.StartDialogPath("seq_beach"); + + base.OnStart(); + } + + public override void Update() + { + base.Update(); + + UpdateSeagulls(); + } + + private void UpdateSeagulls() + { + _birdSoundCounter -= Game1.DeltaTime; + if (_birdSoundCounter < 0) + { + _birdSoundCounter += Game1.RandomNumber.Next(1000, 3500); + Game1.GameManager.PlaySoundEffect("D360-33-21"); + } + + _shoreSoundCounter -= Game1.DeltaTime; + if (_shoreSoundCounter < 0) + { + _shoreSoundCounter += 3500; + Game1.GameManager.PlaySoundEffect("D378-15-0F"); + } + + // update the seagulls far away + for (int i = 0; i < _smallSeagulls.Length; i++) + { + _smallSeagulls[i].GlideCounter -= Game1.DeltaTime; + + if (_smallSeagulls[i].GlideCounter < 0) + { + _smallSeagulls[i].GlideCounter = Game1.RandomNumber.Next(500, 1250); + + // glide down + if (Game1.RandomNumber.Next(0, 4) == 0) + { + _smallSeagulls[i].Direction.X *= 0.25f; + _smallSeagulls[i].Direction.Y = 0.1f; + _smallSeagulls[i].Animation.Animator.Play("glide"); + } + else + { + var centerDirection = _seagullCenter - _smallSeagulls[i].Position; + if (centerDirection != Vector2.Zero) + { + var distance = MathHelper.Clamp(1 - centerDirection.Length() / 48, 0, 1); + var radiant = MathF.Atan2(centerDirection.Y, centerDirection.X) + (MathF.PI - Game1.RandomNumber.Next(0, 628) / 100f) * distance; + + _smallSeagulls[i].Direction = new Vector2(MathF.Cos(radiant), MathF.Sin(radiant)) * (Game1.RandomNumber.Next(8, 15) / 100f); + } + + _smallSeagulls[i].Animation.Animator.Play("idle"); + } + } + + _smallSeagulls[i].Direction.X *= (float)Math.Pow(0.99f, Game1.TimeMultiplier); + _smallSeagulls[i].Position += _smallSeagulls[i].Direction * Game1.TimeMultiplier; + _smallSeagulls[i].Animation.Position = _smallSeagulls[i].Position; + } + + + // update the closer seagulls + for (int i = 0; i < _seagulls.Length; i++) + { + if (_seagulls[i].GlideCounter > 0) + { + _seagulls[i].GlideCounter -= Game1.DeltaTime; + if (_seagulls[i].GlideCounter <= 0) + { + _seagulls[i].Direction.Y = -_seagulls[i].Direction.Y; + _seagulls[i].Animation.Animator.Play("idle"); + } + } + + _seagulls[i].Position += _seagulls[i].Direction * Game1.TimeMultiplier; + _seagulls[i].Animation.Position = _seagulls[i].Position; + } + } + } +} diff --git a/InGame/Overlay/Sequences/MariaCliffSequence.cs b/InGame/Overlay/Sequences/MariaCliffSequence.cs new file mode 100644 index 0000000..c0f37e4 --- /dev/null +++ b/InGame/Overlay/Sequences/MariaCliffSequence.cs @@ -0,0 +1,50 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Overlay.Sequences +{ + class MarinCliffSequence : GameSequence + { + private float _birdSoundCounter; + + public MarinCliffSequence() + { + _sequenceWidth = 160; + _sequenceHeight = 144; + } + + public override void OnStart() + { + Sprites.Clear(); + SpriteDict.Clear(); + + var position = Vector2.Zero; + + // background + Sprites.Add(new SeqSprite("cliff_background", position, 0)); + + // link and marin + Sprites.Add(new SeqAnimation("Sequences/cliff sequence", "link", new Vector2(position.X + 99, position.Y + 40), 1) { Shader = Resources.ColorShader, Color = Game1.GameManager.CloakColor }); + Sprites.Add(new SeqAnimation("Sequences/cliff sequence", "marin", new Vector2(position.X + 81, position.Y + 56), 1)); + + AddDrawable("cliffPhotoFlash", new SeqColor(new Rectangle((int)position.X, (int)position.Y, 160, 144), Color.Transparent, 5)); + + // start the sequence path + Game1.GameManager.StartDialogPath("seq_cliff"); + + base.OnStart(); + } + + public override void Update() + { + base.Update(); + + _birdSoundCounter -= Game1.DeltaTime; + if (_birdSoundCounter < 0) + { + _birdSoundCounter += Game1.RandomNumber.Next(1000, 3500); + Game1.GameManager.PlaySoundEffect("D360-33-21"); + } + } + } +} diff --git a/InGame/Overlay/Sequences/PhotoSequence.cs b/InGame/Overlay/Sequences/PhotoSequence.cs new file mode 100644 index 0000000..0fe61c2 --- /dev/null +++ b/InGame/Overlay/Sequences/PhotoSequence.cs @@ -0,0 +1,37 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.Controls; + +namespace ProjectZ.InGame.Overlay.Sequences +{ + class PhotoSequence : GameSequence + { + public PhotoSequence() + { + _sequenceWidth = 160; + _sequenceHeight = 144; + } + + public override void OnStart() + { + Sprites.Clear(); + SpriteDict.Clear(); + + var photo = Game1.GameManager.SaveManager.GetString("photoSequencePhoto"); + + // background + if (!string.IsNullOrEmpty(photo)) + Sprites.Add(new SeqSprite(photo, new Vector2(0, 0), 0)); + + base.OnStart(); + } + + public override void Update() + { + base.Update(); + + // can close the overlay if the dialog isn't running anymore + if (!Game1.GameManager.DialogIsRunning() && ControlHandler.ButtonPressed(CButtons.B)) + Game1.GameManager.InGameOverlay.CloseOverlay(); + } + } +} diff --git a/InGame/Overlay/Sequences/PictureSequence.cs b/InGame/Overlay/Sequences/PictureSequence.cs new file mode 100644 index 0000000..f244703 --- /dev/null +++ b/InGame/Overlay/Sequences/PictureSequence.cs @@ -0,0 +1,29 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.Controls; + +namespace ProjectZ.InGame.Overlay.Sequences +{ + class PictureSequence : GameSequence + { + public PictureSequence() + { + _sequenceWidth = 103; + _sequenceHeight = 128; + + // background + Sprites.Add(new SeqSprite("trade_picture", new Vector2(0, 0), 0)); + } + + public override void Update() + { + base.Update(); + + // can close the overlay if the dialog isn't running anymore + if (!Game1.GameManager.DialogIsRunning() && ControlHandler.ButtonPressed(CButtons.B)) + { + Game1.GameManager.InGameOverlay.CloseOverlay(); + Game1.GameManager.StartDialogPath("close_picture"); + } + } + } +} diff --git a/InGame/Overlay/Sequences/ShrineSequence.cs b/InGame/Overlay/Sequences/ShrineSequence.cs new file mode 100644 index 0000000..d3156c4 --- /dev/null +++ b/InGame/Overlay/Sequences/ShrineSequence.cs @@ -0,0 +1,26 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.Controls; + +namespace ProjectZ.InGame.Overlay.Sequences +{ + class ShrineSequence : GameSequence + { + public ShrineSequence() + { + _sequenceWidth = 160; + _sequenceHeight = 144; + + // background + Sprites.Add(new SeqSprite("shrine", new Vector2(0, 0), 0)); + } + + public override void Update() + { + base.Update(); + + // can close the overlay if the dialog isn't running anymore + if (!Game1.GameManager.DialogIsRunning() && ControlHandler.ButtonPressed(CButtons.B)) + Game1.GameManager.InGameOverlay.CloseOverlay(); + } + } +} diff --git a/InGame/Overlay/Sequences/TowerCollapseSequence.cs b/InGame/Overlay/Sequences/TowerCollapseSequence.cs new file mode 100644 index 0000000..071addb --- /dev/null +++ b/InGame/Overlay/Sequences/TowerCollapseSequence.cs @@ -0,0 +1,81 @@ +using Microsoft.Xna.Framework; + +namespace ProjectZ.InGame.Overlay.Sequences +{ + class TowerCollapseSequence : GameSequence + { + private SeqSprite _sprTower; + private SeqAnimation _aniDust; + + private int _state; + + public override void OnStart() + { + Sprites.Clear(); + SpriteDict.Clear(); + + Sprites.Add(new SeqSprite("tower_background", new Vector2(0, 0), 0)); + Sprites.Add(new SeqSprite("tower_bottom", new Vector2(48, 96), 1)); + Sprites.Add(_sprTower = new SeqSprite("tower_top", new Vector2(64, 17), 0)); + + _sequenceCounter = 0; + _state = 0; + } + + public override void Update() + { + base.Update(); + + var collapseTime = 800; + var shakeTime = 600; + var shakePeriode = 4.5f; + + if (_sequenceCounter > 250 && _state == 0) + { + Game1.GameManager.ShakeScreen(2300, 0, 1, 0, shakePeriode); + _state = 1; + } + else if (_sequenceCounter > 2500 && _state == 1) + { + Game1.GameManager.PlaySoundEffect("D378-12-0C"); + Game1.GameManager.ShakeScreen(shakeTime, 0, 1, 0, shakePeriode); + Sprites.Add(_aniDust = new SeqAnimation("Sequences/tower dust", "idle", new Vector2(56, 88), 1)); + _sprTower.Position.Y += 8; + _state = 2; + } + else if (_sequenceCounter > 2500 + collapseTime && _state == 2) + { + Game1.GameManager.PlaySoundEffect("D378-12-0C"); + Game1.GameManager.ShakeScreen(shakeTime, 0, 1, 0, shakePeriode); + _sprTower.Position.Y += 8; + _state = 3; + } + else if (_sequenceCounter > 2500 + collapseTime * 2 && _state == 3) + { + Game1.GameManager.PlaySoundEffect("D378-12-0C"); + Game1.GameManager.ShakeScreen(shakeTime, 0, 1, 0, shakePeriode); + _sprTower.Position.Y += 8; + _state = 4; + } + else if (_sequenceCounter > 2500 + collapseTime * 3 && _state == 4) + { + Game1.GameManager.PlaySoundEffect("D378-12-0C"); + Game1.GameManager.ShakeScreen(shakeTime, 0, 1, 0, shakePeriode); + _sprTower.Position.Y += 8; + _state = 5; + } + else if (_sequenceCounter > 2500 + collapseTime * 3 + 800 && _state == 5) + { + Sprites.Remove(_aniDust); + _state = 6; + } + else if (_sequenceCounter > 2500 + collapseTime * 4 + 800 && _state == 6) + { + Game1.GameManager.InGameOverlay.CloseOverlay(); + } + + // @HACK + Game1.GameManager.UpdateShake(); + } + } +} diff --git a/InGame/Overlay/Sequences/WeatherBirdSequence.cs b/InGame/Overlay/Sequences/WeatherBirdSequence.cs new file mode 100644 index 0000000..2878ec1 --- /dev/null +++ b/InGame/Overlay/Sequences/WeatherBirdSequence.cs @@ -0,0 +1,60 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Overlay.Sequences +{ + class WeatherBirdSequence : GameSequence + { + private SeqAnimation _objUlrich; + + public WeatherBirdSequence() + { + _sequenceWidth = 160; + _sequenceHeight = 144; + } + + public override void OnStart() + { + Sprites.Clear(); + SpriteDict.Clear(); + + var position = Vector2.Zero; + + // background + Sprites.Add(new SeqSprite("seqWeatherBirdBackground", position, 0)); + + Sprites.Add(new SeqAnimation("Sequences/weather bird objects", "top", new Vector2(position.X, position.Y + 112), 1)); + for (int i = 0; i < 5; i++) + Sprites.Add(new SeqAnimation("Sequences/weather bird objects", "bottom", new Vector2(position.X + 32 * i, position.Y + 136), 1)); + Sprites.Add(new SeqAnimation("Sequences/weather bird objects", "rotator", new Vector2(position.X + 95, position.Y + 56), 1)); + + // flowers + Sprites.Add(new SeqAnimation("Sequences/weather bird objects", "flower_red", new Vector2(position.X + 32, position.Y + 128), 1)); + Sprites.Add(new SeqAnimation("Sequences/weather bird objects", "flower_red", new Vector2(position.X + 64, position.Y + 120), 1)); + Sprites.Add(new SeqAnimation("Sequences/weather bird objects", "flower_white", new Vector2(position.X + 8, position.Y + 128), 1)); + Sprites.Add(new SeqAnimation("Sequences/weather bird objects", "flower_white", new Vector2(position.X + 104, position.Y + 128), 1)); + Sprites.Add(new SeqAnimation("Sequences/weather bird objects", "flower_white", new Vector2(position.X + 144, position.Y + 120), 1)); + + // link and marin + AddDrawable("weatherBirdLink", new SeqAnimation("Sequences/weather bird link", "walk", new Vector2(position.X - 40, position.Y + 112), 3) { Shader = Resources.ColorShader, Color = Game1.GameManager.CloakColor }); + AddDrawable("weatherBirdMarin", new SeqAnimation("Sequences/weather bird marin", "walk", new Vector2(position.X - 40 - 22, position.Y + 112), 3)); + AddDrawable("weatherBirdUlrich", _objUlrich = new SeqAnimation("Sequences/weather bird ulrich", "stopped", new Vector2(position.X + 180, position.Y + 112), 2)); + + AddDrawable("weatherBirdPhotoFlash", new SeqColor(new Rectangle((int)position.X, (int)position.Y, 160, 144), Color.Transparent, 5)); + + // start the sequence path + Game1.GameManager.StartDialogPath("seq_weather_bird"); + + base.OnStart(); + } + + public override void Update() + { + // @HACK: ulrich needs to change the layer + if (Game1.GameManager.SaveManager.GetString("weatherBirdUlrichFront", "0") == "1") + _objUlrich.Layer = 4; + + base.Update(); + } + } +} diff --git a/InGame/Overlay/TextboxOverlay.cs b/InGame/Overlay/TextboxOverlay.cs new file mode 100644 index 0000000..9a804f2 --- /dev/null +++ b/InGame/Overlay/TextboxOverlay.cs @@ -0,0 +1,684 @@ +using System; +using System.Linq; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Base; +using ProjectZ.Base.UI; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Overlay +{ + public class TextboxOverlay + { + struct ChoiceButton + { + public float Percentage; + public float SelectionPercentage; + } + + public Rectangle DialogBoxTextBox; + + public bool IsOpen; + public bool OwlMode; + public bool UpdateObjects; + + public float TransitionState => _currentOpacity; + + private const int ScrollSpeed = 20; + + private readonly Animator _animator; + + private readonly UiRectangle _textboxBackground; + //private readonly UiRectangle _textboxBackgroundSide; + private readonly UiRectangle[] _textboxBackgroundChoice = new UiRectangle[4]; + private readonly ChoiceButton[] _textboxChoice = new ChoiceButton[4]; + + private Rectangle _dialogBoxRectangle; + private Point _letterSize; + + private string _strFullText; + private string _strDialog; + + private string _choiceKey; + private string[] _choices; + + private float _textScrollCounter; + private float _textMult; + private float _textboxOffsetY; + private float _currentOpacity; + private const float TransitionSpeed = 0.15f; + private int _textOffsetY; + + private float _selectionCounter; + private const int SelectionTime = 250; + + private int _currentDialogCount; + private int _paddingLeft = 5; + private int _paddingRight = 12; + private int _paddingV = 5; + private int _textboxMargin = 16; + private int _uiScale = 4; + private int _dialogBoxWidth = 200; + private int _dialogBoxHeight; + private int _currentState; + private int _currentLine; + private int _currentLineAddition; + + private const int MaxCharacters = 26; + private const int MaxLines = 3; + + private float _choicePercentage; + private int _currentChoiceSelection; + private int _choiceWidth; + + private bool _running = true; + private bool _end; + private bool _isChoice; + private bool _openDialog = false; + private bool _boxEnd; + + private string _scrollText; + private float _scrollCounter; + private const int ScrollTime = 125; + private bool _textScrolling; + + public TextboxOverlay() + { + _animator = AnimatorSaveLoad.LoadAnimator("dialog_arrow"); + + // @HACK + _textboxBackground = new UiRectangle(Rectangle.Empty, "textboxblur", Values.ScreenNameGame, Color.Transparent, Color.Transparent, null) { Radius = Values.UiTextboxRadius }; + Game1.EditorUi.AddElement(_textboxBackground); + + //_textboxBackgroundSide = new UiRectangle(Rectangle.Empty, "textboxblur", Values.ScreenNameGame, Color.Transparent, Color.Transparent, null) { Radius = Values.UiTextboxRadius }; + //Game1.EditorUi.AddElement(_textboxBackgroundSide); + + for (var i = 0; i < _textboxBackgroundChoice.Length; i++) + { + _textboxBackgroundChoice[i] = new UiRectangle(Rectangle.Empty, "", Values.ScreenNameGame, Color.Transparent, Color.Transparent, null) { Radius = Values.UiTextboxRadius }; + Game1.EditorUi.AddElement(_textboxBackgroundChoice[i]); + } + } + + public void Init() + { + IsOpen = false; + + _currentOpacity = 0; + UpdateTextBoxState(); + } + + public void Update() + { + if (MapManager.ObjLink.IsTransitioning) + return; + + // update the opacity of the textbox background + if (IsOpen && _currentOpacity < 1) + _currentOpacity += TransitionSpeed * Game1.TimeMultiplier; + else if (!IsOpen && _currentOpacity > 0) + _currentOpacity -= TransitionSpeed * Game1.TimeMultiplier; + _currentOpacity = MathHelper.Clamp(_currentOpacity, 0, 1); + + if (_currentOpacity <= 0 && _openDialog) + { + _openDialog = false; + Game1.GameManager.SaveManager.SetString("dialogOpen", "0"); + } + + if (_currentOpacity >= 1) + UpdateDialogBox(); + + _textboxOffsetY = (float)Math.Sin((1 - _currentOpacity) * Math.PI / 2) * 3 * _uiScale; + + UpdateTextBoxState(); + + if (_isChoice && !_running && _end) + { + _choicePercentage = AnimationHelper.MoveToTarget(_choicePercentage, 1, 0.075f * Game1.TimeMultiplier); + + _choiceWidth = 0; + for (var i = 0; i < _choices.Length; i++) + { + var width = ((int)Resources.GameFont.MeasureString("" + _choices[i] + "").X + 8) * _uiScale; + if (_choiceWidth < width) + _choiceWidth = width; + } + + for (var i = 0; i < _choices.Length; i++) + { + if (_choicePercentage >= i * 0.25f) + _textboxChoice[i].Percentage = AnimationHelper.MoveToTarget(_textboxChoice[i].Percentage, 1, TransitionSpeed * Game1.TimeMultiplier); + + _textboxChoice[i].SelectionPercentage = AnimationHelper.MoveToTarget(_textboxChoice[i].SelectionPercentage, _currentChoiceSelection == i ? 1 : 0, TransitionSpeed * Game1.TimeMultiplier); + + var choicePositionY = _dialogBoxHeight + 1; + var padding = (int)(_textboxChoice[i].SelectionPercentage * _uiScale); + + _textboxBackgroundChoice[i].BackgroundColor = Color.Lerp(Values.TextboxBackgroundColor, Values.TextboxFontColor, _textboxChoice[i].SelectionPercentage) * 0.85f * _currentOpacity * _textboxChoice[i].Percentage; + _textboxBackgroundChoice[i].BlurColor = Values.TextboxBlurColor * _currentOpacity * _textboxChoice[i].Percentage; + _textboxBackgroundChoice[i].Rectangle = new Rectangle( + _dialogBoxRectangle.X + _dialogBoxRectangle.Width - _choiceWidth * (_choices.Length - i) - (3 * _uiScale) * (_choices.Length - 1 - i) - padding - _uiScale, + _dialogBoxRectangle.Y + choicePositionY * _uiScale + (int)_textboxOffsetY - padding + (int)(Math.Sin((1 - _textboxChoice[i].Percentage) * Math.PI / 2) * 4 * _uiScale), + _choiceWidth + 2 * padding, (Resources.GameFontHeight + 4) * _uiScale + 2 * padding); + + } + } + + UpdateGameState(); + } + + private void UpdateTextBoxState() + { + // set textbox fade in from the bottom + _textboxBackground.BackgroundColor = Values.TextboxBackgroundColor * _currentOpacity; + _textboxBackground.BlurColor = Values.TextboxBlurColor * _currentOpacity; + _textboxBackground.Rectangle.Y = _dialogBoxRectangle.Y + (int)_textboxOffsetY; + + //_textboxBackgroundSide.BackgroundColor = Values.TextboxBackgroundSideColor * _currentOpacity; + //_textboxBackgroundSide.BlurColor = Values.TextboxBlurColor * _currentOpacity; + //_textboxBackgroundSide.Rectangle.Y = _dialogBoxRectangle.Y + (int)_textboxOffsetY; + } + + private void UpdateGameState() + { + // this function gets called by StartDialogX and Freezes the game when a dialog is loaded for the map we are transitioning in; not updating the transition for one frame + if (MapManager.ObjLink.IsTransitioning) + return; + + if (_openDialog && !UpdateObjects) + Game1.UpdateGame = false; + + // needs to be called before the UpdateDialogBox method to ensure the player is frozen between a dialog box and a [freeze:x] coming after a [wait:dialogOpen:1] + if (_openDialog && UpdateObjects) + MapManager.ObjLink.FreezePlayer(); + } + + public void DrawTop(SpriteBatch spriteBatch) + { + if (_currentOpacity <= 0) + return; + + var scrollOffset = 0f; + if (_textScrolling) + { + var scrollPercentage = _scrollCounter / ScrollTime; + scrollOffset = scrollPercentage * Resources.GameFontHeight * _uiScale; + + spriteBatch.DrawString(Resources.GameFont, _scrollText, + new Vector2(DialogBoxTextBox.X, DialogBoxTextBox.Y + _textboxOffsetY - Resources.GameFontHeight * _uiScale + scrollOffset + _textOffsetY * _uiScale), + Values.TextboxFontColor * _currentOpacity * Math.Clamp(scrollPercentage * 2f - 1f, 0, 1), 0, Vector2.Zero, _uiScale, SpriteEffects.None, 0); + } + + // draw the dialog box + spriteBatch.DrawString(Resources.GameFont, _strDialog, + new Vector2(DialogBoxTextBox.X, DialogBoxTextBox.Y + _textboxOffsetY + scrollOffset + _textOffsetY * _uiScale), + Values.TextboxFontColor * _currentOpacity, 0, Vector2.Zero, _uiScale, SpriteEffects.None, 0); + + if (!_running && !_end) + { + _animator.DrawBasic(spriteBatch, new Vector2(_dialogBoxRectangle.Right - _uiScale * 2, _dialogBoxRectangle.Bottom - _uiScale * 2), Color.White, _uiScale); + } + + // show the choices if the text is fully shown + if (_isChoice && !_running && _end) + { + for (var i = 0; i < _choices.Length; i++) + { + var textSize = Resources.GameFont.MeasureString(_choices[i]); + var color = Color.Lerp(Values.TextboxFontColor, Values.TextboxBackgroundColor, _textboxChoice[i].SelectionPercentage); + var posX = _textboxBackgroundChoice[i].Rectangle.X + _textboxBackgroundChoice[i].Rectangle.Width / 2 - (textSize.X * _uiScale) / 2; + var posY = _textboxBackgroundChoice[i].Rectangle.Y + _textboxBackgroundChoice[i].Rectangle.Height / 2 - (textSize.Y * _uiScale) / 2 + _uiScale; + + spriteBatch.DrawString(Resources.GameFont, _choices[i], + new Vector2((int)posX, (int)posY), color * _currentOpacity * _textboxChoice[i].Percentage, 0, Vector2.Zero, _uiScale, SpriteEffects.None, 0); + } + } + } + + public void UpdateDialogBox() + { + _animator.Update(); + + if (_isChoice && !_running && _end) + ChoiceUpdate(); + + if (_textScrolling) + { + _scrollCounter -= Game1.DeltaTime; + + if (_scrollCounter <= 0) + { + _textScrolling = false; + _scrollCounter = 0; + } + + return; + } + + if (ControlHandler.ButtonPressed(CButtons.A)) + { + // close the dialog box + if (_end) + { + OwlMode = false; + IsOpen = false; + InputHandler.ResetInputState(); + + // set the choice variable + if (_isChoice) + Game1.GameManager.SaveManager.SetString(_choiceKey, _currentChoiceSelection.ToString()); + } + else + { + // start next box + if (!_running) + { + _textMult = 1; + _running = true; + + // start text in new textbox + if (_boxEnd) + { + _currentLine = 0; + _currentState += _currentDialogCount + 1; + _currentDialogCount = 0; + _textScrollCounter = -150; + _strDialog = ""; + _textOffsetY = CalculateTextOffsetY(_strFullText); + } + // continue scrolling the text up + else + { + _currentLineAddition = 0; + } + } + // jump to end + else + { + _textMult = 4; + } + } + } + + // scroll text + if (_running) + _textScrollCounter += Game1.DeltaTime * _textMult; + + var updated = false; + while (_running && _currentState + _currentDialogCount < _strFullText.Length && _textScrollCounter > ScrollSpeed) + { + updated = true; + _textScrollCounter -= ScrollSpeed; + + NextLetter(false); + } + + if (updated) + { + _strDialog = _strFullText.Substring(_currentState, _currentDialogCount); + } + + if (_running && _currentState + _currentDialogCount >= _strFullText.Length) + { + _end = true; + _running = false; + Game1.GameManager.PlaySoundEffect("D360-21-15"); + } + } + + private void NextLetter(bool fastForward) + { + if (_strFullText[_currentState + _currentDialogCount] == '\f') + { + _animator.Stop(); + _animator.Play("idle"); + + _boxEnd = true; + _running = false; + _currentLineAddition = MaxLines; + + return; + } + + // line break? + if (_strFullText[_currentState + _currentDialogCount] == '\n') + { + if (_currentLine + 1 < MaxLines) + _currentLine++; + else if (_currentLineAddition < MaxLines) + { + _currentLineAddition++; + _textScrolling = true; + _scrollCounter = ScrollTime; + + var offset = _strFullText.IndexOf('\n', _currentState) - _currentState + 1; + _scrollText = _strFullText.Substring(_currentState, offset); + _strDialog = _strFullText.Substring(_currentState, _currentDialogCount); + + _currentState += offset; + _currentDialogCount -= offset; + } + else + { + _animator.Stop(); + _animator.Play("idle"); + + _boxEnd = false; + _running = false; + + if (!fastForward) + Game1.GameManager.PlaySoundEffect("D360-21-15"); + + return; + } + } + + if (!fastForward && !OwlMode && _running && _currentDialogCount % 6 == 0) + Game1.GameManager.PlaySoundEffect("D370-15-0F", true); + + if (!fastForward && OwlMode && _running && _currentDialogCount % 28 == 0) + Game1.GameManager.PlaySoundEffect("D370-25-19", true); + + _currentDialogCount++; + } + + public void ChoiceUpdate() + { + var newSelection = _currentChoiceSelection; + + var direction = ControlHandler.GetMoveVector2(); + var dir = AnimationHelper.GetDirection(direction); + + if (direction.Length() > Values.ControllerDeadzone && (dir == 0 || dir == 2)) + { + _selectionCounter -= Game1.DeltaTime; + + if (_selectionCounter <= 0) + { + _selectionCounter += SelectionTime; + + if (dir == 0) + newSelection--; + else if (dir == 2) + newSelection++; + } + } + else + { + _selectionCounter = 0; + } + + newSelection = MathHelper.Clamp(newSelection, 0, _choices.Length - 1); + + if (_currentChoiceSelection != newSelection) + { + _currentChoiceSelection = newSelection; + Game1.GameManager.PlaySoundEffect("D360-10-0A"); + } + } + + public void ResolutionChange() + { + _uiScale = Game1.UiScale; + SetUpDialogBox(); + } + + public void SetUpDialogBox() + { + // only works if every letter has the same size + _letterSize = new Point((int)Resources.GameFont.MeasureString("A").X, (int)Resources.GameFont.MeasureString("A").Y); + + _dialogBoxWidth = _letterSize.X * MaxCharacters + _paddingLeft + _paddingRight; + _dialogBoxHeight = _letterSize.Y * MaxLines + _paddingV * 2; + + _dialogBoxRectangle = new Rectangle( + Game1.WindowWidth / 2 - _dialogBoxWidth * _uiScale / 2, + Game1.WindowHeight - (_uiScale * _dialogBoxHeight) - _uiScale * _textboxMargin, _dialogBoxWidth * _uiScale, _dialogBoxHeight * _uiScale); + + DialogBoxTextBox = new Rectangle( + _dialogBoxRectangle.X + _paddingLeft * _uiScale, + _dialogBoxRectangle.Y + _paddingV * _uiScale, + _dialogBoxRectangle.Width - (_paddingLeft + _paddingRight) * _uiScale, + _dialogBoxRectangle.Height - (_paddingV * 2) * _uiScale); + + _textboxBackground.Rectangle = _dialogBoxRectangle; + + //_textboxBackgroundSide.Rectangle = new Rectangle( + // _dialogBoxRectangle.X - 2 * _uiScale, + // _dialogBoxRectangle.Y, 2 * _uiScale, _dialogBoxRectangle.Height); + } + + public void StartDialog(string dialogText) + { + _openDialog = true; + Game1.GameManager.SaveManager.SetString("dialogOpen", "1"); + + _currentLine = 0; + _currentLineAddition = MaxLines; + _currentState = 0; + _currentDialogCount = 0; + _textMult = 1; + + _strFullText = SetUpString(dialogText); + _textOffsetY = CalculateTextOffsetY(_strFullText); + + _strDialog = ""; + _end = false; + IsOpen = true; + _running = true; + + _isChoice = false; + ResetChoice(); + + // needs to be called to make sure to freeze the game directly after the dialog was started + UpdateGameState(); + } + + public void StartChoice(string choiceKey, string choiceText, params string[] choices) + { + _openDialog = true; + Game1.GameManager.SaveManager.SetString("dialogOpen", "1"); + + _currentLine = 0; + _currentLineAddition = MaxLines; + _currentState = 0; + _currentDialogCount = 0; + _textMult = 1; + + _choiceKey = choiceKey; + _strFullText = SetUpString(choiceText); + _textOffsetY = CalculateTextOffsetY(_strFullText); + _choices = choices; + + _strDialog = ""; + _end = false; + IsOpen = true; + _running = true; + + _isChoice = true; + ResetChoice(); + + // needs to be called to make sure to freeze the game directly after the dialog was started + UpdateGameState(); + } + + private void ResetChoice() + { + _choicePercentage = 0; + for (var i = 0; i < _textboxChoice.Length; i++) + { + _textboxChoice[i].Percentage = 0; + _textboxChoice[i].SelectionPercentage = 0; + + _textboxBackgroundChoice[i].BlurColor = Color.Transparent; + _textboxBackgroundChoice[i].BackgroundColor = Color.Transparent; + } + _currentChoiceSelection = 0; + _textboxChoice[0].SelectionPercentage = 1; + } + + public string ReplaceKeys(string inputString) + { + string outputString = inputString; + int openIndex; + int closeIndex; + + do + { + openIndex = inputString.IndexOf('['); + closeIndex = openIndex + 1; + if (openIndex != -1) + { + closeIndex = inputString.IndexOf(']', closeIndex + 1); + if (closeIndex != -1) + { + var stringKey = inputString.Substring(openIndex + 1, closeIndex - openIndex - 1); + var value = Game1.GameManager.SaveManager.GetString(stringKey); + if (value != null) + { + inputString = inputString.Remove(openIndex, closeIndex - openIndex + 1); + inputString = inputString.Insert(openIndex, value); + } + } + else + break; + } + } while (openIndex != -1); + + return outputString; + } + + public string SetUpString(string inputString) + { + // put in the players name + inputString = inputString.Replace("[NAME]", Game1.GameManager.SaveName); + + inputString = ReplaceKeys(inputString); + + return SetUpStringSplit(inputString); + } + + public int CalculateTextOffsetY(string inputString) + { + // center text if \f is used + var fIndex = inputString.IndexOf('\f', _currentState); + if (fIndex > 0) + inputString = inputString.Substring(_currentState, -_currentState + fIndex); + else + inputString = inputString.Substring(_currentState); + + var lineBreaks = inputString.Count(c => c == '\n'); + + if (lineBreaks < 2) + return ((MaxLines - lineBreaks - 1) * Resources.GameFontHeight) / 2; + else + return 0; + } + + public string SetUpStringSplit(string inputString) + { + if (inputString == null) + return "Error"; + + inputString = inputString.Replace("\\n", "\n"); + inputString = inputString.Replace("\\f", "\f"); + + var outString = ""; + var currentState = 0; + var lines = 0; + + while (currentState < inputString.Length) + { + lines++; + var subString = inputString.Substring(currentState, Math.Min(MaxCharacters, inputString.Length - currentState)); + + var indexN = subString.IndexOf('\n'); + var indexF = subString.IndexOf('\f'); + var indexC = subString.IndexOf("{"); + + indexN = indexN == -1 ? 999 : indexN; + indexF = indexF == -1 ? 999 : indexF; + indexC = indexC == -1 ? 999 : indexC; + + // add a new line + if (indexC != 999 && indexC < indexN && indexC < indexF) + { + // finish the line + if (indexC != 0) + { + outString += subString.Substring(0, indexC) + "\n"; + currentState += indexC; + continue; + } + + var closeIndex = subString.IndexOf('}', indexC); + if (closeIndex != -1) + { + var strCenter = subString.Substring(indexC + 1, closeIndex - (indexC + 1)); + for (var i = 0; i < (MaxCharacters - strCenter.Length) / 2; i++) + outString += " "; + + outString += strCenter; + // new line when there is still text and no new textbox + if (currentState + closeIndex + 1 < inputString.Length && + inputString[currentState + closeIndex + 1] != '\f') + outString += "\n"; + + currentState += closeIndex + 1; + } + else + { + // this should not happen + currentState += MaxCharacters; + outString += subString; + } + } + else if (indexN != 999 && indexN < indexC && indexN < indexF) + { + currentState = currentState + indexN + 1; + outString += subString.Substring(0, indexN + 1); + } + // add empty text + else if (indexF != 999) + { + currentState = currentState + indexF + 1; + outString += subString.Substring(0, indexF) + "\f"; + } + // finished? + else if (inputString.Length - currentState <= MaxCharacters) + { + outString += subString; + break; + } + else + { + // find a " " to add a line break + var splitString = false; + for (var i = 0; i < MaxCharacters; i++) + { + if (inputString[currentState + MaxCharacters - i] == ' ') + { + splitString = true; + outString += inputString.Substring(currentState, MaxCharacters - i) + "\n"; + currentState = currentState + MaxCharacters - i + 1; + break; + } + } + + if (!splitString) + { + outString += inputString.Substring(currentState, MaxCharacters) + "\n"; + currentState = currentState + MaxCharacters; + } + } + } + + return outString; + } + } +} diff --git a/InGame/Pages/AudioSettingsPage.cs b/InGame/Pages/AudioSettingsPage.cs new file mode 100644 index 0000000..7926d62 --- /dev/null +++ b/InGame/Pages/AudioSettingsPage.cs @@ -0,0 +1,67 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.Interface; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Pages +{ + class AudioSettingsPage : InterfacePage + { + private readonly InterfaceListLayout _bottomBar; + + public AudioSettingsPage(int width, int height) + { + // graphic settings layout + var graphicSettingsLayout = new InterfaceListLayout { Size = new Point(width, height), Selectable = true }; + + var buttonWidth = 240; + + graphicSettingsLayout.AddElement(new InterfaceLabel(Resources.GameHeaderFont, "settings_audio_header", + new Point(buttonWidth, (int)(height * Values.MenuHeaderSize)), new Point(0, 0))); + + var contentLayout = new InterfaceListLayout { Size = new Point(width, (int)(height * Values.MenuContentSize)), Selectable = true, ContentAlignment = InterfaceElement.Gravities.Top }; + + contentLayout.AddElement(new InterfaceSlider(Resources.GameFont, "settings_audio_music_volume", + buttonWidth, new Point(1, 2), 0, 100, 5, GameSettings.MusicVolume, number => { GameSettings.MusicVolume = number; }) + { SetString = number => " " + number + "%" }); + + contentLayout.AddElement(new InterfaceSlider(Resources.GameFont, "settings_audio_effect_volume", + buttonWidth, new Point(1, 2), 0, 100, 5, GameSettings.EffectVolume, number => { GameSettings.EffectVolume = number; }) + { SetString = number => " " + number + "%" }); + + graphicSettingsLayout.AddElement(contentLayout); + + _bottomBar = new InterfaceListLayout() { Size = new Point(width, (int)(height * Values.MenuFooterSize)), Selectable = true, HorizontalMode = true }; + // back button + _bottomBar.AddElement(new InterfaceButton(new Point(60, 20), new Point(2, 4), "settings_menu_back", element => + { + Game1.UiPageManager.PopPage(); + })); + + graphicSettingsLayout.AddElement(_bottomBar); + + PageLayout = graphicSettingsLayout; + } + + public override void Update(CButtons pressedButtons, GameTime gameTime) + { + base.Update(pressedButtons, gameTime); + + // close the page + if (ControlHandler.ButtonPressed(CButtons.B)) + Game1.UiPageManager.PopPage(); + } + + public override void OnLoad(Dictionary intent) + { + // the left button is always the first one selected + _bottomBar.Deselect(false); + _bottomBar.Select(InterfaceElement.Directions.Left, false); + _bottomBar.Deselect(false); + + PageLayout.Deselect(false); + PageLayout.Select(InterfaceElement.Directions.Top, false); + } + } +} diff --git a/InGame/Pages/ControlSettingsPage.cs b/InGame/Pages/ControlSettingsPage.cs new file mode 100644 index 0000000..1aeaa14 --- /dev/null +++ b/InGame/Pages/ControlSettingsPage.cs @@ -0,0 +1,180 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; +using ProjectZ.Base; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.Interface; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Pages +{ + class ControlSettingsPage : InterfacePage + { + private readonly InterfaceListLayout[] _remapButtons; + private readonly InterfaceListLayout _bottomBar; + + private CButtons _selectedButton; + private bool _updateButton; + + public ControlSettingsPage(int width, int height) + { + // control settings layout + var controlLayout = new InterfaceListLayout { Size = new Point(width, height), Selectable = true }; + + controlLayout.AddElement(new InterfaceLabel(Resources.GameHeaderFont, "settings_controls_header", + new Point(width - 50, (int)(height * Values.MenuHeaderSize)), new Point(0, 0))); + + var controllerHeight = (int)(height * Values.MenuContentSize); + + var buttonWidth = 65; + var lableWidth = 90; + var lableHeight = 12; + var headerHeight = 14; + + var remapHeader = new InterfaceListLayout { AutoSize = true, Margin = new Point(0, 1), HorizontalMode = true, CornerRadius = 0, Color = Values.MenuButtonColor }; + remapHeader.AddElement(new InterfaceListLayout() { Size = new Point(buttonWidth, headerHeight) }); + remapHeader.AddElement(new InterfaceLabel("settings_controls_keyboad", new Point(lableWidth, headerHeight), new Point(0, 0))); + remapHeader.AddElement(new InterfaceLabel("settings_controls_gamepad", new Point(lableWidth, headerHeight), new Point(0, 0))); + controlLayout.AddElement(remapHeader); + + var remapButtons = new InterfaceListLayout { AutoSize = true, Margin = new Point(2, 0), Selectable = true }; + + _remapButtons = new InterfaceListLayout[Enum.GetValues(typeof(CButtons)).Length - 1]; + var index = 0; + + foreach (CButtons eButton in Enum.GetValues(typeof(CButtons))) + { + if (eButton == CButtons.None) + continue; + + _remapButtons[index] = new InterfaceListLayout { Size = new Point(buttonWidth + lableWidth * 2, lableHeight), HorizontalMode = true }; + _remapButtons[index].AddElement(new InterfaceLabel("settings_controls_" + eButton, new Point(buttonWidth, lableHeight), Point.Zero) + { CornerRadius = 0, Color = Values.MenuButtonColor }); + _remapButtons[index].AddElement(new InterfaceLabel("error", new Point(lableWidth, lableHeight), new Point(0, 0)) { Translate = false }); + _remapButtons[index].AddElement(new InterfaceLabel("error", new Point(lableWidth, lableHeight), new Point(0, 0)) { Translate = false }); + + var remapButton = new InterfaceButton(new Point(buttonWidth + lableWidth * 2, lableHeight), new Point(0, 0), _remapButtons[index], + element => + { + _updateButton = true; + _selectedButton = eButton; + }) + { CornerRadius = 0, Color = Color.Transparent }; + + remapButtons.AddElement(remapButton); + remapButtons.AddElement(new InterfaceListLayout() { Size = new Point(1, 1) }); + + index++; + } + + controlLayout.AddElement(remapButtons); + + _bottomBar = new InterfaceListLayout { Size = new Point(width - 50, (int)(height * Values.MenuFooterSize)), HorizontalMode = true, Selectable = true }; + // reset button + _bottomBar.AddElement(new InterfaceButton(new Point(60, 20), new Point(2, 4), "settings_controls_reset", OnClickReset)); + // back button + _bottomBar.AddElement(new InterfaceButton(new Point(60, 20), new Point(2, 4), "settings_menu_back", element => + { + Game1.UiPageManager.PopPage(); + })); + controlLayout.AddElement(_bottomBar); + + PageLayout = controlLayout; + + UpdateUi(); + } + + public override void OnLoad(Dictionary intent) + { + // the left button is always the first one selected + _bottomBar.Deselect(false); + _bottomBar.Select(InterfaceElement.Directions.Right, false); + _bottomBar.Deselect(false); + + PageLayout.Deselect(false); + PageLayout.Select(InterfaceElement.Directions.Top, false); + } + + public override void Update(CButtons pressedButtons, GameTime gameTime) + { + if (_updateButton) + { + // update the selected button binding + var pressedKeys = InputHandler.GetPressedKeys(); + if (pressedKeys.Count > 0) + { + _updateButton = false; + UpdateKeyboard(_selectedButton, pressedKeys[0]); + UpdateUi(); + } + + var pressedGamepadButtons = InputHandler.GetPressedButtons(); + if (pressedGamepadButtons.Count > 0) + { + _updateButton = false; + UpdateButton(_selectedButton, pressedGamepadButtons[0]); + UpdateUi(); + } + + InputHandler.ResetInputState(); + } + else + { + // needs to be after the update button stuff + base.Update(pressedButtons, gameTime); + + // close the page + if (ControlHandler.ButtonPressed(CButtons.B)) + Game1.UiPageManager.PopPage(); + } + } + + public void UpdateUi() + { + var buttonNr = 0; + + foreach (var bEntry in ControlHandler.ButtonDictionary) + { + var str = ""; + + for (var j = 0; j < bEntry.Value.Keys.Length; j++) + str += bEntry.Value.Keys[j]; + ((InterfaceLabel)_remapButtons[buttonNr].Elements[1]).SetText(str); + + str = " "; + for (var j = 0; j < bEntry.Value.Buttons.Length; j++) + str += bEntry.Value.Buttons[j]; + ((InterfaceLabel)_remapButtons[buttonNr].Elements[2]).SetText(str); + + buttonNr++; + } + } + + private void UpdateKeyboard(CButtons buttonIndex, Keys newKey) + { + foreach (var button in ControlHandler.ButtonDictionary) + if (button.Value.Keys[0] == newKey && button.Key != buttonIndex) + button.Value.Keys[0] = ControlHandler.ButtonDictionary[_selectedButton].Keys[0]; + + ControlHandler.ButtonDictionary[_selectedButton].Keys = new Keys[] { newKey }; + } + + private void UpdateButton(CButtons buttonIndex, Buttons newButton) + { + foreach (var button in ControlHandler.ButtonDictionary) + if (button.Value.Buttons[0] == newButton && button.Key != buttonIndex) + button.Value.Buttons[0] = ControlHandler.ButtonDictionary[_selectedButton].Buttons[0]; + + ControlHandler.ButtonDictionary[_selectedButton].Buttons = new Buttons[] { newButton }; + } + + private void OnClickReset(InterfaceElement element) + { + ControlHandler.ResetControlls(); + UpdateUi(); + + InputHandler.ResetInputState(); + } + } +} diff --git a/InGame/Pages/CopyConfirmationPage.cs b/InGame/Pages/CopyConfirmationPage.cs new file mode 100644 index 0000000..5a51838 --- /dev/null +++ b/InGame/Pages/CopyConfirmationPage.cs @@ -0,0 +1,65 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.Interface; + +namespace ProjectZ.InGame.Pages +{ + class CopyConfirmationPage : InterfacePage + { + private InterfaceListLayout _confirmLayout; + + public CopyConfirmationPage(int width, int height) + { + // delete save confirm + { + _confirmLayout = new InterfaceListLayout { Size = new Point(width, height), Selectable = true }; + _confirmLayout.AddElement(new InterfaceButton(new Point(170, 36), new Point(5, 5), "main_menu_copy_confirmation_header", null) { Selectable = false }); + + var yesNoLayout = new InterfaceListLayout { Size = new Point(200, 30), HorizontalMode = true, Selectable = true }; + yesNoLayout.AddElement(new InterfaceButton(new Point(82, 26), new Point(3, 0), "main_menu_copy_confirmation_header_yes", element => OnClickDeleteYes())); + yesNoLayout.AddElement(new InterfaceButton(new Point(82, 26), new Point(3, 0), "main_menu_copy_confirmation_header_no", element => OnClickDeleteNo())); + _confirmLayout.AddElement(yesNoLayout); + } + + PageLayout = _confirmLayout; + } + + public override void OnLoad(Dictionary intent) + { + base.OnLoad(intent); + + _confirmLayout.Deselect(false); + _confirmLayout.Select(InterfaceElement.Directions.Right, false); + } + + public override void Update(CButtons pressedButtons, GameTime gameTime) + { + base.Update(pressedButtons, gameTime); + + if (ControlHandler.ButtonPressed(CButtons.B)) + Abort(); + } + + private void OnClickDeleteYes() + { + var intent = new Dictionary(); + intent.Add("copyFile", true); + + Game1.UiPageManager.PopPage(intent, PageManager.TransitionAnimation.Fade, PageManager.TransitionAnimation.Fade); + } + + private void OnClickDeleteNo() + { + Abort(); + } + + private void Abort() + { + var intent = new Dictionary(); + intent.Add("copyFile", false); + + Game1.UiPageManager.PopPage(intent, PageManager.TransitionAnimation.Fade, PageManager.TransitionAnimation.Fade); + } + } +} diff --git a/InGame/Pages/CopyPage.cs b/InGame/Pages/CopyPage.cs new file mode 100644 index 0000000..39e6b0c --- /dev/null +++ b/InGame/Pages/CopyPage.cs @@ -0,0 +1,215 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.Interface; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Pages +{ + class CopyPage : InterfacePage + { + private InterfaceListLayout[] _fromSaveSlot = new InterfaceListLayout[SaveStateManager.SaveCount]; + private InterfaceLabel[] _saveFromNames = new InterfaceLabel[SaveStateManager.SaveCount]; + + private InterfaceListLayout[] _toSaveSlot = new InterfaceListLayout[SaveStateManager.SaveCount]; + private InterfaceLabel[] _saveToNames = new InterfaceLabel[SaveStateManager.SaveCount]; + + private int _sourceSlotIndex; + private int _targetSlotIndex; + + public CopyPage(int width, int height) + { + var saveButtonRec = new Point(120, 22); + + // main layout + var _mainLayout = new InterfaceListLayout { Size = new Point(width, height), Gravity = InterfaceElement.Gravities.Left, Selectable = true }; + _mainLayout.AddElement(new InterfaceLabel(Resources.GameHeaderFont, "main_menu_copy_header", new Point(width, (int)(height * Values.MenuHeaderSize)), new Point(0, 0))); + + var fromToLayout = new InterfaceListLayout() { Size = new Point(width, (int)(height * Values.MenuContentSize)), HorizontalMode = true, Selectable = true }; + + // list of all save files + { + var fromSaveSlot = new InterfaceListLayout() { Size = new Point(saveButtonRec.X, (int)(height * Values.MenuContentSize)) }; + fromSaveSlot.AddElement(new InterfaceLabel("main_menu_copy_from")); + for (var i = 0; i < SaveStateManager.SaveCount; i++) + { + var _saveButtonLayouts = new InterfaceGravityLayout { Size = new Point(saveButtonRec.X, saveButtonRec.Y) }; + + var numberWidth = 17; + var saveSlotNumber = new InterfaceLabel(null, new Point(numberWidth, 12), Point.Zero) + { Gravity = InterfaceElement.Gravities.Left, TextAlignment = InterfaceElement.Gravities.Center | InterfaceElement.Gravities.Bottom }; + saveSlotNumber.SetText((i + 1).ToString()); + + _saveButtonLayouts.AddElement(saveSlotNumber); + + var saveInfoLayout = new InterfaceListLayout { HorizontalMode = true, Size = new Point(saveButtonRec.X - numberWidth, saveButtonRec.Y), Gravity = InterfaceElement.Gravities.Right }; + + // name on the right + { + var rightWidth = saveButtonRec.X - numberWidth; + var middle = new InterfaceListLayout { Gravity = InterfaceElement.Gravities.Left, Margin = new Point(2, 0), Size = new Point(rightWidth, 30) }; + + // name + middle.AddElement(_saveFromNames[i] = new InterfaceLabel(null, new Point(rightWidth - 3, 12), Point.Zero) { Margin = new Point(1, 0), TextAlignment = InterfaceElement.Gravities.Left | InterfaceElement.Gravities.Bottom }); + + saveInfoLayout.AddElement(middle); + } + + _saveButtonLayouts.AddElement(saveInfoLayout); + + var _saveButtons = new InterfaceButton + { + InsideElement = _saveButtonLayouts, + Size = new Point(saveButtonRec.X, saveButtonRec.Y), + Margin = new Point(0, 2) + }; + + _fromSaveSlot[i] = new InterfaceListLayout { HorizontalMode = true, Gravity = InterfaceElement.Gravities.Right, AutoSize = true }; + + // save file + _fromSaveSlot[i].AddElement(_saveButtons); + + // add save button to the main layout + fromSaveSlot.AddElement(_fromSaveSlot[i]); + } + fromToLayout.AddElement(fromSaveSlot); + + fromToLayout.AddElement(new InterfaceLabel("main_menu_copy_arrow") { Size = new Point(6, 7), Margin = new Point(10, 10) }); + + var toSaveSlot = new InterfaceListLayout() { Size = new Point(saveButtonRec.X, (int)(height * Values.MenuContentSize)), Selectable = true }; + toSaveSlot.AddElement(new InterfaceLabel("main_menu_copy_to")); + for (var i = 0; i < SaveStateManager.SaveCount; i++) + { + var _saveButtonLayouts = new InterfaceGravityLayout { Size = new Point(saveButtonRec.X, saveButtonRec.Y) }; + + var numberWidth = 17; + var saveSlotNumber = new InterfaceLabel(null, new Point(numberWidth, 12), Point.Zero) + { Gravity = InterfaceElement.Gravities.Left, TextAlignment = InterfaceElement.Gravities.Center | InterfaceElement.Gravities.Bottom }; + saveSlotNumber.SetText((i + 1).ToString()); + + _saveButtonLayouts.AddElement(saveSlotNumber); + + var saveInfoLayout = new InterfaceListLayout { HorizontalMode = true, Size = new Point(saveButtonRec.X - numberWidth, saveButtonRec.Y), Gravity = InterfaceElement.Gravities.Right }; + + // name on the right + { + var rightWidth = saveButtonRec.X - numberWidth; + var middle = new InterfaceListLayout { Gravity = InterfaceElement.Gravities.Left, Margin = new Point(2, 0), Size = new Point(rightWidth, 30) }; + + // name + middle.AddElement(_saveToNames[i] = new InterfaceLabel(null, new Point(rightWidth - 3, 12), Point.Zero) { Margin = new Point(1, 0), TextAlignment = InterfaceElement.Gravities.Left | InterfaceElement.Gravities.Bottom }); + + saveInfoLayout.AddElement(middle); + } + + _saveButtonLayouts.AddElement(saveInfoLayout); + + var slotIndex = i; + var _saveButtons = new InterfaceButton + { + InsideElement = _saveButtonLayouts, + Size = new Point(saveButtonRec.X, saveButtonRec.Y), + Margin = new Point(0, 2), + ClickFunction = (InterfaceElement element) => OnSelectSave(slotIndex) + }; + + _toSaveSlot[i] = new InterfaceListLayout { HorizontalMode = true, Gravity = InterfaceElement.Gravities.Right, AutoSize = true, Selectable = true }; + + // save file + _toSaveSlot[i].AddElement(_saveButtons); + + // add save button to the main layout + toSaveSlot.AddElement(_toSaveSlot[i]); + } + fromToLayout.AddElement(toSaveSlot); + + _mainLayout.AddElement(fromToLayout); + } + + // menu bottom bar + { + var menuBottomBar = new InterfaceListLayout + { + Size = new Point(saveButtonRec.X, (int)(height * Values.MenuFooterSize)), + HorizontalMode = true, + Selectable = true + }; + + // back button + menuBottomBar.AddElement(new InterfaceButton(new Point(60, 20), new Point(2, 4), "main_menu_copy_back", element => Abort())); + + _mainLayout.AddElement(menuBottomBar); + } + + PageLayout = _mainLayout; + } + + public override void OnLoad(Dictionary intent) + { + if (intent != null && intent.TryGetValue("selectedSlot", out var selectedSlot)) + { + _sourceSlotIndex = (int)selectedSlot; + } + + UpdateUi(); + + PageLayout.Deselect(false); + PageLayout.Select(InterfaceElement.Directions.Top, false); + } + + public override void OnReturn(Dictionary intent) + { + base.OnReturn(intent); + + // copy file? + if (intent != null && intent.TryGetValue("copyFile", out var copyFile) && (bool)copyFile) + { + var popIntent = new Dictionary(); + popIntent.Add("copyTargetSlot", _targetSlotIndex); + + Game1.UiPageManager.PopPage(popIntent, PageManager.TransitionAnimation.Fade, PageManager.TransitionAnimation.Fade); + } + } + + public override void Update(CButtons pressedButtons, GameTime gameTime) + { + base.Update(pressedButtons, gameTime); + + if (ControlHandler.ButtonPressed(CButtons.B)) + Abort(); + } + + private void Abort() + { + Game1.UiPageManager.PopPage(null, PageManager.TransitionAnimation.Fade, PageManager.TransitionAnimation.Fade); + } + + private void OnSelectSave(int slotIndex) + { + _targetSlotIndex = slotIndex; + + Game1.UiPageManager.ChangePage(typeof(CopyConfirmationPage), null, PageManager.TransitionAnimation.Fade, PageManager.TransitionAnimation.Fade); + } + + private void UpdateUi() + { + for (var i = 0; i < SaveStateManager.SaveCount; i++) + { + var slotName = SaveStateManager.SaveStates[i] == null ? + Game1.LanguageManager.GetString("main_menu_copy_empty", "error") : SaveStateManager.SaveStates[i].Name; + + // only show the selected slot + if (i == _sourceSlotIndex) + { + _fromSaveSlot[i].Select(InterfaceElement.Directions.Left, false); + _saveFromNames[i].SetText(slotName); + } + _fromSaveSlot[i].Visible = i == _sourceSlotIndex; + + _toSaveSlot[i].Visible = i != _sourceSlotIndex; + _saveToNames[i].SetText(slotName); + } + } + } +} diff --git a/InGame/Pages/DeleteSaveSlotPage.cs b/InGame/Pages/DeleteSaveSlotPage.cs new file mode 100644 index 0000000..bf88cd5 --- /dev/null +++ b/InGame/Pages/DeleteSaveSlotPage.cs @@ -0,0 +1,66 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.Interface; + +namespace ProjectZ.InGame.Pages +{ + class DeleteSaveSlotPage : InterfacePage + { + private InterfaceListLayout _confirmLayout; + + public DeleteSaveSlotPage(int width, int height) + { + // delete save confirm + { + _confirmLayout = new InterfaceListLayout { Size = new Point(width, height), Selectable = true }; + _confirmLayout.AddElement(new InterfaceButton(new Point(170, 36), new Point(5, 5), "main_menu_delete_confirmation_header", null) { Selectable = false }); + + var yesNoLayout = new InterfaceListLayout { Size = new Point(200, 30), HorizontalMode = true, Selectable = true }; + yesNoLayout.AddElement(new InterfaceButton(new Point(82, 26), new Point(3, 0), "main_menu_delete_confirmation_header_yes", element => OnClickDeleteYes())); + yesNoLayout.AddElement(new InterfaceButton(new Point(82, 26), new Point(3, 0), "main_menu_delete_confirmation_header_no", element => OnClickDeleteNo())); + _confirmLayout.AddElement(yesNoLayout); + } + + PageLayout = _confirmLayout; + } + + public override void OnLoad(Dictionary intent) + { + base.OnLoad(intent); + + _confirmLayout.Deselect(false); + _confirmLayout.Select(InterfaceElement.Directions.Right, false); + } + + public override void Update(CButtons pressedButtons, GameTime gameTime) + { + base.Update(pressedButtons, gameTime); + + if (ControlHandler.ButtonPressed(CButtons.B)) + Abort(); + } + + private void OnClickDeleteYes() + { + var intent = new Dictionary(); + intent.Add("deleteReturn", true); + intent.Add("deleteSavestate", true); + + Game1.UiPageManager.PopPage(intent, PageManager.TransitionAnimation.Fade, PageManager.TransitionAnimation.Fade); + } + + private void OnClickDeleteNo() + { + Abort(); + } + + private void Abort() + { + var intent = new Dictionary(); + intent.Add("deleteReturn", true); + + Game1.UiPageManager.PopPage(intent, PageManager.TransitionAnimation.Fade, PageManager.TransitionAnimation.Fade); + } + } +} diff --git a/InGame/Pages/ExitGamePage.cs b/InGame/Pages/ExitGamePage.cs new file mode 100644 index 0000000..03b679a --- /dev/null +++ b/InGame/Pages/ExitGamePage.cs @@ -0,0 +1,68 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.Interface; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Pages +{ + class ExitGamePage : InterfacePage + { + public ExitGamePage(int width, int height) + { + var margin = 6; + + // yes no layout + var yesNoLayoutInside = new InterfaceListLayout() { Size = new Point(150 + margin * 2, 55), Selectable = true }; + yesNoLayoutInside.AddElement(new InterfaceLabel(Resources.GameHeaderFont, "game_menu_exit_header", new Point(150, 30), new Point(1, 2)) { TextColor = Color.White }); + var hLayout = new InterfaceListLayout() { Size = new Point(150, 25), Margin = new Point(0, 2), Selectable = true, HorizontalMode = true }; + hLayout.AddElement(new InterfaceButton(new Point(74, 25), Point.Zero, "game_menu_exit_yes", OnClickYes) { Margin = new Point(2, 0) }); + hLayout.AddElement(new InterfaceButton(new Point(74, 25), Point.Zero, "game_menu_exit_no", OnClickNo) { Margin = new Point(2, 0) }); + yesNoLayoutInside.AddElement(hLayout); + + var yesNoLayout = new InterfaceListLayout() { Size = new Point(width, height), Selectable = true }; + yesNoLayout.AddElement(yesNoLayoutInside); + + PageLayout = yesNoLayout; + } + + public override void Update(CButtons pressedButtons, GameTime gameTime) + { + base.Update(pressedButtons, gameTime); + + // close the page + if (ControlHandler.ButtonPressed(CButtons.B)) + Game1.UiPageManager.PopPage(); + } + + public override void OnLoad(Dictionary intent) + { + // select the "Back to Game" button + PageLayout.Deselect(false); + PageLayout.Select(InterfaceElement.Directions.Right, false); + } + + public void OnClickNo(InterfaceElement element) + { + // go to the previous page + Game1.UiPageManager.PopPage(); + } + + public void OnClickYes(InterfaceElement element) + { + // if we are in a sequnece we make sure to revert the changes made in the sequence + if (Game1.GameManager.SaveManager.HistoryEnabled) + { + Game1.GameManager.SaveManager.RevertHistory(); + Game1.GameManager.SaveManager.DisableHistory(); + } + + // save the game on exit + SaveGameSaveLoad.SaveGame(Game1.GameManager); + + Game1.ScreenManager.ChangeScreen(Values.ScreenNameMenu); + } + } +} diff --git a/InGame/Pages/GameMenuPage.cs b/InGame/Pages/GameMenuPage.cs new file mode 100644 index 0000000..dcdb001 --- /dev/null +++ b/InGame/Pages/GameMenuPage.cs @@ -0,0 +1,76 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.Interface; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Pages +{ + class GameMenuPage : InterfacePage + { + public GameMenuPage(int width, int height) + { + // main layout + var mainLayout = new InterfaceListLayout() { Size = new Point(width, height), Selectable = true }; + + mainLayout.AddElement(new InterfaceLabel(Resources.GameHeaderFont, "game_menu_header", + new Point(150, (int)(height * Values.MenuHeaderSize)), new Point(0, 0)) + { TextColor = Color.White }); + + // Size = new Point(width, (int)(height * Values.MenuContentSize)) + var contentLayout = new InterfaceListLayout { AutoSize = true, Selectable = true }; + + contentLayout.AddElement(new InterfaceButton(new Point(150, 25), Point.Zero, "game_menu_back_to_game", e => ClosePage()) { Margin = new Point(0, 2) }); + contentLayout.AddElement(new InterfaceButton(new Point(150, 25), Point.Zero, "game_menu_settings", OnClickSettings) { Margin = new Point(0, 2) }); + contentLayout.AddElement(new InterfaceButton(new Point(150, 25), Point.Zero, "game_menu_exit_to_the_menu", OnClickBackToMenu) { Margin = new Point(0, 2) }); + + mainLayout.AddElement(contentLayout); + + mainLayout.AddElement(new InterfaceListLayout { Size = new Point(width, (int)(height * Values.MenuFooterSize)) }); + + PageLayout = mainLayout; + PageLayout.Select(InterfaceElement.Directions.Top, false); + } + + public override void OnLoad(Dictionary intent) + { + Game1.GbsPlayer.Pause(); + + // select the "Back to Game" button + PageLayout.Deselect(false); + PageLayout.Select(InterfaceElement.Directions.Top, false); + } + + public override void OnPop(Dictionary intent) + { + Game1.GbsPlayer.Resume(); + } + + public override void Update(CButtons pressedButtons, GameTime gameTime) + { + base.Update(pressedButtons, gameTime); + + // close the page + if (ControlHandler.ButtonPressed(CButtons.Start) || + ControlHandler.ButtonPressed(CButtons.Left) || + ControlHandler.ButtonPressed(CButtons.B)) + ClosePage(); + } + + private void ClosePage() + { + Game1.GameManager.InGameOverlay.CloseOverlay(); + } + + public void OnClickSettings(InterfaceElement element) + { + Game1.UiPageManager.ChangePage(typeof(SettingsPage)); + } + + public void OnClickBackToMenu(InterfaceElement element) + { + // show the yes no layout + Game1.UiPageManager.ChangePage(typeof(ExitGamePage)); + } + } +} diff --git a/InGame/Pages/GameOverPage.cs b/InGame/Pages/GameOverPage.cs new file mode 100644 index 0000000..6105894 --- /dev/null +++ b/InGame/Pages/GameOverPage.cs @@ -0,0 +1,75 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameSystems; +using ProjectZ.InGame.Interface; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Pages +{ + class GameOverPage : InterfacePage + { + private InterfaceListLayout _pageLayout; + private InterfaceListLayout _layout0; + + public GameOverPage(int width, int height) + { + _pageLayout = new InterfaceListLayout { Size = new Point(width, height), Selectable = true }; + + _layout0 = new InterfaceListLayout { Size = new Point(width, 75), ContentAlignment = InterfaceElement.Gravities.Bottom }; + var layout1 = new InterfaceListLayout { Size = new Point(width - 10, 55) }; + var layout2 = new InterfaceListLayout { Size = new Point(width, 75), ContentAlignment = InterfaceElement.Gravities.Top, Selectable = true }; + + _pageLayout.AddElement(_layout0); + _pageLayout.AddElement(layout1); + _pageLayout.AddElement(layout2); + + // yes no layout + _layout0.AddElement(new InterfaceImage(Resources.GetSprite("ui game over"), Point.Zero)); + layout2.AddElement(new InterfaceButton(new Point(85, 20), Point.Zero, "gameover_continue", OnClickContinue) { Margin = new Point(2, 2) }); + layout2.AddElement(new InterfaceButton(new Point(85, 20), Point.Zero, "gameover_quit", OnClickQuit) { Margin = new Point(2, 2) }); + + PageLayout = _pageLayout; + } + + public override void OnLoad(Dictionary intent) + { + // select the "Back to Game" button + PageLayout.Deselect(false); + PageLayout.Select(InterfaceElement.Directions.Top, false); + + Game1.GameManager.ResetMusic(); + Game1.GameManager.SetMusic(2, 0); + + Game1.GbsPlayer.SetVolumeMultiplier(1.0f); + Game1.GbsPlayer.Play(); + + _pageLayout.Recalculate = true; + + _layout0.Recalculate = true; + _layout0.Size.Y = 75 - (int)(MapManager.Camera.Scale * 2); + } + + public void OnClickContinue(InterfaceElement element) + { + Game1.UiPageManager.ClearStack(); + Game1.ScreenManager.ChangeScreen(Values.ScreenNameGame); + + ((GameOverSystem)Game1.GameManager.GameSystems[typeof(GameOverSystem)]).EndSystem(); + + Game1.GameManager.RespawnPlayer(); + } + + public void OnClickQuit(InterfaceElement element) + { + ((GameOverSystem)Game1.GameManager.GameSystems[typeof(GameOverSystem)]).EndSystem(); + Game1.ScreenManager.ChangeScreen(Values.ScreenNameMenu); + } + + public override void Draw(SpriteBatch spriteBatch, Vector2 position, int scale, float transparency) + { + PageLayout?.Draw(spriteBatch, position, scale, transparency); + } + } +} diff --git a/InGame/Pages/GameSettingsPage.cs b/InGame/Pages/GameSettingsPage.cs new file mode 100644 index 0000000..3b12e7d --- /dev/null +++ b/InGame/Pages/GameSettingsPage.cs @@ -0,0 +1,77 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.Interface; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Pages +{ + class GameSettingsPage : InterfacePage + { + private readonly InterfaceListLayout _bottomBar; + + public GameSettingsPage(int width, int height) + { + // graphic settings layout + var gameSettingsList = new InterfaceListLayout { Size = new Point(width, height), Selectable = true }; + var buttonWidth = 240; + + gameSettingsList.AddElement(new InterfaceLabel(Resources.GameHeaderFont, "settings_game_header", + new Point(buttonWidth, (int)(height * Values.MenuHeaderSize)), new Point(0, 0))); + + var contentLayout = new InterfaceListLayout { Size = new Point(width, (int)(height * Values.MenuContentSize)), Selectable = true, ContentAlignment = InterfaceElement.Gravities.Top }; + + contentLayout.AddElement(new InterfaceSlider(Resources.GameFont, "settings_audio_music_volume", + buttonWidth, new Point(1, 2), 0, 100, 5, GameSettings.MusicVolume, number => { GameSettings.MusicVolume = number; }) + { SetString = number => " " + number + "%" }); + + contentLayout.AddElement(new InterfaceSlider(Resources.GameFont, "settings_audio_effect_volume", + buttonWidth, new Point(1, 2), 0, 100, 5, GameSettings.EffectVolume, number => { GameSettings.EffectVolume = number; }) + { SetString = number => " " + number + "%" }); + + contentLayout.AddElement(new InterfaceButton(new Point(buttonWidth, 18), new Point(0, 2), "settings_game_language", PressButtonLanguageChange)); + + var toggleAutosave = InterfaceToggle.GetToggleButton(new Point(buttonWidth, 18), new Point(5, 2), + "settings_game_autosave", GameSettings.Autosave, newState => { GameSettings.Autosave = newState; }); + contentLayout.AddElement(toggleAutosave); + + gameSettingsList.AddElement(contentLayout); + + _bottomBar = new InterfaceListLayout() { Size = new Point(width, (int)(height * Values.MenuFooterSize)), Selectable = true, HorizontalMode = true }; + // back button + _bottomBar.AddElement(new InterfaceButton(new Point(60, 20), new Point(2, 4), "settings_menu_back", element => + { + Game1.UiPageManager.PopPage(); + })); + + gameSettingsList.AddElement(_bottomBar); + + PageLayout = gameSettingsList; + } + + public override void Update(CButtons pressedButtons, GameTime gameTime) + { + base.Update(pressedButtons, gameTime); + + // close the page + if (ControlHandler.ButtonPressed(CButtons.B)) + Game1.UiPageManager.PopPage(); + } + + public override void OnLoad(Dictionary intent) + { + // the left button is always the first one selected + _bottomBar.Deselect(false); + _bottomBar.Select(InterfaceElement.Directions.Left, false); + _bottomBar.Deselect(false); + + PageLayout.Deselect(false); + PageLayout.Select(InterfaceElement.Directions.Top, false); + } + + public void PressButtonLanguageChange(InterfaceElement element) + { + Game1.LanguageManager.ToggleLanguage(); + } + } +} diff --git a/InGame/Pages/GraphicSettingsPage.cs b/InGame/Pages/GraphicSettingsPage.cs new file mode 100644 index 0000000..f7366c9 --- /dev/null +++ b/InGame/Pages/GraphicSettingsPage.cs @@ -0,0 +1,132 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.Interface; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Pages +{ + class GraphicSettingsPage : InterfacePage + { + private readonly InterfaceListLayout _bottomBar; + private readonly InterfaceListLayout _toggleFullscreen; + + //private InterfaceSlider _uiScaleSlider; + + public GraphicSettingsPage(int width, int height) + { + // graphic settings layout + var _graphicSettingsLayout = new InterfaceListLayout { Size = new Point(width, height), Selectable = true }; + + var buttonWidth = 240; + + _graphicSettingsLayout.AddElement(new InterfaceLabel(Resources.GameHeaderFont, "settings_graphics_header", + new Point(buttonWidth, (int)(height * Values.MenuHeaderSize)), new Point(0, 0))); + + var contentLayout = new InterfaceListLayout { Size = new Point(width, (int)(height * Values.MenuContentSize)), Selectable = true, ContentAlignment = InterfaceElement.Gravities.Top }; + + contentLayout.AddElement(new InterfaceSlider(Resources.GameFont, "settings_graphics_game_scale", + buttonWidth, new Point(1, 2), -1, 11, 1, GameSettings.GameScale + 1, + number => + { + GameSettings.GameScale = number; + Game1.ScaleSettingChanged = true; + }) + { SetString = number => GameSettings.GameScale == 11 ? "auto" : " x" + (number < 1 ? "1/" + (2 - number) : number.ToString()) }); + + //contentLayout.AddElement(_uiScaleSlider = new InterfaceSlider(Resources.GameFont, "settings_graphics_ui_scale", + // buttonWidth, new Point(1, 2), 1, Game1.ScreenScale + 1, 1, GameSettings.UiScale - 1, + // number => + // { + // GameSettings.UiScale = number >= Game1.ScreenScale + 1 ? 0 : number; + // Game1.ScaleSettingChanged = true; + // }) + //{ SetString = number => GameSettings.UiScale == 0 ? "auto" : " x" + number }); + + _toggleFullscreen = InterfaceToggle.GetToggleButton(new Point(buttonWidth, 18), new Point(5, 2), + "settings_game_fullscreen_mode", GameSettings.IsFullscreen, newState => { Game1.ToggleFullscreen(); }); + contentLayout.AddElement(_toggleFullscreen); + + var toggleFullscreenWindowed = InterfaceToggle.GetToggleButton(new Point(buttonWidth, 18), new Point(5, 2), + "settings_game_fullscreen_windowed", GameSettings.BorderlessWindowed, newState => { Game1.SwitchFullscreenWindowedSetting(); }); + contentLayout.AddElement(toggleFullscreenWindowed); + + // not sure why this should be an option; but if this should be settable then we need to still enable circular shadows (e.g. under the player) + //var shadowToggle = InterfaceToggle.GetToggleButton(new Point(buttonWidth, 18), new Point(5, 2), + // "settings_graphics_shadow", GameSettings.EnableShadows, newState => GameSettings.EnableShadows = newState); + //contentLayout.AddElement(shadowToggle); + + var toggleFpsLock = InterfaceToggle.GetToggleButton(new Point(buttonWidth, 18), new Point(5, 2), + "settings_graphics_fps_lock", GameSettings.LockFps, newState => + { + GameSettings.LockFps = newState; + Game1.FpsSettingChanged = true; + }); + contentLayout.AddElement(toggleFpsLock); + + var smoothCameraToggle = InterfaceToggle.GetToggleButton(new Point(buttonWidth, 18), new Point(5, 2), + "settings_game_change_smooth_camera", GameSettings.SmoothCamera, newState => { GameSettings.SmoothCamera = newState; }); + contentLayout.AddElement(smoothCameraToggle); + + _graphicSettingsLayout.AddElement(contentLayout); + + _bottomBar = new InterfaceListLayout { Size = new Point(width, (int)(height * Values.MenuFooterSize)), Selectable = true, HorizontalMode = true }; + // back button + _bottomBar.AddElement(new InterfaceButton(new Point(60, 20), new Point(2, 4), "settings_menu_back", element => + { + Game1.UiPageManager.PopPage(); + })); + + _graphicSettingsLayout.AddElement(_bottomBar); + + PageLayout = _graphicSettingsLayout; + + //UpdateScaleSlider(); + } + + public override void Update(CButtons pressedButtons, GameTime gameTime) + { + base.Update(pressedButtons, gameTime); + + UpdateFullscreenState(); + + //UpdateScaleSlider(); + + // close the page + if (ControlHandler.ButtonPressed(CButtons.B)) + Game1.UiPageManager.PopPage(); + } + + public override void OnLoad(Dictionary intent) + { + // the left button is always the first one selected + _bottomBar.Deselect(false); + _bottomBar.Select(InterfaceElement.Directions.Left, false); + _bottomBar.Deselect(false); + + PageLayout.Deselect(false); + PageLayout.Select(InterfaceElement.Directions.Top, false); + } + + private void UpdateFullscreenState() + { + var toggle = ((InterfaceToggle)_toggleFullscreen.Elements[1]); + if (toggle.ToggleState != GameSettings.IsFullscreen) + toggle.SetToggle(GameSettings.IsFullscreen); + } + + //private void UpdateScaleSlider() + //{ + // if (GameSettings.UiScale == 0) + // { + // _uiScaleSlider.UpdateStepSize(1, Game1.ScreenScale + 1, Game1.ScreenScale + 1); + // _uiScaleSlider.CurrentStep = Game1.ScreenScale; + // } + // else + // { + // _uiScaleSlider.UpdateStepSize(1, Game1.ScreenScale, Game1.ScreenScale + 1); + // GameSettings.UiScale = _uiScaleSlider.CurrentStep + 1; + // } + //} + } +} diff --git a/InGame/Pages/MainMenuPage.cs b/InGame/Pages/MainMenuPage.cs new file mode 100644 index 0000000..d0069a5 --- /dev/null +++ b/InGame/Pages/MainMenuPage.cs @@ -0,0 +1,397 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.Interface; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Pages +{ + class MainMenuPage : InterfacePage + { + enum State + { + Select, + Delete, + Copy + } + + public InterfaceListLayout[] SaveEntries = new InterfaceListLayout[SaveStateManager.SaveCount]; + + private float[] _playerSelectionState = new float[SaveStateManager.SaveCount]; + private InterfaceImage[] _playerImage = new InterfaceImage[SaveStateManager.SaveCount]; + private InterfaceButton[] _saveButtons = new InterfaceButton[SaveStateManager.SaveCount]; + + private Dictionary _newGameIntent = new Dictionary(); + + private Animator _playerAnimation = new Animator(); + private DictAtlasEntry _heartSprite; + + private InterfaceElement[][] _heartImage = new InterfaceElement[4][]; + + private InterfaceGravityLayout[] _saveButtonLayouts = new InterfaceGravityLayout[SaveStateManager.SaveCount]; + private InterfaceLabel[] _saveNames = new InterfaceLabel[SaveStateManager.SaveCount]; + private InterfaceLabel[] _saveRuby = new InterfaceLabel[SaveStateManager.SaveCount]; + private InterfaceListLayout[] _deleteCopyLayouts = new InterfaceListLayout[SaveStateManager.SaveCount]; + + private InterfaceListLayout _mainLayout; + private InterfaceListLayout _newGameButtonLayout; + + private InterfaceListLayout _menuBottomBar; + private InterfaceListLayout _saveFileList; + + private int _selectedSaveIndex; + + public MainMenuPage(int width, int height) + { + var smallButtonWidth = 80; + var smallButtonMargin = 2; + + var saveButtonRec = new Point(186, 30); + var sideSize = 50; + + _heartSprite = Resources.GetSprite("heart menu"); + + _playerAnimation = AnimatorSaveLoad.LoadAnimator("menu_link"); + _playerAnimation.Play("idle"); + + _newGameButtonLayout = new InterfaceListLayout { Size = saveButtonRec }; + _newGameButtonLayout.AddElement(new InterfaceLabel("main_menu_new_game")); + + // list of all save files + { + _saveFileList = new InterfaceListLayout() { Size = new Point(width, (int)(height * Values.MenuContentSize)), Selectable = true }; + for (var i = 0; i < SaveStateManager.SaveCount; i++) + { + _saveButtonLayouts[i] = new InterfaceGravityLayout { Size = new Point(saveButtonRec.X, saveButtonRec.Y) }; + + var numberWidth = 17; + var saveSlotNumber = new InterfaceLabel(null, new Point(numberWidth, 28), Point.Zero) + { Gravity = InterfaceElement.Gravities.Left }; + saveSlotNumber.SetText((i + 1).ToString()); + + _saveButtonLayouts[i].AddElement(saveSlotNumber); + + var saveInfoLayout = new InterfaceListLayout { HorizontalMode = true, Size = new Point(saveButtonRec.X - numberWidth, saveButtonRec.Y), Gravity = InterfaceElement.Gravities.Right }; + + // hearts on the left + { + var heartsWidth = saveButtonRec.X / 2 - numberWidth - 8; + var hearts = new InterfaceListLayout { Size = new Point(heartsWidth, 30) }; + + var rowOne = new InterfaceListLayout { Size = new Point(heartsWidth - 4, 7), Margin = new Point(2, 1), HorizontalMode = true, ContentAlignment = InterfaceElement.Gravities.Right }; + var rowTwo = new InterfaceListLayout { Size = new Point(heartsWidth - 4, 7), Margin = new Point(2, 1), HorizontalMode = true, ContentAlignment = InterfaceElement.Gravities.Right }; + + // hearts + _heartImage[i] = new InterfaceElement[14]; + for (var j = 0; j < 7; j++) + { + // top row + _heartImage[i][j] = rowOne.AddElement(new InterfaceImage(Resources.SprItem, _heartSprite.ScaledRectangle, Point.Zero, new Point(1, 1)) { Gravity = InterfaceElement.Gravities.Right }); + // bottom row + _heartImage[i][j + 7] = + rowTwo.AddElement(new InterfaceImage(Resources.SprItem, _heartSprite.ScaledRectangle, Point.Zero, new Point(1, 1)) { Gravity = InterfaceElement.Gravities.Right }); + } + + hearts.AddElement(rowOne); + hearts.AddElement(rowTwo); + + saveInfoLayout.AddElement(hearts); + } + + // name + rubys on the right + { + var rightWidth = saveButtonRec.X / 2 + 8; + var middle = new InterfaceListLayout { Gravity = InterfaceElement.Gravities.Left, Margin = new Point(2, 0), Size = new Point(rightWidth, 30) }; + + // name + middle.AddElement(_saveNames[i] = new InterfaceLabel(null, new Point(rightWidth - 3, 15), Point.Zero) { Margin = new Point(1, 0), TextAlignment = InterfaceElement.Gravities.Left | InterfaceElement.Gravities.Bottom }); + // ruby + middle.AddElement(_saveRuby[i] = new InterfaceLabel(null, new Point(rightWidth - 2, 13), Point.Zero) { Margin = new Point(0, 0), TextAlignment = InterfaceElement.Gravities.Left }); + + saveInfoLayout.AddElement(middle); + } + + var i1 = i; + _saveButtonLayouts[i].AddElement(saveInfoLayout); + + _saveButtons[i] = new InterfaceButton + { + InsideElement = _saveButtonLayouts[i], + Size = new Point(saveButtonRec.X, saveButtonRec.Y), + Margin = new Point(0, 2), + ClickFunction = e => OnClickSave(i1) + }; + + SaveEntries[i] = new InterfaceListLayout { HorizontalMode = true, Gravity = InterfaceElement.Gravities.Right, AutoSize = true, Selectable = true }; + + // dummy layout + SaveEntries[i].AddElement(new InterfaceListLayout { Size = new Point(sideSize - 20, 20) }); + SaveEntries[i].AddElement(_playerImage[i] = new InterfaceImage(_playerAnimation.SprTexture, _playerAnimation.CurrentFrame.SourceRectangle, new Point(20, 16), new Point(0, 0))); + + // save file + SaveEntries[i].AddElement(_saveButtons[i]); + + // copy/delete options + var currentSlot = i; + _deleteCopyLayouts[i] = new InterfaceListLayout + { + Gravity = InterfaceElement.Gravities.Right, + Size = new Point(sideSize, saveButtonRec.Y), + PreventSelection = true, + Selectable = true, + Visible = false + }; + + var insideCopy = new InterfaceListLayout() { Size = new Point(sideSize - 4, 13) }; + insideCopy.AddElement(new InterfaceLabel("main_menu_copy") { Size = new Point(40, 12), TextAlignment = InterfaceElement.Gravities.Bottom }); + _deleteCopyLayouts[i].AddElement(new InterfaceButton(new Point(sideSize - 4, 13), new Point(0, 1), insideCopy, element => OnClickCopy(currentSlot))); + + var insideDelete = new InterfaceListLayout() { Size = new Point(sideSize - 4, 13) }; + insideDelete.AddElement(new InterfaceLabel("main_menu_erase") { Size = new Point(40, 12), TextAlignment = InterfaceElement.Gravities.Bottom }); + _deleteCopyLayouts[i].AddElement(new InterfaceButton(new Point(sideSize - 4, 13), new Point(0, 1), insideDelete, element => OnClickDelete(currentSlot))); + + SaveEntries[i].AddElement(_deleteCopyLayouts[i]); + + // add save button to the main layout + _saveFileList.AddElement(SaveEntries[i]); + } + } + + var buttonHeight = 18; + + // menu bottom bar + { + _menuBottomBar = new InterfaceListLayout + { + Size = new Point(saveButtonRec.X, (int)(height * Values.MenuFooterSize)), + HorizontalMode = true, + Selectable = true + }; + + var smallButtonLayout = new InterfaceGravityLayout { Size = new Point(smallButtonWidth, buttonHeight) }; + smallButtonLayout.AddElement(new InterfaceLabel("main_menu_settings") { Gravity = InterfaceElement.Gravities.Center }); + _menuBottomBar.AddElement(new InterfaceButton + { + Size = new Point(smallButtonWidth, buttonHeight), + InsideElement = smallButtonLayout, + Margin = new Point(smallButtonMargin, 2), + ClickFunction = element => + { + Game1.UiPageManager.ChangePage(typeof(SettingsPage)); + } + }); + } + + // main layout + { + _mainLayout = new InterfaceListLayout { Size = new Point(width, height), Gravity = InterfaceElement.Gravities.Left, Selectable = true }; + + _mainLayout.AddElement(new InterfaceLabel(Resources.GameHeaderFont, "main_menu_select_header", new Point(width, (int)(height * Values.MenuHeaderSize)), new Point(0, 0))); + _mainLayout.AddElement(_saveFileList); + _mainLayout.AddElement(_menuBottomBar); + } + + PageLayout = _mainLayout; + PageLayout.Select(InterfaceElement.Directions.Top, false); + } + + public override void OnLoad(Dictionary intent) + { + // load the savestates + SaveStateManager.LoadSaveData(); + + UpdateUi(); + + // select the savestate + if (_selectedSaveIndex != -1) + { + _saveFileList.Elements[_selectedSaveIndex].Deselect(false); + _saveFileList.Elements[_selectedSaveIndex].Select(InterfaceElement.Directions.Left, false); + } + + for (var i = 0; i < _deleteCopyLayouts.Length; i++) + _deleteCopyLayouts[i].Visible = i == 0 && SaveStateManager.SaveStates[i] != null; + + PageLayout = _mainLayout; + PageLayout.Deselect(false); + PageLayout.Select(InterfaceElement.Directions.Top, false); + + UpdatePlayerAnimation(25); + } + + public override void OnReturn(Dictionary intent) + { + base.OnReturn(intent); + + if (intent != null && intent.TryGetValue("deleteReturn", out var deleteReturn) && (bool)deleteReturn) + { + // select the savestate + _saveFileList.Elements[_selectedSaveIndex].Deselect(false); + _saveFileList.Elements[_selectedSaveIndex].Select(InterfaceElement.Directions.Left, false); + } + + // delete the save state? + if (intent != null && intent.TryGetValue("deleteSavestate", out var deleteSaveState) && (bool)deleteSaveState) + { + SaveGameSaveLoad.DeleteSaveFile(_selectedSaveIndex); + ReloadSaves(); + } + + // copy save state + if (intent != null && intent.TryGetValue("copyTargetSlot", out var targetSlot)) + { + SaveGameSaveLoad.CopySaveFile(_selectedSaveIndex, (int)targetSlot); + ReloadSaves(); + + // select the savestate + _saveFileList.Elements[_selectedSaveIndex].Deselect(false); + _saveFileList.Elements[_selectedSaveIndex].Select(InterfaceElement.Directions.Left, false); + _saveFileList.Elements[_selectedSaveIndex].Deselect(false); + + // select the target slot + _saveFileList.Select((int)targetSlot, false); + } + } + + public override void Update(CButtons pressedButtons, GameTime gameTime) + { + base.Update(pressedButtons, gameTime); + + if (Game1.FinishedLoading && Game1.LoadFirstSave) + { + Game1.LoadFirstSave = false; + LoadSave(0); + } + + UpdatePlayerAnimation(); + + // only show the copy/delete buttons for the saveslot that is currently selected + var selectedSaveIndex = -1; + for (var i = 0; i < _deleteCopyLayouts.Length; i++) + { + _deleteCopyLayouts[i].Visible = _saveFileList.Elements[i].Selected && SaveStateManager.SaveStates[i] != null; + if (_saveFileList.Elements[i].Selected) + selectedSaveIndex = i; + } + + if (ControlHandler.ButtonPressed(CButtons.B)) + { + _selectedSaveIndex = selectedSaveIndex; + + // change to the game screen + Game1.ScreenManager.ChangeScreen(Values.ScreenNameIntro); + // close the menu page + Game1.UiPageManager.PopPage(null, PageManager.TransitionAnimation.TopToBottom, PageManager.TransitionAnimation.TopToBottom); + } + } + + private void UpdatePlayerAnimation(float transitionSpeed = 0.25f) + { + // update the animation + _playerAnimation.Update(); + + for (var i = 0; i < SaveStateManager.SaveCount; i++) + { + _playerSelectionState[i] = AnimationHelper.MoveToTarget(_playerSelectionState[i], _saveButtons[i].Selected ? 1 : 0, transitionSpeed * Game1.TimeMultiplier); + + _playerImage[i].ImageColor = Color.Lerp(Color.Transparent, Color.White, _playerSelectionState[i]); + _playerImage[i].SourceRectangle = _playerAnimation.CurrentFrame.SourceRectangle; + _playerImage[i].Offset = new Vector2( + _playerAnimation.CurrentAnimation.Offset.X + _playerAnimation.CurrentFrame.Offset.X, + _playerAnimation.CurrentAnimation.Offset.Y + _playerAnimation.CurrentFrame.Offset.Y); + _playerImage[i].Effects = + (_playerAnimation.CurrentFrame.MirroredV ? SpriteEffects.FlipVertically : SpriteEffects.None) | + (_playerAnimation.CurrentFrame.MirroredH ? SpriteEffects.FlipHorizontally : SpriteEffects.None); + } + } + + private void OnClickCopy(int number) + { + _selectedSaveIndex = number; + + var intent = new Dictionary(); + intent.Add("selectedSlot", number); + + Game1.UiPageManager.ChangePage(typeof(CopyPage), intent, PageManager.TransitionAnimation.Fade, PageManager.TransitionAnimation.Fade); + } + + private void OnClickDelete(int number) + { + _selectedSaveIndex = number; + + Game1.UiPageManager.ChangePage(typeof(DeleteSaveSlotPage), null, PageManager.TransitionAnimation.Fade, PageManager.TransitionAnimation.Fade); + } + + private void OnClickSave(int number) + { + _selectedSaveIndex = number; + + // load the save file + LoadSave(number); + } + + private void LoadSave(int saveIndex) + { + // load game or create new save + if (SaveStateManager.SaveStates[saveIndex] != null) + { + // change to the game screen + Game1.ScreenManager.ChangeScreen(Values.ScreenNameGame); + // load the save + Game1.GameManager.LoadSaveFile(saveIndex); + // close the menu page + Game1.UiPageManager.PopPage(null, PageManager.TransitionAnimation.TopToBottom, PageManager.TransitionAnimation.TopToBottom); + } + else + { + // change to the NewGamePage + _newGameIntent["SelectedSaveSlot"] = saveIndex; + Game1.UiPageManager.ChangePage(typeof(NewGamePage), _newGameIntent); + } + } + + private void ReloadSaves() + { + // load the savestates + SaveStateManager.LoadSaveData(); + + // update the UI + UpdateUi(); + } + + private void UpdateUi() + { + for (var i = 0; i < SaveStateManager.SaveCount; i++) + { + if (SaveStateManager.SaveStates[i] == null) + { + _saveButtons[i].InsideElement = _newGameButtonLayout; + continue; + } + else + { + _saveButtons[i].InsideElement = _saveButtonLayouts[i]; + } + + _saveNames[i].SetText(SaveStateManager.SaveStates[i].Name); + _saveRuby[i].SetText(SaveStateManager.SaveStates[i].CurrentRubee.ToString()); + + for (var j = 0; j < 14; j++) + { + // only draw the hearts the player has + _heartImage[i][j].Hidden = SaveStateManager.SaveStates[i].MaxHearth <= j; + + var state = 4 - MathHelper.Clamp(SaveStateManager.SaveStates[i].CurrentHearth - (j * 4), 0, 4); + + ((InterfaceImage)_heartImage[i][j]).SourceRectangle = new Rectangle( + _heartSprite.ScaledRectangle.X + (_heartSprite.ScaledRectangle.Width + _heartSprite.TextureScale) * state, + _heartSprite.ScaledRectangle.Y, + _heartSprite.ScaledRectangle.Width, _heartSprite.ScaledRectangle.Height); + } + } + } + } +} diff --git a/InGame/Pages/NewGamePage.cs b/InGame/Pages/NewGamePage.cs new file mode 100644 index 0000000..67ca9a3 --- /dev/null +++ b/InGame/Pages/NewGamePage.cs @@ -0,0 +1,216 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.Interface; +using ProjectZ.InGame.Things; +using ProjectZ.Base; + +namespace ProjectZ.InGame.Pages +{ + class NewGamePage : InterfacePage + { + private InterfaceButton _capsLockButton; + private InterfaceButton[,] _keyboardButtons; + private InterfaceListLayout[] _keyboardRows; + + private readonly InterfaceButton _newGameButton; + private readonly InterfaceLabel _labelNameInput; + + private const int MaxNameLength = 12; + private string _strNameInput; + private int _selectedSaveSlot; + + private const char CapsLockCharacter = '³'; + private const char BackCharacter = '°'; + + private bool _upperMode; + + private char[,] _charactersUpper = new char[,] + { + { 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P' }, + { 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', '-' }, + { CapsLockCharacter, 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ' ', BackCharacter } + }; + + private char[,] _charactersLower = new char[,] + { + { 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p' }, + { 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', '-' }, + { CapsLockCharacter, 'z', 'x', 'c', 'v', 'b', 'n', 'm', ' ', BackCharacter } + }; + + public NewGamePage(int width, int height) + { + // new game layout + var newGameLayout = new InterfaceListLayout { Size = new Point(width, height), Selectable = true }; + newGameLayout.AddElement(new InterfaceLabel("new_game_menu_save_name") { Margin = new Point(0, 2) }); + + _labelNameInput = new InterfaceLabel(null) { Selectable = true, Size = new Point(200, 20) }; + + var layerButton = new InterfaceListLayout { Size = new Point(200, 20) }; + layerButton.AddElement(_labelNameInput); + _newGameButton = new InterfaceButton { Size = new Point(200, 20), InsideElement = layerButton }; + newGameLayout.AddElement(_newGameButton); + + + { + var keyboardLayout = new InterfaceListLayout { AutoSize = true, Margin = new Point(0, 5), Selectable = true }; + + var keyWidth = 20; + var keyHeight = 20; + + _keyboardButtons = new InterfaceButton[_charactersUpper.GetLength(0), _charactersUpper.GetLength(1)]; + _keyboardRows = new InterfaceListLayout[_charactersUpper.GetLength(0)]; + + for (var y = 0; y < _charactersUpper.GetLength(0); y++) + { + _keyboardRows[y] = new InterfaceListLayout { AutoSize = true, HorizontalMode = true, Selectable = true }; + + for (int x = 0; x < _charactersUpper.GetLength(1); x++) + { + if (_charactersUpper[y, x] == '-') + continue; + + var letterX = x; + var letterY = y; + //var buttonWidth = _charactersUpper[y, x] == BackCharacter ? keyWidth * 2 + 2 : keyHeight; + _keyboardButtons[y, x] = new InterfaceButton(new Point(keyWidth, keyHeight), new Point(1, 1), "", element => KeyPressed(letterX, letterY)) { CornerRadius = 0 }; + ((InterfaceLabel)_keyboardButtons[y, x].InsideElement).SetText(_charactersUpper[y, x].ToString()); + + if (_charactersUpper[y, x] == CapsLockCharacter) + _capsLockButton = _keyboardButtons[y, x]; + + _keyboardRows[y].AddElement(_keyboardButtons[y, x]); + } + + _keyboardRows[y].SetSelectionIndex(4); + keyboardLayout.AddElement(_keyboardRows[y]); + } + + newGameLayout.AddElement(keyboardLayout); + } + + + var nglBottomLayout = new InterfaceListLayout { Size = new Point(200, 20), HorizontalMode = true, Selectable = true }; + nglBottomLayout.AddElement(new InterfaceButton(new Point(99, 20), new Point(1, 0), "new_game_menu_back", OnClickBackButton)); + nglBottomLayout.AddElement(new InterfaceButton(new Point(99, 20), new Point(1, 0), "new_game_menu_start_game", OnClickNewGameButton)); + nglBottomLayout.Select(InterfaceElement.Directions.Right, false); + nglBottomLayout.Deselect(false); + + newGameLayout.AddElement(nglBottomLayout); + newGameLayout.Select(InterfaceElement.Directions.Top, false); + + PageLayout = newGameLayout; + } + + public override void OnLoad(Dictionary intent) + { + // get the selected save slot number from the intent + _selectedSaveSlot = (int)intent["SelectedSaveSlot"]; + + // reset the name of the save slot + _strNameInput = "Link"; + _labelNameInput.SetText(_strNameInput + " "); + + _upperMode = true; + UpdateKeyboard(); + + PageLayout.Deselect(false); + PageLayout.Select(InterfaceElement.Directions.Top, false); + + base.OnLoad(intent); + } + + private void UpdateKeyboard() + { + _capsLockButton.Color = _upperMode ? Values.MenuButtonColorSelected : Values.MenuButtonColor; + + for (var y = 0; y < _charactersUpper.GetLength(0); y++) + for (int x = 0; x < _charactersUpper.GetLength(1); x++) + if (_keyboardButtons[y, x] != null) + ((InterfaceLabel)_keyboardButtons[y, x].InsideElement).SetText((_upperMode ? _charactersUpper[y, x] : _charactersLower[y, x]).ToString()); + } + + public override void Update(CButtons pressedButtons, GameTime gameTime) + { + base.Update(pressedButtons, gameTime); + + // @HACK: going up/down we select the correct button + for (var y = 0; y < _charactersUpper.GetLength(0); y++) + for (int x = 0; x < _charactersUpper.GetLength(1); x++) + if (_keyboardButtons[y, x] != null && _keyboardButtons[y, x].Selected) + { + for (var y1 = 0; y1 < _charactersUpper.GetLength(0); y1++) + _keyboardRows[y1].SetSelectionIndex(x); + } + + if (_newGameButton.Selected) + { + // get the keyboard input + var strInput = InputHandler.ReturnCharacter(); + AddCharacters(strInput); + + if (InputHandler.KeyPressed(Keys.Back)) + RemoveCharacter(); + } + else + { + // close the page + if (ControlHandler.ButtonPressed(CButtons.B)) + Game1.UiPageManager.PopPage(); + } + + _labelNameInput.SetText(_strNameInput + ((gameTime.TotalGameTime.Milliseconds % 500) < 250 ? "_" : " ")); + } + + private void RemoveCharacter() + { + // remove the last letter + if (_strNameInput.Length > 0) + _strNameInput = _strNameInput.Remove(_strNameInput.Length - 1); + } + + private void AddCharacters(string letter) + { + _strNameInput += letter; + + // cut the string off + if (_strNameInput.Length > MaxNameLength) + _strNameInput = _strNameInput.Remove(MaxNameLength); + } + + private void KeyPressed(int x, int y) + { + var characters = _upperMode ? _charactersUpper : _charactersLower; + + // toggle caps lock + if (characters[y, x] == CapsLockCharacter) + { + _upperMode = !_upperMode; + UpdateKeyboard(); + } + else if (characters[y, x] == BackCharacter) + RemoveCharacter(); + else + { + AddCharacters(characters[y, x].ToString()); + } + } + + private void OnClickNewGameButton(InterfaceElement element) + { + // change to the game screen + Game1.ScreenManager.ChangeScreen(Values.ScreenNameGame); + // create new save file + Game1.GameManager.StartNewGame(_selectedSaveSlot, _strNameInput); + // close the gameui + Game1.UiPageManager.PopAllPages(PageManager.TransitionAnimation.TopToBottom, PageManager.TransitionAnimation.TopToBottom); + } + + private void OnClickBackButton(InterfaceElement element) + { + Game1.UiPageManager.PopPage(); + } + } +} diff --git a/InGame/Pages/PageManager.cs b/InGame/Pages/PageManager.cs new file mode 100644 index 0000000..abb8a03 --- /dev/null +++ b/InGame/Pages/PageManager.cs @@ -0,0 +1,246 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.Interface; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Pages +{ + public class PageManager + { + public enum TransitionAnimation + { + Fade, + LeftToRight, + RightToLeft, + TopToBottom, + BottomToTop + } + + public Dictionary InsideElement = new Dictionary(); + public List PageStack = new List(); + + private TransitionAnimation _transitionOutAnimation; + private TransitionAnimation _transitionInAnimation; + + private Vector2 _menuPosition; + + private double _transitionCount; + + private float _transitionState; + + private int _width; + private int _height; + private int _currentPage; + private int _nextPage; + private int _transitionTime; + private int _transitionDirection; + + private const int TransitionFade = 125; + private const int TransitionNormal = 200; + + private bool _isTransitioning; + + public void Load() + { + _width = Values.MinWidth - 32; + _height = Values.MinHeight - 32; + + AddPage(new MainMenuPage(_width, _height)); + AddPage(new CopyPage(_width, _height)); + AddPage(new CopyConfirmationPage(_width, _height)); + AddPage(new DeleteSaveSlotPage(_width, _height)); + AddPage(new NewGamePage(_width, _height)); + AddPage(new SettingsPage(_width, _height)); + AddPage(new GameSettingsPage(_width, _height)); + //AddPage(new AudioSettingsPage(_width, _height)); + AddPage(new ControlSettingsPage(_width, _height)); + AddPage(new GraphicSettingsPage(_width, _height)); + AddPage(new GameMenuPage(_width, _height)); + AddPage(new ExitGamePage(_width, _height)); + AddPage(new GameOverPage(_width, _height)); + } + + public virtual void Update(GameTime gameTime) + { + // not a good place + _menuPosition = new Vector2( + (Game1.WindowWidth / 2 - _width * Game1.UiScale / 2) / Game1.UiScale * Game1.UiScale, + (Game1.WindowHeight / 2 - _height * Game1.UiScale / 2) / Game1.UiScale * Game1.UiScale); + + if (_isTransitioning) + { + _transitionCount += Game1.DeltaTime; + + if (_transitionCount >= _transitionTime) + { + _transitionCount = 0; + _isTransitioning = false; + + // remove the old page after finishing the transition + if (_transitionDirection == 1) + { + if (PageStack.Count > 0) + PageStack.RemoveAt(0); + } + + _currentPage = 0; + } + } + + if (!_isTransitioning && PageStack.Count > _currentPage) + InsideElement[PageStack[_currentPage]].Update(ControlHandler.GetPressedButtons(), gameTime); + } + + public void Draw(SpriteBatch spriteBatch) + { + _transitionState = (float)(Math.Sin(_transitionCount / _transitionTime * Math.PI - Math.PI / 2) + 1) / 2f; + + // draw the current page + if (PageStack.Count > _currentPage) + { + var directionX = + _transitionOutAnimation == TransitionAnimation.RightToLeft ? _transitionDirection : + _transitionOutAnimation == TransitionAnimation.LeftToRight ? -_transitionDirection : 0; + var directionY = + _transitionOutAnimation == TransitionAnimation.TopToBottom ? -_transitionDirection : + _transitionOutAnimation == TransitionAnimation.BottomToTop ? _transitionDirection : 0; + var transitionOffset = new Vector2( + _width * 0.65f * _transitionState * directionX * Game1.UiScale, + _height * 0.65f * _transitionState * directionY * Game1.UiScale); + + InsideElement[PageStack[_currentPage]].Draw(spriteBatch, + _menuPosition + transitionOffset, Game1.UiScale, 1 - _transitionState); + } + + if (!_isTransitioning || PageStack.Count <= _nextPage) + return; + + // draw the next page while transitioning + var directionXNext = + _transitionInAnimation == TransitionAnimation.RightToLeft ? -_transitionDirection : + _transitionInAnimation == TransitionAnimation.LeftToRight ? _transitionDirection : 0; + var directionYNext = + _transitionInAnimation == TransitionAnimation.TopToBottom ? _transitionDirection : + _transitionInAnimation == TransitionAnimation.BottomToTop ? -_transitionDirection : 0; + var transitionOffsetNext = new Vector2( + _width * 0.65f * (1 - _transitionState) * directionXNext * Game1.UiScale, + _height * 0.65f * (1 - _transitionState) * directionYNext * Game1.UiScale); + + InsideElement[PageStack[_nextPage]].Draw(spriteBatch, + _menuPosition + transitionOffsetNext, Game1.UiScale, _transitionState); + } + + private void AddPage(InterfacePage element) + { + InsideElement.Add(element.GetType(), element); + } + + public bool ChangePage(Type nextPage, Dictionary intent, TransitionAnimation animationIn = TransitionAnimation.RightToLeft, TransitionAnimation animationOut = TransitionAnimation.RightToLeft) + { + // do not add the page/restart the animation if it is transitioning out of the page + if (!_isTransitioning || PageStack.Count <= 0 || nextPage != PageStack[0]) + { + PageStack.Insert(0, nextPage); + + _transitionCount = 0; + _transitionState = 0; + } + else + { + _transitionCount = _transitionTime - _transitionCount; + } + + _isTransitioning = true; + _transitionDirection = -1; + + _currentPage = 1; + _nextPage = 0; + + // onload + InsideElement[nextPage].OnLoad(intent); + + _transitionInAnimation = animationIn; + _transitionOutAnimation = animationOut; + + // @HACK + _transitionTime = _transitionInAnimation == TransitionAnimation.Fade ? TransitionFade : TransitionNormal; + + return true; + } + + public InterfacePage GetPage(Type pageType) + { + return InsideElement[pageType]; + } + + public InterfacePage GetCurrentPage() + { + if (PageStack.Count <= 0) + return null; + + return InsideElement[PageStack[0]]; + } + + public bool ChangePage(Type nextPage) + { + return ChangePage(nextPage, null); + } + + public void PopPage(Dictionary intent = null, TransitionAnimation animationIn = TransitionAnimation.RightToLeft, TransitionAnimation animationOut = TransitionAnimation.RightToLeft) + { + if (PageStack.Count <= 0) + return; + + if (PageStack.Count > 0) + InsideElement[PageStack[0]].OnPop(intent); + + if (!_isTransitioning) + { + _transitionCount = 0; + _isTransitioning = true; + } + else + { + PageStack.RemoveAt(0); + _transitionCount = _transitionTime - _transitionCount; + } + + _transitionDirection = 1; + + _currentPage = 0; + _nextPage = 1; + + // onload + if (PageStack.Count > 1) + InsideElement[PageStack[1]].OnReturn(intent); + + _transitionInAnimation = animationIn; + _transitionOutAnimation = animationOut; + + // @HACK + _transitionTime = _transitionInAnimation == TransitionAnimation.Fade ? TransitionFade : TransitionNormal; + } + + public void PopAllPages(TransitionAnimation animationIn = TransitionAnimation.RightToLeft, TransitionAnimation animationOut = TransitionAnimation.RightToLeft) + { + PopPage(null, animationIn, animationOut); + + // remove everything but the current page + if (PageStack.Count > 1) + { + for (var i = 0; i < PageStack.Count; i++) + InsideElement[PageStack[i]].OnPop(null); + + PageStack.RemoveRange(1, PageStack.Count - 1); + } + } + + public void ClearStack() + { + PageStack.Clear(); + } + } +} diff --git a/InGame/Pages/SettingsPage.cs b/InGame/Pages/SettingsPage.cs new file mode 100644 index 0000000..227d3e6 --- /dev/null +++ b/InGame/Pages/SettingsPage.cs @@ -0,0 +1,98 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.Interface; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Pages +{ + class SettingsPage : InterfacePage + { + private readonly InterfaceLabel _versionLabel; + + public SettingsPage(int width, int height) + { + // settings layout + var settingsLayout = new InterfaceListLayout { Size = new Point(width, height), Selectable = true }; + + var headerLayout = new InterfaceListLayout { Size = new Point(width, (int)(height * Values.MenuHeaderSize)), ContentAlignment = InterfaceElement.Gravities.Left, HorizontalMode = true }; + { + _versionLabel = new InterfaceLabel("", new Point((width - 150) / 2 - 2, headerLayout.Size.Y), new Point(1, 0)) + { Translate = false, TextAlignment = InterfaceElement.Gravities.Left | InterfaceElement.Gravities.Top }; + _versionLabel.SetText(Values.VersionString); + headerLayout.AddElement(_versionLabel); + + headerLayout.AddElement(new InterfaceLabel(Resources.GameHeaderFont, "settings_menu_header", new Point(150, (int)(height * Values.MenuHeaderSize)), new Point(0, 0))); + } + settingsLayout.AddElement(headerLayout); + + var contentLayout = new InterfaceListLayout { Size = new Point(width, (int)(height * Values.MenuContentSize)), Selectable = true }; + + // game settings button + contentLayout.AddElement(new InterfaceButton(new Point(150, 25), new Point(1, 2), "settings_menu_game", element => + { + Game1.UiPageManager.ChangePage(typeof(GameSettingsPage)); + })); + + //// audio settings button + //contentLayout.AddElement(new InterfaceButton(new Point(150, 25), new Point(1, 2), "settings_menu_audio", element => + //{ + // Game1.UiPageManager.ChangePage(typeof(AudioSettingsPage)); + //})); + + // controll settings button + contentLayout.AddElement(new InterfaceButton(new Point(150, 25), new Point(1, 2), "settings_menu_controls", element => + { + Game1.UiPageManager.ChangePage(typeof(ControlSettingsPage)); + })); + + // graphic settings button + contentLayout.AddElement(new InterfaceButton(new Point(150, 25), new Point(1, 2), "settings_menu_video", element => + { + Game1.UiPageManager.ChangePage(typeof(GraphicSettingsPage)); + })); + + settingsLayout.AddElement(contentLayout); + + var bottomLayout = new InterfaceListLayout { Size = new Point(width, (int)(height * Values.MenuFooterSize)), Selectable = true }; + // back button + bottomLayout.AddElement(new InterfaceButton(new Point(60, 20), new Point(2, 4), "settings_menu_back", element => + { + ExitPage(); + })); + settingsLayout.AddElement(bottomLayout); + + PageLayout = settingsLayout; + } + + public override void Update(CButtons pressedButtons, GameTime gameTime) + { + base.Update(pressedButtons, gameTime); + + // close the page + if (ControlHandler.ButtonPressed(CButtons.B)) + ExitPage(); + } + + public override void OnLoad(Dictionary intent) + { + PageLayout.Deselect(false); + PageLayout.Select(InterfaceElement.Directions.Top, false); + + // only show the version in the main menu + if(Game1.ScreenManager.CurrentScreenId == Values.ScreenNameGame) + _versionLabel.TextColor = Color.Transparent; + else + _versionLabel.TextColor = Color.White; + } + + private void ExitPage() + { + // save the new settings + SettingsSaveLoad.SaveSettings(); + + Game1.UiPageManager.PopPage(); + } + } +} diff --git a/InGame/SaveLoad/AnimatorSaveLoad.cs b/InGame/SaveLoad/AnimatorSaveLoad.cs new file mode 100644 index 0000000..95763a0 --- /dev/null +++ b/InGame/SaveLoad/AnimatorSaveLoad.cs @@ -0,0 +1,138 @@ +using System; +using System.IO; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.SaveLoad +{ + public class AnimatorSaveLoad + { + public static void SaveAnimator(string path, Animator animator) + { + var pathTemp = path + ".temp"; + var writer = new StreamWriter(pathTemp); + + var saveString = animator.SpritePath; + // animation version + writer.WriteLine("1"); + writer.WriteLine(saveString); + + for (var i = 0; i < animator.Animations.Count; i++) + { + saveString = animator.Animations[i].Id + ";"; + saveString += animator.Animations[i].NextAnimation + ";"; + saveString += animator.Animations[i].LoopCount + ";"; + + saveString += animator.Animations[i].Offset.X + ";"; + saveString += animator.Animations[i].Offset.Y + ";"; + + saveString += animator.Animations[i].Frames.Length; + + // write frames + for (var j = 0; j < animator.Animations[i].Frames.Length; j++) + { + saveString += ";" + + animator.Animations[i].Frames[j].FrameTime + ";" + + + animator.Animations[i].Frames[j].SourceRectangle.X + ";" + + animator.Animations[i].Frames[j].SourceRectangle.Y + ";" + + animator.Animations[i].Frames[j].SourceRectangle.Width + ";" + + animator.Animations[i].Frames[j].SourceRectangle.Height + ";" + + + animator.Animations[i].Frames[j].Offset.X + ";" + + animator.Animations[i].Frames[j].Offset.Y + ";" + + + animator.Animations[i].Frames[j].CollisionRectangle.X + ";" + + animator.Animations[i].Frames[j].CollisionRectangle.Y + ";" + + animator.Animations[i].Frames[j].CollisionRectangle.Width + ";" + + animator.Animations[i].Frames[j].CollisionRectangle.Height + ";" + + + animator.Animations[i].Frames[j].MirroredV + ";" + + animator.Animations[i].Frames[j].MirroredH; + } + + writer.WriteLine(saveString); + } + + writer.Close(); + + File.Delete(path); + File.Move(pathTemp, path); + } + + public static Animator LoadAnimator(string animatorId) + { + // TODO_End: preload all the animations + return LoadAnimatorFile(Values.PathAnimationFolder + animatorId + ".ani"); + } + + public static Animator LoadAnimatorFile(string filePath) + { + if (!File.Exists(filePath)) + return null; + + var reader = new StreamReader(filePath); + + var animator = new Animator(); + + var version = reader.ReadLine(); + animator.SpritePath = reader.ReadLine(); + animator.SprTexture = Resources.GetTexture(animator.SpritePath); + + // load the animations + while (!reader.EndOfStream) + { + var strLine = reader.ReadLine(); + + if (strLine == null) + continue; + + var strSplit = strLine.Split(';'); + + if (strSplit.Length < 16) + continue; + + var pos = 0; + var animationId = strSplit[pos].ToLower(); + + var animation = new Animation(animationId); + + animation.NextAnimation = strSplit[pos += 1].ToLower(); + animation.LoopCount = Convert.ToInt32(strSplit[pos += 1]); + animation.Offset.X = Convert.ToInt32(strSplit[pos += 1]); + animation.Offset.Y = Convert.ToInt32(strSplit[pos += 1]); + + var frames = Convert.ToInt32(strSplit[pos += 1]); + animation.Frames = new Frame[frames]; + + animator.AddAnimation(animation); + + for (var i = 0; i < frames; i++) + { + animator.SetFrameAt(animationId, i, new Frame() + { + FrameTime = Convert.ToInt32(strSplit[pos += 1]), + + SourceRectangle = new Rectangle( + Convert.ToInt32(strSplit[pos += 1]), Convert.ToInt32(strSplit[pos += 1]), + Convert.ToInt32(strSplit[pos += 1]), Convert.ToInt32(strSplit[pos += 1])), + + Offset = new Point(Convert.ToInt32(strSplit[pos += 1]), Convert.ToInt32(strSplit[pos += 1])), + + CollisionRectangle = new Rectangle( + Convert.ToInt32(strSplit[pos += 1]), Convert.ToInt32(strSplit[pos += 1]), + Convert.ToInt32(strSplit[pos += 1]), Convert.ToInt32(strSplit[pos += 1])), + + MirroredV = Convert.ToBoolean(strSplit[pos += 1]), + MirroredH = Convert.ToBoolean(strSplit[pos += 1]) + }); + } + } + + reader.Close(); + + return animator; + } + } +} diff --git a/InGame/SaveLoad/DataMapSerializer.cs b/InGame/SaveLoad/DataMapSerializer.cs new file mode 100644 index 0000000..789521b --- /dev/null +++ b/InGame/SaveLoad/DataMapSerializer.cs @@ -0,0 +1,82 @@ +using System.IO; +#if WINDOWS +using System.Windows.Forms; +#endif + +namespace ProjectZ.InGame.SaveLoad +{ + class DataMapSerializer + { + public static void SaveDialog(string[,] data) + { +#if WINDOWS + var openFileDialog = new SaveFileDialog + { + RestoreDirectory = true, + Filter = "Data (*.data)|*.data" + }; + + if (openFileDialog.ShowDialog() == DialogResult.OK) + SaveData(openFileDialog.FileName, data); +#endif + } + + public static void LoadDialog(ref string[,] data) + { +#if WINDOWS + var openFileDialog = new OpenFileDialog + { + Filter = "Data (*.data)|*.data", + RestoreDirectory = true, + }; + + if (openFileDialog.ShowDialog() != DialogResult.OK) return; + + data = LoadData(openFileDialog.FileName); +#endif + } + + public static void SaveData(string path, string[,] data) + { + var writer = new StreamWriter(path); + + // write down the size + writer.WriteLine(data.GetLength(0)); + writer.WriteLine(data.GetLength(1)); + + for (var y = 0; y < data.GetLength(1); y++) + { + var line = ""; + for (var x = 0; x < data.GetLength(0); x++) + line += data[x, y] + ";"; + + writer.WriteLine(line); + } + + writer.Close(); + } + + public static string[,] LoadData(string path) + { + var reader = new StreamReader(path); + + var lengthX = int.Parse(reader.ReadLine()); + var lengthY = int.Parse(reader.ReadLine()); + + var output = new string[lengthX, lengthY]; + + for (var y = 0; y < lengthY; y++) + { + var line = reader.ReadLine(); + var split = line.Split(';'); + + for (var x = 0; x < lengthX; x++) + output[x, y] = split[x]; + } + + reader.Close(); + + return output; + } + } +} diff --git a/InGame/SaveLoad/DialogPathLoader.cs b/InGame/SaveLoad/DialogPathLoader.cs new file mode 100644 index 0000000..b676412 --- /dev/null +++ b/InGame/SaveLoad/DialogPathLoader.cs @@ -0,0 +1,227 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.Overlay; + +namespace ProjectZ.InGame.SaveLoad +{ + class DialogPathLoader + { + public static void LoadScripts(string filePath, Dictionary> dialogPaths) + { + var reader = new StreamReader(filePath); + + // go from line to line + while (!reader.EndOfStream) + { + var strLine = reader.ReadLine().Replace(" ", ""); + + // ignore comment + if (strLine.Length == 0 || strLine.StartsWith("//")) + continue; + + var split = strLine.Split(new[] { "->" }, StringSplitOptions.None); + + if (split.Length <= 1) continue; + + var splitKey = split[0].Split(':'); + + DialogPath newPath; + if (splitKey.Length == 2) + newPath = new DialogPath(splitKey[0], splitKey[1]); + else + newPath = new DialogPath(splitKey[1], splitKey[2]); + + for (var i = 1; i < split.Length; i++) + AddAction(newPath, split[i], splitKey[0]); + + // create dictionary entry or create one + if (dialogPaths.ContainsKey(splitKey[0])) + dialogPaths[splitKey[0]].Add(newPath); + else + dialogPaths.Add(splitKey[0], new List { newPath }); + } + + reader.Close(); + } + + private static void AddAction(DialogPath path, string split, string key) + { + if (!split.Contains('[') && split.Length > 0) + { + path.Action.Add(new DialogActionStartDialog(split)); + return; + } + + var action = split.Replace("[", "").Replace("]", ""); + var stringSplit = action.Split(':'); + + if (stringSplit[0] == "path") + { + path.Action.Add(new DialogActionStartPath(stringSplit[1])); + } + else if (stringSplit[0] == "wait") + { + path.Action.Add(new DialogActionWait(stringSplit[1], stringSplit[2])); + } + else if (stringSplit[0] == "countdown") + { + var time = int.Parse(stringSplit[1]); + path.Action.Add(new DialogActionCountdown(time)); + } + else if (stringSplit[0] == "update_objects") + { + path.Action.Add(new DialogActionUpdateObjects()); + } + else if (stringSplit[0] == "freeze" && stringSplit.Length == 2) + { + path.Action.Add(new DialogActionFreezePlayerTime(int.Parse(stringSplit[1]))); + } + else if (stringSplit[0] == "freeze" && stringSplit.Length == 3) + { + path.Action.Add(new DialogActionFreezePlayer(stringSplit[1], stringSplit[2])); + } + else if (stringSplit[0] == "lock_player" && stringSplit.Length == 2) + { + path.Action.Add(new DialogActionLockPlayerTime(int.Parse(stringSplit[1]))); + } + else if (stringSplit[0] == "lock_player" && stringSplit.Length == 3) + { + path.Action.Add(new DialogActionLockPlayer(stringSplit[1], stringSplit[2])); + } + else if (stringSplit[0] == "shake" && stringSplit.Length == 6) + { + path.Action.Add(new DialogActionShake( + int.Parse(stringSplit[1]), int.Parse(stringSplit[2]), int.Parse(stringSplit[3]), + float.Parse(stringSplit[4], CultureInfo.InvariantCulture), + float.Parse(stringSplit[5], CultureInfo.InvariantCulture))); + } + else if (stringSplit[0] == "set") + { + if (stringSplit.Length == 2) + path.Action.Add(new DialogActionSetVariable(key, stringSplit[1])); + else + path.Action.Add(new DialogActionSetVariable(stringSplit[1], stringSplit[2])); + } + else if (stringSplit[0] == "check_item") + { + var itemCount = int.Parse(stringSplit[2]); + path.Action.Add(new DialogActionCheckItem(stringSplit[1], itemCount, stringSplit[3])); + } + else if (stringSplit[0] == "cooldown") + { + var cooldownTime = int.Parse(stringSplit[1]); + path.Action.Add(new DialogActionCooldown(cooldownTime, stringSplit[2])); + } + else if (stringSplit[0] == "add_item") + { + var itemCount = int.Parse(stringSplit[2]); + path.Action.Add(new DialogActionAddItem(stringSplit[1], itemCount)); + } + else if (stringSplit[0] == "add_item_amount") + { + var itemCount = int.Parse(stringSplit[2]); + path.Action.Add(new DialogActionAddItemAmount(stringSplit[1], itemCount)); + } + else if (stringSplit[0] == "remove_item") + { + var itemCount = int.Parse(stringSplit[2]); + path.Action.Add(new DialogActionRemoveItem(stringSplit[1], itemCount, stringSplit[3])); + } + else if (stringSplit[0] == "stop_music") + { + if (stringSplit.Length == 3) + path.Action.Add(new DialogActionStopMusicTime(int.Parse(stringSplit[1]), int.Parse(stringSplit[2]))); + else + path.Action.Add(new DialogActionStopMusic()); + } + else if (stringSplit[0] == "music") + { + var songNr = int.Parse(stringSplit[1]); + var priority = int.Parse(stringSplit[2]); + path.Action.Add(new DialogActionPlayMusic(songNr, priority)); + } + else if (stringSplit[0] == "music_speed") + { + path.Action.Add(new DialogActionMusicSpeed( + float.Parse(stringSplit[1], CultureInfo.InvariantCulture))); + } + else if (stringSplit[0] == "sound") + { + path.Action.Add(new DialogActionSoundEffect(stringSplit[1])); + } + else if (stringSplit[0] == "dialog") + { + var choices = new string[stringSplit.Length - 3]; + for (var j = 0; j < stringSplit.Length - 3; j++) + choices[j] = stringSplit[j + 3]; + path.Action.Add(new DialogActionDialog(stringSplit[1], stringSplit[2], choices)); + } + else if (stringSplit[0] == "buy") + { + path.Action.Add(new DialogActionBuyItem(stringSplit[1])); + } + else if (stringSplit[0] == "open_book") + { + path.Action.Add(new DialogActionOpenBook()); + } + else if (stringSplit[0] == "start_sequence") + { + path.Action.Add(new DialogActionStartSequence(stringSplit[1])); + } + else if (stringSplit[0] == "seq_set_position") + { + var posX = int.Parse(stringSplit[2]); + var posY = int.Parse(stringSplit[3]); + path.Action.Add(new DialogActionSeqSetPosition(stringSplit[1], new Vector2(posX, posY))); + } + else if (stringSplit[0] == "seq_lerp") + { + var posX = int.Parse(stringSplit[2]); + var posY = int.Parse(stringSplit[3]); + var time = float.Parse(stringSplit[4], CultureInfo.InvariantCulture); + path.Action.Add(new DialogActionSeqLerp(stringSplit[1], new Vector2(posX, posY), time)); + } + else if (stringSplit[0] == "seq_color") + { + var colorR = byte.Parse(stringSplit[2]); + var colorG = byte.Parse(stringSplit[3]); + var colorB = byte.Parse(stringSplit[4]); + var colorA = byte.Parse(stringSplit[5]); + var time = int.Parse(stringSplit[6]); + path.Action.Add(new DialogActionSeqColorLerp(stringSplit[1], new Color(colorR, colorG, colorB, colorA), time)); + } + else if (stringSplit[0] == "seq_play") + { + path.Action.Add(new DialogActionSeqPlay(stringSplit[1], stringSplit[2])); + } + else if (stringSplit[0] == "seq_finish_animation") + { + var stopFrameIndex = int.Parse(stringSplit[2]); + path.Action.Add(new DialogActionFinishAnimation(stringSplit[1], stopFrameIndex)); + } + else if (stringSplit[0] == "close_overlay") + { + path.Action.Add(new DialogActionCloseOverlay()); + } + else if (stringSplit[0] == "fill_hearts") + { + path.Action.Add(new DialogActionFillHearts()); + } + else if (stringSplit[0] == "spawn") + { + path.Action.Add(new DialogActionSpawnObject(key, stringSplit[1], stringSplit[2])); + } + else if (stringSplit[0] == "map_transition") + { + path.Action.Add(new DialogActionChangeMap(stringSplit[1], stringSplit[2])); + } + else if (stringSplit[0] == "save_history") + { + path.Action.Add(new DialogActionSaveHistory(bool.Parse(stringSplit[1]))); + } + } + } +} diff --git a/InGame/SaveLoad/DictAtlasEntry.cs b/InGame/SaveLoad/DictAtlasEntry.cs new file mode 100644 index 0000000..e6f0c90 --- /dev/null +++ b/InGame/SaveLoad/DictAtlasEntry.cs @@ -0,0 +1,34 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace ProjectZ.InGame.SaveLoad +{ + public class DictAtlasEntry + { + public readonly Texture2D Texture; + + public readonly Rectangle SourceRectangle; + public readonly Rectangle ScaledRectangle; + public readonly Vector2 Origin; + public readonly Vector2 ScaledOrigin; + + public readonly int TextureScale; + public readonly float Scale; + + public DictAtlasEntry(Texture2D texture, Rectangle sourceRectangle, Vector2 origin, int textureScale) + { + Texture = texture; + + SourceRectangle = sourceRectangle; + ScaledRectangle = new Rectangle( + sourceRectangle.X * textureScale, sourceRectangle.Y * textureScale, + sourceRectangle.Width * textureScale, sourceRectangle.Height * textureScale); + + Origin = origin; + ScaledOrigin = new Vector2(origin.X * textureScale, origin.Y * textureScale); + + TextureScale = textureScale; + Scale = 1.0f / textureScale; + } + } +} diff --git a/InGame/SaveLoad/MapData.cs b/InGame/SaveLoad/MapData.cs new file mode 100644 index 0000000..7ffa819 --- /dev/null +++ b/InGame/SaveLoad/MapData.cs @@ -0,0 +1,226 @@ +using System; +using System.Diagnostics; +using System.Globalization; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameObjects; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.SaveLoad +{ + public class MapData + { + public static void AddObject(Map.Map map, GameObjectItem gameObject) + { + // this can be used to update gameobjects + //if (gameObject.Index == "door") + //{ + // var parameterArray = GetParameterArray("newDoor"); + + // // set the object position + // parameterArray[1] = gameObject.Parameter[1]; + // parameterArray[2] = gameObject.Parameter[2]; + + // parameterArray[5] = gameObject.Parameter[3]; + // parameterArray[6] = gameObject.Parameter[4]; + // parameterArray[7] = gameObject.Parameter[3]; + // parameterArray[8] = gameObject.Parameter[5]; + + // var newDoor = new GameObjectItem("newDoor", parameterArray); + + // map.Objects.ObjectList.Add(newDoor); + //} + + //if (gameObject.Index == "gravestone" || gameObject.Index == "moveStone" || + // gameObject.Index == "moveStoneCave") + //{ + // gameObject.Parameter[3] = 0x01 << (int)gameObject.Parameter[3]; + //} + + // @HACK: we need this value to be set before calling any object constructor + if (gameObject.Index == "link2dspawner") + map.Is2dMap = true; + + map.Objects.ObjectList.Add(gameObject); + } + + public static object[] GetParameterArray(string objectId) + { + var objParameter = GameObjectTemplates.ObjectTemplates[objectId].Parameter; + + // object has only posX and posY as parameter + if (objParameter == null) + return new object[3]; + + var outParameter = new object[objParameter.Length + 3]; + + for (var i = 0; i < objParameter.Length; i++) + { + var parameter = objParameter[i]; + + // arrays need to be cloned + if (parameter is Array recArray) + outParameter[i + 3] = recArray.Clone(); + else + outParameter[i + 3] = parameter; + } + + return outParameter; + } + + public static object[] StringToParameter(string objectIndex, string[] parameters) + { + if (objectIndex == null || !GameObjectTemplates.ObjectTemplates.ContainsKey(objectIndex)) + return null; + + var parameterArray = GetParameterArray(objectIndex); + + // set the object position + parameterArray[1] = Convert.ToInt32(parameters[1]); + parameterArray[2] = Convert.ToInt32(parameters[2]); + + if (parameters.Length <= 3) + return parameterArray; + + var parCount = Math.Min(parameters.Length, parameterArray.Length); + for (var i = 3; i < parCount; i++) + if (parameters[i].Length > 0) + parameterArray[i] = ConvertToObject(parameters[i], GameObjectTemplates.GameObjectParameter[objectIndex][i].ParameterType); + + return parameterArray; + } + + public static object[] GetParameter(string objectIndex, string[] parameters) + { + if (objectIndex == null || !GameObjectTemplates.ObjectTemplates.ContainsKey(objectIndex)) + return null; + + var parameterArray = GetParameterArray(objectIndex); + + if (parameters == null) + return parameterArray; + + var length = MathHelper.Min(parameters.Length, parameterArray.Length - 3); + for (var i = 0; i < length; i++) + if (parameters[i].Length > 0) + parameterArray[i + 3] = ConvertToObject(parameters[i], GameObjectTemplates.GameObjectParameter[objectIndex][i + 3].ParameterType); + + return parameterArray; + } + + public static object ConvertToObject(string strInput, Type outputType) + { + object output; + + if (outputType == typeof(bool)) + { + bool.TryParse(strInput, out var boolOutput); + output = boolOutput; + } + else if (outputType == typeof(int)) + { + int.TryParse(strInput, out var intOutput); + output = intOutput; + } + else if (outputType == typeof(float)) + { + float.TryParse(strInput, NumberStyles.Float, CultureInfo.InvariantCulture, out var floatOutput); + output = floatOutput; + } + else if (outputType == typeof(string)) + { + output = strInput; + } + else if (outputType == typeof(Rectangle)) + { + var split = strInput.Split('.'); + var outRectangle = new Rectangle(0, 0, 0, 0); + + if (split.Length == 4) + { + if (split[0].Length > 0) + int.TryParse(split[0], out outRectangle.X); + if (split[1].Length > 0) + int.TryParse(split[1], out outRectangle.Y); + if (split[2].Length > 0) + int.TryParse(split[2], out outRectangle.Width); + if (split[3].Length > 0) + int.TryParse(split[3], out outRectangle.Height); + } + + output = outRectangle; + } + else + { + output = null; + } + + return output; + } + + public static string GetObjectString(int index, string objectIndex, object[] parameter) + { + var strOutput = ""; + var originalParameter = GameObjectTemplates.ObjectTemplates[objectIndex].Parameter; + + for (var i = 1; i < parameter.Length; i++) + { + // only write the parameter that are not equal to the original ones + if (i < 3 || !ParameterEqual(parameter[i], originalParameter[i - 3])) + { + if (parameter[i] is bool || parameter[i] is int || parameter[i] is string) + strOutput += parameter[i]; + else if (parameter[i] is float) + strOutput += ((float) parameter[i]).ToString(CultureInfo.InvariantCulture); + else if (parameter[i] is Rectangle rectangle) + strOutput += rectangle.X + "." + rectangle.Y + "." + rectangle.Width + "." + rectangle.Height; + else + { + Debug.Fail("tried to save not supported type " + objectIndex + " argument " + i); + } + } + + // saves space + if (i < parameter.Length - 1) + strOutput += ";"; + } + + return index + ";" + strOutput; + } + + public static bool ParameterEqual(object parameterOne, object parameterTwo) + { + if (parameterOne == null && parameterTwo == null) + return true; + + if (parameterOne == null || parameterTwo == null) + return false; + + // type does not match + // is this even possible? + if (parameterOne.GetType() != parameterTwo.GetType()) + return false; + + if (parameterOne is bool || parameterOne is int || parameterOne is float || parameterOne is string || + parameterOne is Vector2 || parameterOne is Rectangle || parameterOne is Color || parameterOne is Texture2D || parameterOne is Values.CollisionTypes) + return parameterOne.Equals(parameterTwo); + else if (parameterOne is Rectangle[]) + { + if (((Rectangle[])parameterOne).Length != ((Rectangle[])parameterTwo).Length) + return false; + + for (var i = 0; i < ((Rectangle[])parameterOne).Length; i++) + { + if (((Rectangle[])parameterOne)[i] != ((Rectangle[])parameterTwo)[i]) + return false; + } + } + else + { + Debug.Fail("can not compare objects from type " + parameterOne.GetType() + "; need to implement missing type"); + } + + return true; + } + } +} diff --git a/InGame/SaveLoad/SaveCondition.cs b/InGame/SaveLoad/SaveCondition.cs new file mode 100644 index 0000000..a2494a0 --- /dev/null +++ b/InGame/SaveLoad/SaveCondition.cs @@ -0,0 +1,186 @@ +using System.Collections.Generic; + +namespace ProjectZ.InGame.SaveLoad +{ + // the parser does support and, or, negate and simple brackets + // this is probably not how it should be done + // I never wrote something like this before and did not look into how it is normally done... + class SaveCondition + { + private static readonly Dictionary BracketDictionary = new Dictionary(); + + public static void TestCondition() + { + Game1.GameManager.SaveManager.SetString("enter1", "1"); + Game1.GameManager.SaveManager.SetString("et1", "1"); + Game1.GameManager.SaveManager.SetString("enter2", "1"); + Game1.GameManager.SaveManager.SetString("et2", "0"); + + var condition = GetConditionNode("(!enter1|et1)"); + var cCheck = condition.Check(); + } + + public static bool CheckCondition(string strCondition) + { + var condition = GetConditionNode(strCondition); + return condition.Check(); + } + + public static ConditionNode GetConditionNode(string strCondition) + { + BracketDictionary.Clear(); + + // prepass replaces elements in brackets with dummy elements + strCondition = PreParse(strCondition); + + // build the normal left/right tree + var node = ParseCondition(strCondition); + + // readd the bracket elements + return PostParse(node); + } + + private static string PreParse(string strCondition) + { + // does not support brackets inside brackets + while (strCondition.Contains("(")) + { + var indexOpen = strCondition.IndexOf('('); + var indexClose = strCondition.IndexOf(')'); + + var subString0 = strCondition.Substring(indexOpen + 1, indexClose - indexOpen - 1); + + var index = BracketDictionary.Count; + BracketDictionary.Add(index, subString0); + + strCondition = strCondition.Remove(indexOpen, indexClose - indexOpen + 1); + strCondition = strCondition.Insert(indexOpen, "#" + index); + } + + return strCondition; + } + + private static ConditionNode ParseCondition(string strCondition) + { + if (string.IsNullOrEmpty(strCondition)) + return new ConditionNode(); + + if (strCondition.Contains("|")) + { + var subString = strCondition.Split(new[] { '|' }, 2); + + var condition = new CNodeOr( + ParseCondition(subString[0]), + ParseCondition(subString[1])); + + return condition; + } + + if (strCondition.Contains("&")) + { + var subString = strCondition.Split(new[] { '&' }, 2); + + var condition = new CNodeAnd( + ParseCondition(subString[0]), + ParseCondition(subString[1])); + + return condition; + } + + return new CNode(strCondition.Replace("!", ""), strCondition.Contains('!')); + } + + private static ConditionNode PostParse(ConditionNode conditionNode) + { + if (conditionNode is CNode cNode) + if (cNode.SaveKey.Contains('#')) + { + var index = int.Parse(cNode.SaveKey.Replace("#", "")); + conditionNode = ParseCondition(BracketDictionary[index]); + } + if (conditionNode.Left is CNode nodeLeft) + if (nodeLeft.SaveKey.Contains('#')) + { + var index = int.Parse(nodeLeft.SaveKey.Replace("#", "")); + conditionNode.Left = ParseCondition(BracketDictionary[index]); + } + if (conditionNode.Right is CNode nodeRight) + if (nodeRight.SaveKey.Contains('#')) + { + var index = int.Parse(nodeRight.SaveKey.Replace("#", "")); + conditionNode.Right = ParseCondition(BracketDictionary[index]); + } + + if (conditionNode.Left != null) + conditionNode.Left = PostParse(conditionNode.Left); + if (conditionNode.Right != null) + conditionNode.Right = PostParse(conditionNode.Right); + + return conditionNode; + } + } + + class ConditionNode + { + public ConditionNode Left; + public ConditionNode Right; + + public virtual bool Check() => false; + } + + class CNode : ConditionNode + { + public string SaveKey; + public string Condition; + public bool Negate; + + public CNode(string saveKey, bool negate) + { + if (saveKey.Contains("=")) + { + var split = saveKey.Split("="); + SaveKey = split[0]; + Condition = split[1]; + } + else + { + SaveKey = saveKey; + Condition = "1"; + } + Negate = negate; + } + + public override bool Check() + { + return Negate ^ (Game1.GameManager.SaveManager.GetString(SaveKey, "0") == Condition); + } + } + + class CNodeAnd : ConditionNode + { + public CNodeAnd(ConditionNode left, ConditionNode right) + { + Left = left; + Right = right; + } + + public override bool Check() + { + return Left.Check() && Right.Check(); + } + } + + class CNodeOr : ConditionNode + { + public CNodeOr(ConditionNode left, ConditionNode right) + { + Left = left; + Right = right; + } + + public override bool Check() + { + return Left.Check() || Right.Check(); + } + } +} diff --git a/InGame/SaveLoad/SaveGameSaveLoad.cs b/InGame/SaveLoad/SaveGameSaveLoad.cs new file mode 100644 index 0000000..7e1784d --- /dev/null +++ b/InGame/SaveLoad/SaveGameSaveLoad.cs @@ -0,0 +1,318 @@ +using System; +using System.Collections.Generic; +using System.IO; +using Microsoft.Xna.Framework; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.SaveLoad +{ + public class SaveGameSaveLoad + { + private static SaveManager playerSaveState; + + public static string SaveFileName = "save"; + public static string SaveFileNameGame = "saveGame"; + + public static bool SaveExists(int slot) + { + return SaveManager.FileExists(Values.PathSaveFolder + "/" + SaveFileName + slot) && + SaveManager.FileExists(Values.PathSaveFolder + "/" + SaveFileNameGame + slot); + } + + public static bool CopySaveFile(int from, int to) + { + return CopySaveFile(Values.PathSaveFolder + SaveFileName + from, Values.PathSaveFolder + SaveFileName + to) && + CopySaveFile(Values.PathSaveFolder + SaveFileNameGame + from, Values.PathSaveFolder + SaveFileNameGame + to); + } + + public static bool CopySaveFile(string fromFile, string toFile) + { + if (!File.Exists(fromFile) || toFile == fromFile) + return false; + + // delete other file + if (File.Exists(toFile)) + File.Delete(toFile); + + // create file copy + File.Copy(fromFile, toFile); + + return true; + } + + public static bool DeleteSaveFile(int slot) + { + return DeleteSaveFile(Values.PathSaveFolder + SaveFileName + slot) && + DeleteSaveFile(Values.PathSaveFolder + SaveFileNameGame + slot); + } + + private static bool DeleteSaveFile(string filePath) + { + if (!File.Exists(filePath)) + return false; + + // delete the file + File.Delete(filePath); + + return true; + } + + public static void SaveGame(GameManager gameManager) + { + // save the game variables + gameManager.SaveManager.Save(Values.PathSaveFolder + "/" + SaveFileNameGame + gameManager.SaveSlot, Values.SaveRetries); + + // player variables + // is this state already created before starting a sequence? + if (playerSaveState == null) + FillSaveState(ref playerSaveState, gameManager); + + playerSaveState.Save(Values.PathSaveFolder + "/" + SaveFileName + gameManager.SaveSlot, Values.SaveRetries); + playerSaveState = null; + } + + public static void FillSaveState(GameManager gameManager) + { + FillSaveState(ref playerSaveState, gameManager); + } + + public static void ClearSaveState() + { + playerSaveState = null; + } + + private static void FillSaveState(ref SaveManager saveManager, GameManager gameManager) + { + saveManager = new SaveManager(); + + saveManager.SetString("savename", gameManager.SaveName); + saveManager.SetInt("maxHearth", gameManager.MaxHearths); + saveManager.SetInt("deathCount", gameManager.DeathCount); + saveManager.SetInt("currentHearth", gameManager.CurrentHealth); + saveManager.SetInt("cloak", gameManager.CloakType); + saveManager.SetInt("ocarinaSong", gameManager.SelectedOcarinaSong); + saveManager.SetInt("guardianAcornCount", gameManager.GuardianAcornCount); + saveManager.SetInt("pieceOfPowerCount", gameManager.PieceOfPowerCount); + + saveManager.SetBool("debugMode", gameManager.DebugMode); + + // this is only used in the main menu + var rubyObject = Game1.GameManager.GetItem("ruby"); + if (rubyObject != null) + saveManager.SetInt("rubyCount", rubyObject.Count); + + saveManager.SetString("currentMap", MapManager.ObjLink.SaveMap); + saveManager.SetInt("posX", (int)MapManager.ObjLink.SavePosition.X); + saveManager.SetInt("posY", (int)MapManager.ObjLink.SavePosition.Y); + + saveManager.SetInt("dir", MapManager.ObjLink.SaveDirection); + + if (gameManager.PlayerMapPosition != null) + { + saveManager.SetInt("mapPosX", gameManager.PlayerMapPosition.Value.X); + saveManager.SetInt("mapPosY", gameManager.PlayerMapPosition.Value.Y); + } + + var dsKeys = ""; + foreach (var strKey in gameManager.DungeonMaps.Keys) + dsKeys += strKey + ","; + saveManager.SetString("dungeonKeyNames", dsKeys); + + foreach (var miniMap in gameManager.DungeonMaps) + { + for (var y = 0; y < miniMap.Value.Tiles.GetLength(1); y++) + { + var strLine = ""; + + for (var x = 0; x < miniMap.Value.Tiles.GetLength(0); x++) + strLine += (miniMap.Value.Tiles[x, y].DiscoveryState ? "1" : "0") + ","; + + saveManager.SetString(miniMap.Key + "line" + y, strLine); + } + } + + // save equipped items + for (var i = 0; i < gameManager.Equipment.Length; i++) + { + var strItem = ""; + if (gameManager.Equipment[i] != null) + strItem += gameManager.Equipment[i].Name + ":" + gameManager.Equipment[i].Count; + + saveManager.SetString("equipment" + i, strItem); + } + + // save all the collected objects (keys, relicts,...) + for (var i = 0; i < gameManager.CollectedItems.Count; i++) + { + var strItem = ""; + strItem += gameManager.CollectedItems[i].Name + ":" + gameManager.CollectedItems[i].Count; + + if (gameManager.CollectedItems[i].LocationBounding != null) + strItem += ":" + gameManager.CollectedItems[i].LocationBounding; + + saveManager.SetString("object" + i, strItem); + } + + // save the discovered map areas + var values = new int[8]; + if (gameManager.MapVisibility != null) + for (var y = 0; y < 16; y++) + { + var index = y / 2; + for (var x = 0; x < 16; x++) + values[index] = values[index] << 1 | (gameManager.MapVisibility[x, y] ? 0x1 : 0x0); + } + + for (var i = 0; i < values.Length; i++) + saveManager.SetInt("map" + i, values[i]); + } + + public static void LoadSaveFile(GameManager gameManager, int slot) + { + // save game variables + if (!gameManager.SaveManager.LoadFile(Values.PathSaveFolder + "/" + SaveFileNameGame + slot)) + return; + + var saveManager = new SaveManager(); + + gameManager.SaveSlot = slot; + gameManager.Equipment = new GameItemCollected[GameManager.EquipmentSlots]; + gameManager.CollectedItems.Clear(); + gameManager.DungeonMaps = new Dictionary(); + + if (!saveManager.LoadFile(Values.PathSaveFolder + "/" + SaveFileName + slot)) + return; + + gameManager.SaveName = saveManager.GetString("savename"); + gameManager.MaxHearths = saveManager.GetInt("maxHearth"); + gameManager.CurrentHealth = saveManager.GetInt("currentHearth"); + gameManager.CloakType = saveManager.GetInt("cloak", 0); + gameManager.SelectedOcarinaSong = saveManager.GetInt("ocarinaSong", -1); + gameManager.GuardianAcornCount = saveManager.GetInt("guardianAcornCount", 0); + gameManager.PieceOfPowerCount = saveManager.GetInt("pieceOfPowerCount", 0); + gameManager.DeathCount = saveManager.GetInt("deathCount", 0); + + gameManager.DebugMode = saveManager.GetBool("debugMode", false); + + // so the map positions is still shown right even if the game was saved outside of the overworld + if (saveManager.ContainsValue("mapPosX")) + gameManager.PlayerMapPosition = new Point( + saveManager.GetInt("mapPosX"), + saveManager.GetInt("mapPosY")); + else + gameManager.PlayerMapPosition = null; + + // load the dungeon discovery state + var strDungeonKeys = saveManager.GetString("dungeonKeyNames"); + if (!string.IsNullOrEmpty(strDungeonKeys)) + { + var keys = strDungeonKeys.Split(','); + + for (var i = 0; i < keys.Length - 1; i++) + { + // make sure the mini map is loaded + gameManager.LoadMiniMap(keys[i]); + + // should never happen + if (!gameManager.DungeonMaps.TryGetValue(keys[i], out var map)) + continue; + + var width = map.Tiles.GetLength(0); + var height = map.Tiles.GetLength(1); + + for (var y = 0; y < height; y++) + { + var line = saveManager.GetString(keys[i] + "line" + y); + + // should never happen + if (line == null) + continue; + + var splitLine = line.Split(','); + + // should never happen + if (splitLine.Length - 1 != width) + continue; + + for (var x = 0; x < width; x++) + map.Tiles[x, y].DiscoveryState = splitLine[x] == "1"; + } + } + } + + // load equipped items + for (var i = 0; i < gameManager.Equipment.Length; i++) + { + var strItem = saveManager.GetString("equipment" + i); + + if (!string.IsNullOrEmpty(strItem)) + { + // load the collected item + gameManager.CollectItem(GetGameItem(strItem), i); + } + else + { + gameManager.Equipment[i] = null; + } + } + + // load all the collected items + string strObject; + var counter = 0; + while ((strObject = saveManager.GetString("object" + counter)) != null) + { + // add the collected object + gameManager.CollectItem(GetGameItem(strObject)); + counter++; + } + + // load the discovered map data map + gameManager.MapVisibility = new bool[16, 16]; + var values = new int[8]; + + for (var i = 0; i < values.Length; i++) + values[i] = saveManager.GetInt("map" + i); + + for (var y = 0; y < 16; y++) + { + var index = y / 2; + + for (var x = 0; x < 16; x++) + { + // check the first bit of the 32bit value + gameManager.MapVisibility[x, y] = (values[index] & 0x80000000) != 0; + values[index] = values[index] << 1; + } + } + + MapManager.ObjLink.SaveMap = saveManager.GetString("currentMap"); + MapManager.ObjLink.SavePosition.X = saveManager.GetInt("posX"); + MapManager.ObjLink.SavePosition.Y = saveManager.GetInt("posY"); + MapManager.ObjLink.SaveDirection = saveManager.GetInt("dir"); + MapManager.ObjLink.Direction = saveManager.GetInt("dir"); + + gameManager.LoadedMap = saveManager.GetString("currentMap"); + gameManager.SavePositionX = saveManager.GetInt("posX"); + gameManager.SavePositionY = saveManager.GetInt("posY"); + gameManager.SaveDirection = saveManager.GetInt("dir"); + } + + public static GameItemCollected GetGameItem(string strItem) + { + var strSplit = strItem.Split(':'); + + // set the item name and count + var item = new GameItemCollected(strSplit[0]) + { + Count = Convert.ToInt16(strSplit[1]) + }; + + // check if the item is location bound + if (strSplit.Length > 2) + item.LocationBounding = strSplit[2]; + + return item; + } + } +} diff --git a/InGame/SaveLoad/SaveLoadMap.cs b/InGame/SaveLoad/SaveLoadMap.cs new file mode 100644 index 0000000..f8549bb --- /dev/null +++ b/InGame/SaveLoad/SaveLoadMap.cs @@ -0,0 +1,532 @@ +using System; +using System.Collections.Generic; +using System.IO; +using ProjectZ.InGame.GameObjects; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Things; +#if WINDOWS +using System.Windows.Forms; +#endif + +namespace ProjectZ.InGame.SaveLoad +{ + public class SaveLoadMap + { + public static void LoadMap(Map.Map map) + { +#if WINDOWS + var openFileDialog = new OpenFileDialog + { + Filter = "Map files (*.map)|*.map", + InitialDirectory = Path.GetFullPath(Path.GetDirectoryName(map.MapFileName)), + RestoreDirectory = true, + }; + + if (openFileDialog.ShowDialog() != DialogResult.OK) + return; + + EditorLoadMap(openFileDialog.FileName, map); +#endif + } + + public static void EditorLoadMap(string filePath, Map.Map map) + { + var safeFileName = Path.GetFileName(filePath); + map.MapName = safeFileName; + + // load the map file + LoadMapFile(filePath, map); + + // create the objects + map.Objects.LoadObjects(); + + Game1.GameManager.MapManager.FinishLoadingMap(map); + } + + public static void SaveMapDialog(Map.Map map) + { +#if WINDOWS + var openFileDialog = new SaveFileDialog + { + FileName = Path.GetFileName(map.MapFileName), + InitialDirectory = Path.GetFullPath(Path.GetDirectoryName(map.MapFileName)), + RestoreDirectory = true, + Filter = "Map File (*.map)|*.map" + }; + + if (openFileDialog.ShowDialog() == DialogResult.OK) + SaveMapFile(openFileDialog.FileName, map); +#endif + } + + public static void SaveMap(Map.Map map) + { + SaveMapFile(map.MapFileName, map); + } + + // this function is used to update the file format of existing maps + public static void UpdateMaps() + { +#if WINDOWS + var openFileDialog = new OpenFileDialog() + { + Filter = "Map files (*.map)|*.map", + Multiselect = true + }; + + if (openFileDialog.ShowDialog() != DialogResult.OK) return; + + var newMap = new Map.Map(); + + foreach (var fileName in openFileDialog.FileNames) + { + // load the map file + LoadMapFile(fileName, newMap); + // save the map file + SaveMapFile(fileName, newMap); + } +#endif + } + + public static void ImportTilemap() + { +#if WINDOWS + var openFileDialog = new OpenFileDialog + { + Filter = "Text files (*.txt)|*.txt" + }; + + if (openFileDialog.ShowDialog() != DialogResult.OK) + return; + + var reader = new StreamReader(openFileDialog.FileName); + + var tilesetName = Path.GetFileName(openFileDialog.FileName).Replace(".txt", "") + ".png"; + + var mapWidth = Convert.ToInt32(reader.ReadLine()); + var mapDepth = 3; + + var mapHeight = Convert.ToInt32(reader.ReadLine()); + // create a new map + Game1.GameManager.MapManager.CurrentMap = Map.Map.CreateEmptyMap(); + Game1.GameManager.MapManager.CurrentMap.MapFileName = openFileDialog.FileName.Replace(".txt", ".map"); + Game1.GameManager.MapManager.CurrentMap.TileMap.TilesetPath = tilesetName; + + Game1.GameManager.MapManager.CurrentMap.Objects.SpawnObject(MapManager.ObjLink); + MapManager.ObjLink.Map = Game1.GameManager.MapManager.CurrentMap; + + Game1.GameManager.MapManager.CurrentMap.TileMap.ArrayTileMap = new int[mapWidth, mapHeight, mapDepth]; + + for (var y = 0; y < mapHeight; y++) + { + var strLine = reader.ReadLine(); + + if (strLine == null) continue; + + var strTiles = strLine.Split(','); + + for (var x = 0; x < mapWidth; x++) + Game1.GameManager.MapManager.CurrentMap.TileMap.ArrayTileMap[x, y, 0] = + strTiles[x] == "" ? -1 : Int32.Parse(strTiles[x]); + } + + reader.Close(); + + Game1.GameManager.MapManager.CurrentMap.HoleMap.ArrayTileMap = new int[mapWidth, mapHeight, 1]; + for (var y = 0; y < mapHeight; y++) + for (var x = 0; x < mapWidth; x++) + Game1.GameManager.MapManager.CurrentMap.HoleMap.ArrayTileMap[x, y, 0] = -1; + + // load the tileset texture + Game1.GameManager.MapManager.CurrentMap.TileMap.SetTileset(Resources.GetTexture(tilesetName)); + Game1.GameManager.MapManager.CurrentMap.HoleMap.SetTileset(Resources.GetTexture("hole.png")); + + // empty 2 and 3 layer + for (var z = 1; z < mapDepth; z++) + for (var y = 0; y < mapHeight; y++) + for (var x = 0; x < mapWidth; x++) + Game1.GameManager.MapManager.CurrentMap.TileMap.ArrayTileMap[x, y, z] = -1; + + Game1.GameManager.MapManager.CurrentMap.DigMap = new string[mapWidth, mapHeight]; +#endif + } + + public static void SaveMapFile(string savePath, Map.Map map) + { + var strTempFile = savePath + ".temp"; + var strOldFile = savePath + ".delete"; + var writer = new StreamWriter(strTempFile); + + // write down the map format version + writer.WriteLine("3"); + + writer.WriteLine(map.MapOffsetX); + writer.WriteLine(map.MapOffsetY); + + // save the tilemap + SaveTileMap(writer, map.TileMap); + + // save the map objects + SaveObjects(writer, map.Objects); + + writer.Close(); + + // change the file to the right one + if (File.Exists(savePath)) + { + File.Move(savePath, strOldFile); + File.Move(strTempFile, savePath); + File.Delete(strOldFile); + } + else + { + File.Move(strTempFile, savePath); + } + + // save the dig map + // could be included into the map file in the future + if (map.DigMap != null) + SaveDigMap(savePath, map); + } + + private static void SaveDigMap(string savePath, Map.Map map) + { + savePath += ".data"; + + var pathTemp = savePath + ".temp"; + var pathDelete = savePath + ".delete"; + + DataMapSerializer.SaveData(pathTemp, map.DigMap); + + // change the file to the right one + if (File.Exists(savePath)) + { + File.Move(savePath, pathDelete); + File.Move(pathTemp, savePath); + File.Delete(pathDelete); + } + else + { + File.Move(pathTemp, savePath); + } + } + + public static void LoadMap(string mapName, Map.Map map) + { + map.MapName = mapName; + LoadMapFile(Values.PathMapsFolder + mapName, map); + } + + public static void LoadMapFile(string fileName, Map.Map map) + { + var reader = new StreamReader(fileName); + + // reset map variables + map.Reset(); + map.MapFileName = fileName; + + var fileVersion = int.Parse(reader.ReadLine()); + + if (fileVersion > 2) + { + map.MapOffsetX = int.Parse(reader.ReadLine()); + map.MapOffsetY = int.Parse(reader.ReadLine()); + } + + // load the tilemap + LoadTileMap(reader, map.TileMap); + + CreateEmptyHoleMap(map.HoleMap, map.MapWidth, map.MapHeight); + + map.HoleMap.SetTileset(Resources.GetTexture("hole.png")); + + // create empty state map + map.StateMap = new MapStates.FieldStates[map.MapWidth, map.MapHeight]; + + map.UpdateMap = new int[map.MapWidth, map.MapHeight]; + + // load the objects + LoadObjects(reader, map); + + // close the file + reader.Close(); + + // load the dig map + if (File.Exists(fileName + ".data")) + map.DigMap = DataMapSerializer.LoadData(fileName + ".data"); + else + map.DigMap = new string[map.MapWidth, map.MapHeight]; + } + + public static void CreateEmptyHoleMap(TileMap holeMap, int width, int height) + { + holeMap.ArrayTileMap = new int[width, height, 1]; + + for (var y = 0; y < height; y++) + for (var x = 0; x < width; x++) + holeMap.ArrayTileMap[x, y, 0] = -1; + } + + public static void SaveObjects(StreamWriter writer, ObjectManager objectManager) + { + // write down the directory of the objects + writer.WriteLine(GameObjectTemplates.ObjectTemplates.Count); + + var keyToIndexDictionary = new Dictionary(); + + var counter = 0; + foreach (var entry in GameObjectTemplates.ObjectTemplates) + { + writer.WriteLine(entry.Key); + keyToIndexDictionary.Add(entry.Key, counter); + counter++; + } + + // write the free objects + objectManager.ObjectList.Sort(); + writer.WriteLine(objectManager.ObjectList.Count); + + foreach (var gameObject in objectManager.ObjectList) + { + // don't save objects that are not in the game + if (!GameObjectTemplates.ObjectTemplates.ContainsKey(gameObject.Index)) + continue; + + // create a string from the parameter of the object + var strObjectLine = MapData.GetObjectString( + keyToIndexDictionary[gameObject.Index], gameObject.Index, gameObject.Parameter); + writer.WriteLine(strObjectLine); + } + } + + private static void LoadObjects(StreamReader reader, Map.Map map) + { + // read the objects used on this map + var objCount = Convert.ToInt32(reader.ReadLine()); + var objectList = new string[objCount]; + + for (var i = 0; i < objCount; i++) + objectList[i] = reader.ReadLine(); + + // read objects + map.Objects.Clear(); + + var objectCount = Convert.ToInt32(reader.ReadLine()); + for (var i = 0; i < objectCount; i++) + { + var objectSplit = reader.ReadLine().Split(';'); + + var objectIndex = Convert.ToInt32(objectSplit[0]); + var strIndex = objectList[objectIndex]; + + // this can be used to replace object names + + //if (false) + // if (strIndex == "e1" || + // strIndex == "e2" || + // strIndex == "e3" || + // strIndex == "e4" || + // strIndex == "e5" || + // strIndex == "e9" || + // strIndex == "e12" || + // strIndex == "e15" || + // strIndex == "e16" || + // strIndex == "e17" || + // strIndex == "e19" || + // strIndex == "moblinSword" || + // strIndex == "e_pokey" || + // strIndex == "e_darknut" || + // strIndex == "e_darknutSpear" || + // strIndex == "shroudedStalfos" || + // strIndex == "e_raven" || + // strIndex == "e_moblinPigSword" || + // strIndex == "e_armos" || + // strIndex == "e_spinyBeetle" || + // strIndex == "e_tektite" || + // strIndex == "e_bomber" || + // strIndex == "e_wingedOctorok" || + // strIndex == "e20" || + // strIndex == "goponga_flower" || + // strIndex == "goponga_flower_giant") + // { + // var newParameters = new string[5]; + // newParameters[0] = objectSplit[0]; + // newParameters[1] = objectSplit[1]; + // newParameters[2] = objectSplit[2]; + // newParameters[3] = strIndex; + // newParameters[4] = ""; + + // if (objectSplit.Length > 3) + // { + // var combinedString = objectSplit[3]; + // for (var j = 4; j < objectSplit.Length; j++) + // combinedString += "$" + objectSplit[j]; + + // newParameters[4] = combinedString; + // } + + // objectSplit = newParameters; + // strIndex = "enemy_respawner"; + // } + + // check if the object exists + if (GameObjectTemplates.ObjectTemplates.ContainsKey(strIndex)) + MapData.AddObject(map, new GameObjectItem(strIndex, MapData.StringToParameter(strIndex, objectSplit))); + } + } + + private static void SaveTileMap(StreamWriter writer, TileMap tileMap) + { + // tileset path + writer.WriteLine(tileMap.TilesetPath); + + // tilemap dimensions + writer.WriteLine(tileMap.ArrayTileMap.GetLength(0)); + writer.WriteLine(tileMap.ArrayTileMap.GetLength(1)); + writer.WriteLine(tileMap.ArrayTileMap.GetLength(2)); + + // write the tilemap + for (var z = 0; z < tileMap.ArrayTileMap.GetLength(2); z++) + for (var y = 0; y < tileMap.ArrayTileMap.GetLength(1); y++) + { + var strLine = ""; + for (var x = 0; x < tileMap.ArrayTileMap.GetLength(0); x++) + { + if (tileMap.ArrayTileMap[x, y, z] >= 0) + strLine += tileMap.ArrayTileMap[x, y, z]; + + strLine += ","; + } + writer.WriteLine(strLine); + } + } + + public static void LoadTileMap(StreamReader reader, TileMap tileMap) + { + var textureName = reader.ReadLine(); + + var tileSize = 16; + if (Resources.TilesetSizes.ContainsKey(textureName)) + tileSize = Resources.TilesetSizes[textureName]; + + // load the tileset texture + tileMap.TilesetPath = textureName; + tileMap.SetTileset(Resources.GetTexture(textureName), tileSize); + + tileMap.BlurLayer = true; + + var width = Convert.ToInt32(reader.ReadLine()); + var height = Convert.ToInt32(reader.ReadLine()); + var depth = Convert.ToInt32(reader.ReadLine()); + + tileMap.ArrayTileMap = new int[width, height, depth]; + + // load the tile map + for (var z = 0; z < depth; z++) + for (var y = 0; y < height; y++) + { + var strLine = reader.ReadLine(); + var strTiles = strLine?.Split(','); + + for (var x = 0; x < width; x++) + tileMap.ArrayTileMap[x, y, z] = strTiles[x] == "" ? -1 : int.Parse(strTiles[x]); + } + } + + public static void SaveMiniMapDiscovery(string fileName, int[,] map) + { + using (var writer = new StreamWriter(fileName)) + { + writer.WriteLine(map.GetLength(0)); + writer.WriteLine(map.GetLength(1)); + + for (var y = 0; y < map.GetLength(1); y++) + { + var strLine = ""; + + for (var x = 0; x < map.GetLength(0); x++) + strLine += map[x, y] + ","; + + writer.WriteLine(strLine); + } + } + } + + public static GameManager.MiniMap LoadMiniMap(string fileName) + { + if (!File.Exists(fileName)) + return null; + + var miniMap = new GameManager.MiniMap(); + + var reader = new StreamReader(fileName); + + miniMap.OffsetX = Convert.ToInt32(reader.ReadLine()); + miniMap.OffsetY = Convert.ToInt32(reader.ReadLine()); + + var width = Convert.ToInt32(reader.ReadLine()); + var height = Convert.ToInt32(reader.ReadLine()); + miniMap.Tiles = new GameManager.MiniMapTile[width, height]; + + // read the tile map + for (var y = 0; y < height; y++) + { + var strLine = reader.ReadLine(); + var split = strLine.Split(','); + + for (var x = 0; x < width; x++) + { + var tileIndex = Convert.ToInt32(split[x]); + miniMap.Tiles[x, y] = new GameManager.MiniMapTile { TileIndex = tileIndex }; + } + } + + reader.ReadLine(); + + // read the hint map + for (var y = 0; y < height; y++) + { + var strLine = reader.ReadLine(); + var split = strLine.Split(','); + + for (var x = 0; x < width; x++) + { + var hintSplit = split[x].Split("."); + if (hintSplit.Length != 2) + continue; + + miniMap.Tiles[x, y].HintTileIndex = Convert.ToInt32(hintSplit[0]); + miniMap.Tiles[x, y].HintKey = hintSplit[1]; + } + } + + reader.ReadLine(); + + // read the tile overrides + int.TryParse(reader.ReadLine(), out var overrideCount); + if (overrideCount > 0) + { + miniMap.Overrides = new GameManager.MiniMapOverrides[overrideCount]; + + for (var i = 0; i < overrideCount; i++) + { + var strOverride = reader.ReadLine(); + var split = strOverride.Split(','); + if (split.Length != 4) + continue; + + var saveKey = split[0]; + int.TryParse(split[1], out var posX); + int.TryParse(split[2], out var posY); + int.TryParse(split[3], out var tileIndex); + + miniMap.Overrides[i] = new GameManager.MiniMapOverrides { SaveKey = saveKey, PosX = posX, PosY = posY, TileIndex = tileIndex }; + } + } + + reader.Close(); + + return miniMap; + } + } +} \ No newline at end of file diff --git a/InGame/SaveLoad/SaveManager.cs b/InGame/SaveLoad/SaveManager.cs new file mode 100644 index 0000000..3ce409e --- /dev/null +++ b/InGame/SaveLoad/SaveManager.cs @@ -0,0 +1,372 @@ +using System; +using System.Collections.Generic; +using System.IO; +using ProjectZ.InGame.Things; +using System.Globalization; +#if WINDOWS +using System.Windows.Forms; +#endif + +namespace ProjectZ.InGame.SaveLoad +{ + public class SaveManager + { + private readonly Dictionary _boolDictionary = new Dictionary(); + private readonly Dictionary _intDictionary = new Dictionary(); + private readonly Dictionary _floatDictionary = new Dictionary(); + private readonly Dictionary _stringDictionary = new Dictionary(); + + struct HistoryFrame + { + public string Key; + + public bool? BoolValueOld; + public bool? BoolValue; + + public int? IntValueOld; + public int? IntValue; + + public float? FloatValueOld; + public float? FloatValue; + + public string StringValueOld; + public string StringValue; + } + + private Stack _history = new Stack(); + private bool _historyEnabled; + + public bool HistoryEnabled + { + get { return _historyEnabled; } + } + + public void Save(string filePath, int retries) + { + for (var i = 0; i < retries; i++) + { + try + { + Save(filePath); + return; + } + catch (Exception) { } + } + +#if WINDOWS + // @TODO: this is bad; maybe try to write the file into another directory? + MessageBox.Show("Error while saving", "Saving Failed", MessageBoxButtons.OK, MessageBoxIcon.Error); +#endif + } + + private void Save(string filePath) + { + Directory.CreateDirectory(Values.PathSaveFolder); + + FileStream fileStream; + if (!File.Exists(filePath)) + fileStream = File.Create(filePath); + else + { + fileStream = File.OpenWrite(filePath); + fileStream.SetLength(0); + } + + using (var writer = new StreamWriter(fileStream)) + { + foreach (var element in _boolDictionary) + writer.WriteLine("b " + element.Key + " " + element.Value); + + foreach (var element in _intDictionary) + writer.WriteLine("i " + element.Key + " " + element.Value); + + foreach (var element in _floatDictionary) + writer.WriteLine("f " + element.Key + " " + element.Value.ToString(CultureInfo.InvariantCulture)); + + foreach (var element in _stringDictionary) + writer.WriteLine("s " + element.Key + " " + element.Value); + } + + fileStream.Close(); + fileStream.Dispose(); + } + + public void Reset() + { + _boolDictionary.Clear(); + _intDictionary.Clear(); + _stringDictionary.Clear(); + } + + public static bool FileExists(string filePath) + { + return File.Exists(filePath); + } + + public bool LoadFile(string filePath) + { + Reset(); + + if (!File.Exists(filePath)) + return false; + + for (var i = 0; i < Values.LoadRetries; i++) + { + try + { + using (var reader = new StreamReader(filePath)) + { + while (!reader.EndOfStream) + { + var line = reader.ReadLine(); + + var strSplit = line?.Split(' '); + + if (strSplit?.Length >= 3) + { + var valueString = line.Substring(strSplit[0].Length + strSplit[1].Length + 2); + + if (strSplit[0] == "b") + { + _boolDictionary.Add(strSplit[1], Convert.ToBoolean(valueString)); + } + else if (strSplit[0] == "i") + { + _intDictionary.Add(strSplit[1], Convert.ToInt32(valueString)); + } + else if (strSplit[0] == "f") + { + _floatDictionary.Add(strSplit[1], float.Parse(valueString, CultureInfo.InvariantCulture)); + } + else if (strSplit[0] == "s") + { + _stringDictionary.Add(strSplit[1], valueString); + } + } + } + } + + return true; + } + catch (Exception) { } + } + + return false; + } + + // bool + public void SetBool(string key, bool value) + { + if (_boolDictionary.ContainsKey(key)) + { + if (_historyEnabled && _boolDictionary[key] != value) + _history.Push(new HistoryFrame() { Key = key, BoolValueOld = _boolDictionary[key], BoolValue = value }); + + _boolDictionary[key] = value; + } + else + { + if (_historyEnabled) + _history.Push(new HistoryFrame() { Key = key, BoolValue = value }); + + _boolDictionary.Add(key, value); + } + + Game1.GameManager.MapManager.CurrentMap.Objects.TriggerKeyChange(); + } + + public bool GetBool(string key, bool defaultReturn) + { + if (key != null && _boolDictionary.ContainsKey(key)) + return _boolDictionary[key]; + + return defaultReturn; + } + + // int + public void SetInt(string key, int value) + { + if (_intDictionary.ContainsKey(key)) + { + if (_historyEnabled && _intDictionary[key] != value) + _history.Push(new HistoryFrame() { Key = key, IntValueOld = _intDictionary[key], IntValue = value }); + + _intDictionary[key] = value; + } + else + { + if (_historyEnabled) + _history.Push(new HistoryFrame() { Key = key, IntValue = value }); + + _intDictionary.Add(key, value); + } + + Game1.GameManager.MapManager.CurrentMap.Objects.TriggerKeyChange(); + } + + public int GetInt(string key) + { + return _intDictionary[key]; + } + + public int GetInt(string key, int defaultReturn) + { + if (_intDictionary.ContainsKey(key)) + return _intDictionary[key]; + + return defaultReturn; + } + + public void RemoveInt(string key) + { + if (_intDictionary.ContainsKey(key)) + { + if (_historyEnabled) + _history.Push(new HistoryFrame() { Key = key, IntValueOld = _intDictionary[key] }); + + _intDictionary.Remove(key); + } + + Game1.GameManager.MapManager.CurrentMap.Objects.TriggerKeyChange(); + } + + // float + public void SetFloat(string key, float value) + { + if (_floatDictionary.ContainsKey(key)) + { + if (_historyEnabled && _floatDictionary[key] != value) + _history.Push(new HistoryFrame() { Key = key, FloatValueOld = _floatDictionary[key], FloatValue = value }); + + _floatDictionary[key] = value; + } + else + { + if (_historyEnabled) + _history.Push(new HistoryFrame() { Key = key, FloatValue = value }); + + _floatDictionary.Add(key, value); + } + + Game1.GameManager.MapManager.CurrentMap.Objects.TriggerKeyChange(); + } + + public float GetFloat(string key) + { + return _floatDictionary[key]; + } + + public float GetFloat(string key, float defaultReturn) + { + if (_floatDictionary.ContainsKey(key)) + return _floatDictionary[key]; + + return defaultReturn; + } + + // string + public void SetString(string key, string value) + { + if (_stringDictionary.ContainsKey(key)) + { + if (_historyEnabled && _stringDictionary[key] != value) + _history.Push(new HistoryFrame() { Key = key, StringValueOld = _stringDictionary[key], StringValue = value }); + + _stringDictionary[key] = value; + } + else + { + if (_historyEnabled) + _history.Push(new HistoryFrame() { Key = key, StringValue = value }); + + _stringDictionary.Add(key, value); + } + + Game1.GameManager.MapManager.CurrentMap.Objects.TriggerKeyChange(); + } + + public string GetString(string key) + { + _stringDictionary.TryGetValue(key, out string outString); + return outString; + } + + public string GetString(string key, string defaultValue) + { + _stringDictionary.TryGetValue(key, out string outString); + if (outString == null) + outString = defaultValue; + return outString; + } + + public void RemoveString(string key) + { + if (_stringDictionary.ContainsKey(key)) + { + if (_historyEnabled) + _history.Push(new HistoryFrame() { Key = key, StringValueOld = _stringDictionary[key] }); + + _stringDictionary.Remove(key); + } + + Game1.GameManager.MapManager.CurrentMap.Objects.TriggerKeyChange(); + } + + public bool ContainsValue(string key) + { + return + _boolDictionary.ContainsKey(key) || + _intDictionary.ContainsKey(key) || + _floatDictionary.ContainsKey(key) || + _stringDictionary.ContainsKey(key); + } + + public void EnableHistory() + { + _historyEnabled = true; + } + + public void DisableHistory() + { + _historyEnabled = false; + _history.Clear(); + } + + public void RevertHistory() + { + while (0 < _history.Count) + { + var frame = _history.Pop(); + + if (frame.BoolValue != null) + { + if (frame.BoolValueOld != null) + _boolDictionary[frame.Key] = frame.BoolValueOld.Value; + else + _boolDictionary.Remove(frame.Key); + } + else if (frame.IntValue != null) + { + if (frame.IntValueOld != null) + _intDictionary[frame.Key] = frame.IntValueOld.Value; + else + _intDictionary.Remove(frame.Key); + } + else if (frame.FloatValue != null) + { + if (frame.FloatValueOld != null) + _floatDictionary[frame.Key] = frame.FloatValueOld.Value; + else + _floatDictionary.Remove(frame.Key); + } + else if (frame.StringValue != null) + { + if (frame.StringValueOld != null) + _stringDictionary[frame.Key] = frame.StringValueOld; + else + _stringDictionary.Remove(frame.Key); + } + } + } + } +} diff --git a/InGame/SaveLoad/SaveStateManager.cs b/InGame/SaveLoad/SaveStateManager.cs new file mode 100644 index 0000000..7f3f3e8 --- /dev/null +++ b/InGame/SaveLoad/SaveStateManager.cs @@ -0,0 +1,44 @@ +using ProjectZ.InGame.Things; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProjectZ.InGame.SaveLoad +{ + internal class SaveStateManager + { + public class SaveState + { + public string Name; + public int MaxHearth; + public int CurrentHearth; + public int CurrentRubee; + } + + public static SaveState[] SaveStates = new SaveState[SaveCount]; + + public const int SaveCount = 4; + + public static void LoadSaveData() + { + for (var i = 0; i < SaveCount; i++) + { + var saveManager = new SaveManager(); + + // check if the save was loaded or not + if (saveManager.LoadFile(Values.PathSaveFolder + "/" + SaveGameSaveLoad.SaveFileName + i)) + { + SaveStates[i] = new SaveState(); + SaveStates[i].Name = saveManager.GetString("savename"); + SaveStates[i].CurrentHearth = saveManager.GetInt("currentHearth"); + SaveStates[i].MaxHearth = saveManager.GetInt("maxHearth"); + SaveStates[i].CurrentRubee = saveManager.GetInt("rubyCount", 0); + } + else + SaveStates[i] = null; + } + } + } +} diff --git a/InGame/SaveLoad/SettingsSaveLoad.cs b/InGame/SaveLoad/SettingsSaveLoad.cs new file mode 100644 index 0000000..0c847d9 --- /dev/null +++ b/InGame/SaveLoad/SettingsSaveLoad.cs @@ -0,0 +1,65 @@ +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.SaveLoad +{ + class SettingsSaveLoad + { + private static readonly string SettingsFileName = "settings"; + + public static void LoadSettings() + { + var saveManager = new SaveManager(); + + // error loading file + if (!saveManager.LoadFile(SettingsFileName)) + return; + + Values.PathContentFolder = saveManager.GetString("ContentPath", Values.PathContentFolder); + Values.PathSaveFolder = saveManager.GetString("SavePath", Values.PathSaveFolder); + + GameSettings.GameScale = saveManager.GetInt("GameScale", GameSettings.GameScale); + GameSettings.UiScale = saveManager.GetInt("UIScale", GameSettings.UiScale); + GameSettings.MusicVolume = saveManager.GetInt("MusicVolume", GameSettings.MusicVolume); + GameSettings.EffectVolume = saveManager.GetInt("EffectVolume", GameSettings.EffectVolume); + GameSettings.EnableShadows = saveManager.GetBool("EnableShadows", GameSettings.EnableShadows); + GameSettings.Autosave = saveManager.GetBool("Autosave", GameSettings.Autosave); + GameSettings.SmoothCamera = saveManager.GetBool("SmoothCamera", GameSettings.SmoothCamera); + GameSettings.BorderlessWindowed = saveManager.GetBool("BorderlessWindowed", GameSettings.BorderlessWindowed); + GameSettings.IsFullscreen = saveManager.GetBool("IsFullscreen", GameSettings.IsFullscreen); + GameSettings.LockFps = saveManager.GetBool("LockFPS", GameSettings.LockFps); + + Values.ControllerDeadzone = saveManager.GetFloat("ControllerDeadzone", Values.ControllerDeadzone); + Game1.LanguageManager.CurrentLanguageIndex = saveManager.GetInt("CurrentLanguage", Game1.LanguageManager.CurrentLanguageIndex); + + ControlHandler.LoadButtonMap(saveManager); + } + + public static void SaveSettings() + { + var saveManager = new SaveManager(); + + saveManager.SetString("ContentPath", Values.PathContentFolder); + saveManager.SetString("SavePath", Values.PathSaveFolder); + + saveManager.SetInt("Version", 1); + saveManager.SetInt("GameScale", GameSettings.GameScale); + saveManager.SetInt("UIScale", GameSettings.UiScale); + saveManager.SetInt("MusicVolume", GameSettings.MusicVolume); + saveManager.SetInt("EffectVolume", GameSettings.EffectVolume); + saveManager.SetBool("EnableShadows", GameSettings.EnableShadows); + saveManager.SetBool("Autosave", GameSettings.Autosave); + saveManager.SetBool("SmoothCamera", GameSettings.SmoothCamera); + saveManager.SetBool("BorderlessWindowed", GameSettings.BorderlessWindowed); + saveManager.SetBool("IsFullscreen", GameSettings.IsFullscreen); + saveManager.SetBool("LockFPS", GameSettings.LockFps); + + saveManager.SetFloat("ControllerDeadzone", Values.ControllerDeadzone); + saveManager.SetInt("CurrentLanguage", Game1.LanguageManager.CurrentLanguageIndex); + + ControlHandler.SaveButtonMaps(saveManager); + + saveManager.Save(SettingsFileName, Values.SaveRetries); + } + } +} diff --git a/InGame/SaveLoad/SpriteAtlasSerialization.cs b/InGame/SaveLoad/SpriteAtlasSerialization.cs new file mode 100644 index 0000000..9d85a88 --- /dev/null +++ b/InGame/SaveLoad/SpriteAtlasSerialization.cs @@ -0,0 +1,103 @@ +using System.Collections.Generic; +using System.IO; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace ProjectZ.InGame.SaveLoad +{ + class SpriteAtlasSerialization + { + public class SpriteAtlas + { + public int Scale = 1; + public List Data = new List(); + } + + public class AtlasEntry + { + public string EntryId; + public Rectangle SourceRectangle; + public Vector2 Origin; + + public override string ToString() + { + return EntryId; + } + } + + public static void SaveSpriteAtlas(string filePath, SpriteAtlas spriteAtlas) + { + using var writer = new StreamWriter(filePath); + + // version + writer.WriteLine("1"); + writer.WriteLine(spriteAtlas.Scale); + + // this scales the source rectangle because that is the easy thing to do to support scaling in the editor + // this makes it possible to upscale the image by x and just change the scale value in the .atlas file + for (var i = 0; i < spriteAtlas.Data.Count; i++) + { + var rectangle = spriteAtlas.Data[i].SourceRectangle; + var origin = spriteAtlas.Data[i].Origin; + writer.WriteLine($"{spriteAtlas.Data[i].EntryId}:" + + $"{rectangle.X / spriteAtlas.Scale}," + + $"{rectangle.Y / spriteAtlas.Scale}," + + $"{rectangle.Width / spriteAtlas.Scale}," + + $"{rectangle.Height / spriteAtlas.Scale}," + + $"{origin.X / spriteAtlas.Scale}," + + $"{origin.Y / spriteAtlas.Scale}"); + } + } + + public static bool LoadSpriteAtlas(string filePath, SpriteAtlas spriteAtlas) + { + if (!File.Exists(filePath)) + return false; + + using var reader = new StreamReader(filePath); + + // version is currently not used + reader.ReadLine(); + + // will crash if the data does not contain integer numbers + spriteAtlas.Scale = int.Parse(reader.ReadLine()); + + while (!reader.EndOfStream) + { + var strLine = reader.ReadLine(); + var split = strLine.Split(':'); + if (split.Length == 2) + { + var newEntry = new AtlasEntry(); + newEntry.EntryId = split[0]; + + var rectangleData = split[1].Split(","); + if (rectangleData.Length >= 4) + newEntry.SourceRectangle = new Rectangle( + int.Parse(rectangleData[0]), int.Parse(rectangleData[1]), + int.Parse(rectangleData[2]), int.Parse(rectangleData[3])); + if (rectangleData.Length >= 6) + newEntry.Origin = new Vector2(int.Parse(rectangleData[4]), int.Parse(rectangleData[5])); + + spriteAtlas.Data.Add(newEntry); + } + } + + return true; + } + + public static void LoadSourceDictionary(Texture2D texture, string fileName, Dictionary dictionary) + { + var spriteAtlas = new SpriteAtlas(); + + if (!LoadSpriteAtlas(fileName, spriteAtlas)) + return; + + for (var i = 0; i < spriteAtlas.Data.Count; i++) + { + var newEntry = new DictAtlasEntry(texture, spriteAtlas.Data[i].SourceRectangle, spriteAtlas.Data[i].Origin, spriteAtlas.Scale); + dictionary.TryAdd(spriteAtlas.Data[i].EntryId, newEntry); + } + } + } +} diff --git a/InGame/Screens/EndingScreen.cs b/InGame/Screens/EndingScreen.cs new file mode 100644 index 0000000..fe9a35a --- /dev/null +++ b/InGame/Screens/EndingScreen.cs @@ -0,0 +1,41 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Screens +{ + internal class EndingScreen : Screen + { + private float _counter; + + public EndingScreen(string screenId) : base(screenId) + { + + } + + public override void OnLoad() + { + _counter = 2000; + + Game1.GameManager.ResetMusic(); + Game1.GameManager.SetMusic(67, 0); + + Game1.GbsPlayer.SetVolumeMultiplier(1.0f); + Game1.GbsPlayer.Play(); + } + + public override void Update(GameTime gameTime) + { + _counter -= Game1.DeltaTime; + if (_counter < 0) + Game1.ScreenManager.ChangeScreen(Values.ScreenNameMenu); + } + + public override void Draw(SpriteBatch spriteBatch) + { + spriteBatch.Begin(); + spriteBatch.DrawString(Resources.GameFont, "Ending", new Vector2(100, 100), Color.Red); + spriteBatch.End(); + } + } +} diff --git a/InGame/Screens/GameScreen.cs b/InGame/Screens/GameScreen.cs new file mode 100644 index 0000000..31b7b75 --- /dev/null +++ b/InGame/Screens/GameScreen.cs @@ -0,0 +1,51 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Screens +{ + internal class GameScreen : Screen + { + public GameScreen(string screenId) : base(screenId) { } + + public override void Load(ContentManager content) { } + + public override void OnLoad() + { + Game1.GameManager.OnLoad(); + } + + public override void Update(GameTime gameTime) + { + Game1.EditorUi.CurrentScreen = Values.ScreenNameGame; + + Game1.GameManager.UpdateGame(); + } + + public override void Draw(SpriteBatch spriteBatch) + { + Game1.GameManager.DrawGame(spriteBatch); + } + + public override void DrawTop(SpriteBatch spriteBatch) + { + Game1.GameManager.DrawTop(spriteBatch); + } + + public override void DrawRenderTarget(SpriteBatch spriteBatch) + { + Game1.GameManager.DrawRenderTarget(spriteBatch); + } + + public override void OnResize(int newWidth, int newHeight) + { + Game1.GameManager.OnResize(); + } + + public override void OnResizeEnd(int newWidth, int newHeight) + { + Game1.GameManager.OnResizeEnd(); + } + } +} diff --git a/InGame/Screens/IntroScreen.cs b/InGame/Screens/IntroScreen.cs new file mode 100644 index 0000000..cf5beff --- /dev/null +++ b/InGame/Screens/IntroScreen.cs @@ -0,0 +1,868 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Screens +{ + public class IntroScreen : Screen + { + private Texture2D _sprOcean; + private Texture2D _sprRain; + private Texture2D _sprIntro; + private Texture2D _sprWaves; + private Texture2D _sprCloud; + + private Animator _loadingAnimator; + private Animator _marinAnimator; + private Animator _linkAnimator; + private Animator _lightAnimation; + private Animator _linkBoatAnimator; + + private Animator[] _thunder = new Animator[2]; + private Vector2[] _thunderPositions = new Vector2[2]; + private float[] _thunderCounts = { 1000, 2000 }; + + private enum States + { + OceanCamera, + OceanPicture, + OceanThunder, + StrandFading, + StrandCamera, + StrandMarin, + StrandLogo + }; + + private States _currentState; + + private int _scale = 1; + private Vector2 _cameraCenter; + private Matrix TransformMatrix => + Matrix.CreateTranslation(new Vector3( + -(float)(Math.Round(_cameraCenter.X * _scale) / _scale), + -(float)(Math.Round(_cameraCenter.Y * _scale) / _scale), 0)) * + Matrix.CreateScale(_scale) * + Matrix.CreateTranslation(new Vector3((int)(Game1.WindowWidth * 0.5f), (int)(Game1.WindowHeight * 0.5f), 0)) * Game1.GetMatrix; + + private float _cameraState; + private Vector2 _cameraStart; + private Vector2 _cameraTarget; + + private enum MarinState + { + WalkSlow, + Walk, + Run, + Stand, + Hold, + Push, + End + }; + + private MarinState marinState; + + private MarinState[] _marinStates = + { + MarinState.WalkSlow, MarinState.Stand, MarinState.Run, MarinState.Stand, MarinState.Walk, MarinState.Stand, MarinState.Walk, MarinState.Stand, MarinState.Walk, MarinState.Stand, + MarinState.Hold, MarinState.Push, MarinState.Hold, MarinState.Push, MarinState.Hold, MarinState.Push, MarinState.Hold, MarinState.Push, MarinState.End, + }; + private int[] _marinTimes = { + 1000, 1100, 900, 1300, 200, // stand times + 2000, 500, 2100, 200, 400, 200, 250, 750 // push hold times + }; + + private Vector2[] _marinGoalPositions = + { + new Vector2(-150, 219), new Vector2(-94, 219), new Vector2(-72, 219), new Vector2(-64, 219), + new Vector2(-18, 219) + }; + + private float _marinStateCounter; + private int _marinIndex; + private int _marinWalkIndex; + private int _marinTimeIndex; + + private readonly Rectangle _oceanCloudRectangle = new Rectangle(0, 0, 32, 32); + private int _thunderIndex; + private float _thunderCount = 250; + private float _thunderTransition; + + private readonly Rectangle _ocean0Rectangle = new Rectangle(0, 288, 32, 16); + private readonly Rectangle _ocean1Rectangle = new Rectangle(0, 304, 32, 16); + private readonly Rectangle _ocean2Rectangle = new Rectangle(0, 320, 32, 16); + private readonly Rectangle _oceanRectangle = new Rectangle(0, 144, 32, 32); + + private DictAtlasEntry _spriteOceanBoat; + + private Vector2 _oceanBoatPosition; + private Vector2 _oceanPosition0; + private Vector2 _oceanPosition1; + private Vector2 _oceanPosition2; + private Vector2 _oceanPosition3; + + private readonly int[] _thunderFrame = { 1, 0, 1, 2, 1, 0, 1, 2, 1, 0, 1, 2, 1, 0 }; + private Color[] _oceanColor = { new Color(0, 32, 168), new Color(32, 32, 168), new Color(96, 96, 232) }; + + private DictAtlasEntry _spriteBackground; + private DictAtlasEntry _spriteMountain; + private DictAtlasEntry _spriteLogo0; + private DictAtlasEntry _spriteLogo1; + + private readonly Rectangle _treesRectangle = new Rectangle(0, 320, 32, 46); + private readonly Rectangle _sandRectangle = new Rectangle(0, 364, 32, 16); + private readonly Rectangle _waveRectangle = new Rectangle(0, 0, 32, 24); + + private Vector2 _logoPosition; + private float _logoState; + private float _logoCounter; + + private Vector2 _ligthPosition; + private Vector2[] _lightPositions = + { + new Vector2(7, 0), + new Vector2(41, 0), + new Vector2(2, 19), + new Vector2(0, 56), + new Vector2(34, 9), + new Vector2(55, 9), + new Vector2(72, 9), + new Vector2(96, 9), + new Vector2(34, 47), + new Vector2(55, 47), + new Vector2(72, 47), + new Vector2(90, 47), + new Vector2(119, 47), + }; + private int _lightIndex; + + private Vector2 _treePosition; + private Vector2 _mountainRightPosition; + private Vector2 _mountainLeftPosition; + private Vector2 _cloundLeftPosition; + private Vector2 _wavePosition; + private Vector2 _marinPosition; + private Vector2 _marinGoal; + + private int _currentFrame; + private float _waveCounter; + + private int _oceanFrameIndex; + + private float _oceanShoreCounter = 2000; + + private int _screenWidth = 160; + private int _screenHeight = 144; + + private float StrandFadeTime = 600; + private float _strandFadeCount; + private float _loadingTransparency = 0.75f; + + private const int Slow = 500; + private const int Fast = 200; + private readonly int[] _waveTimes = { Slow, Fast, Fast, Fast, Slow, Fast, Fast, Fast, Fast, Fast }; + + private bool _loaded; + + public IntroScreen(string screenId) : base(screenId) { } + + public override void Load(ContentManager content) + { + if (_loaded) + return; + _loaded = true; + + _spriteOceanBoat = Resources.GetSprite("intro_boat"); + + _spriteBackground = Resources.GetSprite("intro_background"); + _spriteMountain = Resources.GetSprite("intro_mountain"); + _spriteLogo0 = Resources.GetSprite("intro_logo_0"); + _spriteLogo1 = Resources.GetSprite("intro_logo_1"); + + _mountainLeftPosition.X = -_spriteBackground.SourceRectangle.Width / 2 - _spriteMountain.SourceRectangle.Width; + _mountainLeftPosition.Y = 0; + + _mountainRightPosition.X = _spriteBackground.SourceRectangle.Width / 2; + _mountainRightPosition.Y = 0; + + _treePosition.X = 0; + _treePosition.Y = _spriteBackground.SourceRectangle.Height - 16; + + _wavePosition.X = _treePosition.X; + _wavePosition.Y = _treePosition.Y + _treesRectangle.Height + 16; + + _logoPosition.X = -_spriteBackground.SourceRectangle.Width / 2 + 16; + _logoPosition.Y = 3; + + _sprOcean = Resources.GetTexture("ocean.png"); + _sprRain = Resources.GetTexture("rain.png"); + _sprIntro = Resources.GetTexture("intro.png"); + _sprCloud = Resources.GetTexture("cloud.png"); + _sprWaves = Resources.GetTexture("waves.png"); + + _loadingAnimator = AnimatorSaveLoad.LoadAnimator("Intro/loading"); + _loadingAnimator.Play("idle"); + + _thunder[0] = AnimatorSaveLoad.LoadAnimator("Intro/thunder"); + _thunder[1] = AnimatorSaveLoad.LoadAnimator("Intro/thunder"); + + _linkBoatAnimator = AnimatorSaveLoad.LoadAnimator("Intro/link_boat"); + _marinAnimator = AnimatorSaveLoad.LoadAnimator("Intro/maria"); + _linkAnimator = AnimatorSaveLoad.LoadAnimator("Intro/link"); + _lightAnimation = AnimatorSaveLoad.LoadAnimator("Intro/light"); + } + + public override void OnLoad() + { + Init(); + } + + private void Init() + { + _linkAnimator.Play("idle"); + _marinAnimator.Play("walk"); + _lightAnimation.Stop(); + + _currentState = States.OceanCamera; + _cameraCenter = new Vector2(-220, 55); + + // start playing the prologue music + Game1.GameManager.ResetMusic(); + Game1.GameManager.StopMusic(); + Game1.GameManager.SetMusic(25, 0); + + Game1.GbsPlayer.SetVolumeMultiplier(1.0f); + Game1.GbsPlayer.Play(); + // play track for 52sec +#if WINDOWS + Game1.GbsPlayer.SoundGenerator.SetStopTime(48.75f); +#endif + } + + public override void Update(GameTime gameTime) + { + if (Game1.FinishedLoading && Game1.LoadFirstSave) + { + Game1.LoadFirstSave = false; + if (SaveManager.FileExists(Values.PathSaveFolder + "/" + SaveGameSaveLoad.SaveFileName + "0")) + { + // change to the game screen + Game1.ScreenManager.ChangeScreen(Values.ScreenNameGame); + // load the save + Game1.GameManager.LoadSaveFile(0); + } + } + +#if WINDOWS + if (Game1.GbsPlayer.SoundGenerator.WasStopped && Game1.GbsPlayer.SoundGenerator.FinishedPlaying()) + { + Game1.GameManager.SetMusic(0, 0); + Game1.GbsPlayer.Play(); + } +#endif + + if (Game1.FinishedLoading && + (ControlHandler.ButtonPressed(CButtons.A) || ControlHandler.ButtonPressed(CButtons.Start))) + Game1.ScreenManager.ChangeScreen(Values.ScreenNameMenu); + + if (!Game1.FinishedLoading) + _loadingAnimator.Update(); + if (Game1.FinishedLoading) + _loadingTransparency = AnimationHelper.MoveToTarget(_loadingTransparency, 0, 0.125f * Game1.TimeMultiplier); + + UpdateOcean(); + + UpdateBeach(); + + _scale = MathHelper.Clamp(Math.Min(Game1.WindowWidth / _screenWidth, Game1.WindowHeight / _screenHeight), 1, 10); + } + + private void UpdateOcean() + { + if (_currentState == States.OceanCamera) + { + // move the camera to the center + var goalPosition = new Vector2(0, 55); + var direction = goalPosition - _cameraCenter; + if (direction.Length() < Game1.TimeMultiplier * 0.25f) + { + _currentState = States.OceanPicture; + + _linkBoatAnimator.Stop(); + _linkBoatAnimator.Play("run"); + } + else + { + direction.Normalize(); + _cameraCenter += direction * Game1.TimeMultiplier * 0.25f; + } + + _thunderIndex = 0; + for (var i = 0; i < _thunder.Length; i++) + { + _thunder[i].Update(); + if (_thunder[i].IsPlaying) + UpdateThunderIndex(_thunder[i].FrameCounter); + + _thunderCounts[i] -= Game1.DeltaTime; + if (_thunderCounts[i] <= 0) + { + var animation = Game1.RandomNumber.Next(0, 4); + _thunder[i].Play("thunder" + animation); + _thunderCounts[i] = Game1.RandomNumber.Next(2000, 4000); + + // play sound effect + Game1.GameManager.PlaySoundEffect("D378-12-0C", true); + + var randomX = (int)_cameraCenter.X - 150 + Game1.RandomNumber.Next(0, 300); + if (animation < 2) + _thunderPositions[i] = new Vector2(randomX, 28); + else + _thunderPositions[i] = new Vector2(randomX, 14); + } + } + + _oceanPosition0 = new Vector2(_cameraCenter.X * 0.1f, 60 + (int)Math.Round(Math.Sin(Game1.TotalTime / 500) * 1)); + _oceanPosition1 = new Vector2(_cameraCenter.X * 0.05f, 60 + (int)Math.Round(Math.Sin(Game1.TotalTime / 500 + 0.1) * 2)); + _oceanPosition2 = new Vector2(-_cameraCenter.X * 0.05f, 60 + (int)Math.Round(Math.Sin(Game1.TotalTime / 500 + 0.2) * 3)); + _oceanPosition3 = new Vector2(-_cameraCenter.X * 0.25f, 60 + (int)Math.Round(Math.Sin(Game1.TotalTime / 500 + 0.2) * 3)); + _oceanBoatPosition = new Vector2(-16 + _cameraCenter.X * 0.05f, 47 + (int)Math.Round(Math.Sin(Game1.TotalTime / 500) * 2.5)); + } + else if (_currentState == States.OceanPicture) + { + _cameraCenter = new Vector2(0, 0); + + _linkBoatAnimator.Update(); + + if (_oceanFrameIndex != _linkBoatAnimator.CurrentFrameIndex && + (_linkBoatAnimator.CurrentFrameIndex == 1 || _linkBoatAnimator.CurrentFrameIndex == 10)) + { + Game1.GameManager.PlaySoundEffect("D378-12-0C", true); + } + + _oceanFrameIndex = _linkBoatAnimator.CurrentFrameIndex; + + // transition to next state + if (!_linkBoatAnimator.IsPlaying) + { + _currentState = States.OceanThunder; + _thunderTransition = 0; + _thunderCount = 250; + _thunder[0].Play("null"); + } + } + else if (_currentState == States.OceanThunder) + { + if (_thunderCount < 0) + { + _thunder[0].Play("thunderboat"); + + var counter = _thunder[0].FrameCounter; + UpdateThunderIndex(counter); + + if (counter > 500) + { + _thunderTransition = ((float)counter - 500) / 700f; + if (_thunderTransition >= 1) + { + InitBeach(); + return; + } + } + } + else + _thunderCount -= Game1.DeltaTime; + + _thunder[0].Update(); + + // center the camera + _cameraCenter = new Vector2(0, 55); + + _oceanPosition0 = new Vector2(_cameraCenter.X * 0.1f, 60); + _oceanPosition1 = new Vector2(_cameraCenter.X * 0.05f, 60); + _oceanPosition2 = new Vector2(-_cameraCenter.X * 0.05f, 60); + _oceanPosition3 = new Vector2(-_cameraCenter.X * 0.25f, 60); + _oceanBoatPosition = new Vector2(-16 + _cameraCenter.X * 0.05f, 47); + + _thunderPositions[0] = new Vector2(-2, -17); + } + } + + private void UpdateThunderIndex(double time) + { + var index = (int)(time / (2000 / 60.0)); + if (index < _thunderFrame.Length) + _thunderIndex = _thunderFrame[index]; + } + + private void InitBeach() + { + _currentState = States.StrandFading; + + _cameraCenter = new Vector2(-400, 210); + _marinPosition = new Vector2(-250, 219); + + _marinAnimator.Play("stand"); + _marinAnimator.SpeedMultiplier = 1.0f; + + _logoState = 0; + _strandFadeCount = 3700 + StrandFadeTime; + _marinIndex = 0; + _marinWalkIndex = 0; + _marinTimeIndex = 0; + + NextState(); + } + + private void UpdateBeach() + { + if (_currentState != States.StrandFading && _currentState != States.StrandCamera && + _currentState != States.StrandMarin && _currentState != States.StrandLogo) + return; + + if (_currentState == States.StrandFading) + { + _strandFadeCount -= Game1.DeltaTime; + + if (_strandFadeCount < StrandFadeTime) + { + UpdateMarin(); + } + + if (_strandFadeCount <= 0) + { + _strandFadeCount = 0; + _currentState = States.StrandCamera; + } + } + // move camera to marin + else if (_currentState == States.StrandCamera) + { + UpdateMarin(); + + // reached marin? + if (_cameraCenter.X >= _marinPosition.X + 18) + { + _currentState = States.StrandMarin; + } + } + // camera follows marin directly + else if (_currentState == States.StrandMarin) + { + UpdateMarin(); + + if (_marinIndex == _marinStates.Length - 1) + { + _cameraState = 0; + _cameraStart = _cameraCenter; + _cameraTarget = new Vector2(_cameraCenter.X, _logoPosition.Y + _spriteLogo0.ScaledRectangle.Height + 5); + + _logoCounter = 0; + _currentState = States.StrandLogo; + } + } + else if (_currentState == States.StrandLogo) + { + if (!MoveCamera(0.65f)) + { + _logoCounter += Game1.DeltaTime; + + if (_logoCounter > 750 && _logoState != 1) + { + _logoState = AnimationHelper.MoveToTarget(_logoState, 1, 0.05f * Game1.TimeMultiplier); + + if (_logoState == 1) + Game1.GameManager.PlaySoundEffect("D378-25-19"); + } + + if (_logoCounter > 1500) + { + if (!_lightAnimation.IsPlaying) + { + _lightAnimation.Play("idle"); + + _lightIndex = (_lightIndex + Game1.RandomNumber.Next(1, _lightPositions.Length)) % _lightPositions.Length; + _ligthPosition = _lightPositions[_lightIndex]; + } + } + } + } + else + { + _oceanShoreCounter -= Game1.DeltaTime; + if (_oceanShoreCounter <= 0) + { + _oceanShoreCounter += 3500; + Game1.GameManager.PlaySoundEffect("D378-15-0F"); + } + } + + if (_currentState != States.StrandLogo && _strandFadeCount < StrandFadeTime) + { + UpdateCamera(new Vector2(_marinPosition.X + 18, 210), _currentState == States.StrandMarin ? 1.0f : 0.75f); + } + + _marinAnimator.Update(); + _linkAnimator.Update(); + _lightAnimation.Update(); + + _cloundLeftPosition = new Vector2(-_sprCloud.Width, 47); + + // update wave animation + _waveCounter += Game1.DeltaTime; + if (_waveCounter > _waveTimes[_currentFrame]) + { + _waveCounter -= _waveTimes[_currentFrame]; + _currentFrame = (_currentFrame + 1) % 10; + } + } + + private void UpdateCamera(Vector2 tragetPosition, float maxSpeed) + { + var direction = tragetPosition - _cameraCenter; + if (direction != Vector2.Zero) + { + var distance = direction.Length(); + + if (distance <= 0.1f * Game1.TimeMultiplier) + _cameraCenter = tragetPosition; + else + { + var speedMult = Math.Clamp(CameraFunction(distance / 12.5f), 0, maxSpeed); + + direction.Normalize(); + var cameraSpeed = direction * speedMult * Game1.TimeMultiplier; + + _cameraCenter += cameraSpeed; + } + } + } + + private float CameraFunction(float x) + { + var y = MathF.Atan(x); + + if (x > 2) + y += (x - 2) / 2; + + return y + 0.1f; + } + + private bool MoveCamera(float speed) + { + if (_cameraCenter == _cameraTarget) + return false; + + _cameraState += 0.005f * Game1.TimeMultiplier; + _cameraState = Math.Clamp(_cameraState, 0, 1); + + _cameraCenter = Vector2.Lerp(_cameraStart, _cameraTarget, 0.5f + MathF.Sin(-MathF.PI * 0.5f + _cameraState * MathF.PI) * 0.5f); + + return true; + } + + private void UpdateMarin() + { + if (marinState == MarinState.Stand) + { + _marinAnimator.Play("stand"); + + _marinStateCounter -= Game1.DeltaTime; + if (_marinStateCounter <= 0) + NextState(); + } + else if (marinState == MarinState.Walk || marinState == MarinState.WalkSlow) + { + _marinAnimator.Play("move"); + + if (_marinPosition.X < _marinGoal.X) + { + _marinPosition.X += Game1.TimeMultiplier * (marinState == MarinState.Walk ? 0.5f : 0.25f); + } + else + { + _marinPosition = _marinGoal; + NextState(); + } + } + else if (marinState == MarinState.Run) + { + _marinAnimator.SpeedMultiplier = 2.0f; + _marinAnimator.Play("move"); + + if (_marinPosition.X < _marinGoal.X) + { + _marinPosition.X += Game1.TimeMultiplier * 1.0f; + } + else + { + _marinPosition = _marinGoal; + _marinAnimator.SpeedMultiplier = 1.0f; + NextState(); + } + } + else if (marinState == MarinState.Hold) + { + _marinAnimator.Play("hold"); + _linkAnimator.Play("idle"); + + _marinStateCounter -= Game1.DeltaTime; + if (_marinStateCounter <= 0) + NextState(); + } + else if (marinState == MarinState.Push) + { + _marinAnimator.Play("push"); + _linkAnimator.Play("pushed"); + + _marinStateCounter -= Game1.DeltaTime; + if (_marinStateCounter <= 0) + NextState(); + } + } + + private void NextState() + { + marinState = _marinStates[_marinIndex]; + _marinIndex++; + + if (marinState == MarinState.Stand || marinState == MarinState.Hold || marinState == MarinState.Push) + { + _marinStateCounter = _marinTimes[_marinTimeIndex]; + _marinTimeIndex++; + } + else if (marinState == MarinState.Walk || marinState == MarinState.WalkSlow || marinState == MarinState.Run) + { + _marinGoal = _marinGoalPositions[_marinWalkIndex]; + _marinWalkIndex++; + } + } + + public override void Draw(SpriteBatch spriteBatch) + { + Game1.Graphics.GraphicsDevice.Clear(_currentState == States.OceanPicture ? Color.Black : new Color(104, 96, 248)); + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, TransformMatrix); + + DrawOcean(spriteBatch); + + DrawBeach(spriteBatch); + + spriteBatch.End(); + + // draw the loading animation + if (_loadingTransparency > 0) + { + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, Game1.GetMatrix); + _loadingAnimator.DrawBasic(spriteBatch, new Vector2( + Game1.WindowWidth - 2 * _scale, Game1.WindowHeight - 2 * _scale), Color.White * _loadingTransparency, _scale); + spriteBatch.End(); + } + } + + private void DrawOcean(SpriteBatch spriteBatch) + { + if (_currentState != States.OceanCamera && _currentState != States.OceanPicture && _currentState != States.OceanThunder) + return; + + var screenLeft = (int)Math.Floor(_cameraCenter.X) - (int)Math.Ceiling(Game1.WindowWidth / (double)_scale / 2.0); + var screenRight = (int)Math.Ceiling(_cameraCenter.X) + (int)Math.Ceiling(Game1.WindowWidth / (double)_scale / 2.0); + var screenTop = (int)Math.Floor(_cameraCenter.Y) - (int)Math.Ceiling(Game1.WindowHeight / (double)_scale / 2.0); + var screenBottom = (int)Math.Ceiling(_cameraCenter.Y) + (int)Math.Ceiling(Game1.WindowHeight / (double)_scale / 2.0); + var width = screenRight - screenLeft + 2; + var height = screenBottom - screenTop + 2; + var cloudOffset = _cameraCenter.X * 0.05f; + + if (_currentState == States.OceanCamera || _currentState == States.OceanThunder) + { + // draw the dark cloud + spriteBatch.Draw(Resources.SprWhite, new Rectangle(screenLeft, screenTop, width, -screenTop), new Color(24, 56, 40)); + + // draw the clouds + spriteBatch.Draw(_sprOcean, + new Rectangle(screenLeft, 0, width, _oceanCloudRectangle.Height), + new Rectangle(_oceanCloudRectangle.X + screenLeft - (int)cloudOffset, + _oceanCloudRectangle.Y + _thunderIndex * (_oceanCloudRectangle.Height + 16), width, + _oceanCloudRectangle.Height), + Color.White, 0, new Vector2(1 - cloudOffset % 1, 0), SpriteEffects.None, 0); + + // draw the dark sky + spriteBatch.Draw(Resources.SprWhite, new Rectangle(screenLeft, _oceanCloudRectangle.Height, width, 64), _oceanColor[_thunderIndex]); + + // draw the ocean top + var oceanAnimationOffset = _thunderIndex * 64; + spriteBatch.Draw(_sprOcean, + new Rectangle(screenLeft, (int)_oceanPosition0.Y, width, _ocean0Rectangle.Height), + new Rectangle(_ocean0Rectangle.X + screenLeft - (int)_oceanPosition0.X, + _ocean0Rectangle.Y + oceanAnimationOffset, width, _ocean0Rectangle.Height), + Color.White, 0, new Vector2(1 - _oceanPosition0.X % 1, 0), SpriteEffects.None, 0); + + // draw the ocean middle + spriteBatch.Draw(_sprOcean, + new Rectangle(screenLeft, (int)_oceanPosition1.Y, width, _ocean1Rectangle.Height), + new Rectangle(_ocean1Rectangle.X + screenLeft - (int)_oceanPosition1.X, + _ocean1Rectangle.Y + oceanAnimationOffset, width, _ocean1Rectangle.Height), + Color.White, 0, new Vector2(1 - _oceanPosition1.X % 1, 0), SpriteEffects.None, 0); + + // draw the boat + DrawHelper.DrawNormalized(spriteBatch, _spriteOceanBoat, _oceanBoatPosition, Color.White); + + // draw the ocean middle + spriteBatch.Draw(_sprOcean, + new Rectangle(screenLeft, (int)_oceanPosition2.Y, width, _ocean2Rectangle.Height), + new Rectangle(_ocean2Rectangle.X + screenLeft - (int)_oceanPosition2.X, + _ocean2Rectangle.Y + oceanAnimationOffset, width, _ocean2Rectangle.Height), + Color.White, 0, new Vector2(1 - _oceanPosition2.X % 1, 0), SpriteEffects.None, 0); + + // draw the ocean + spriteBatch.Draw(_sprOcean, + new Rectangle(screenLeft, (int)_oceanPosition3.Y + 16, width, _oceanRectangle.Height), + new Rectangle(_oceanRectangle.X + screenLeft - (int)_oceanPosition3.X, + _oceanRectangle.Y + _thunderIndex * (_oceanRectangle.Height + 16), width, _oceanRectangle.Height), + Color.White, 0, new Vector2(1 - _oceanPosition3.X % 1, 0), SpriteEffects.None, 0); + + // draw the dark ocean + spriteBatch.Draw(Resources.SprWhite, + new Rectangle(screenLeft, (int)_oceanPosition3.Y + 48, width, + screenBottom - ((int)_oceanPosition3.Y + 48)), new Color(16, 0, 104)); + } + + if (_currentState == States.OceanPicture) + { + _linkBoatAnimator.Draw(spriteBatch, Vector2.Zero, Color.White); + } + + // draw the rain + var rainOffset = new Vector2((float)(Game1.TotalTime / 2.5f + Math.Sin(Game1.TotalTime / 500) * 5), (float)Game1.TotalTime / 2.3f); + spriteBatch.Draw(_sprRain, + new Rectangle(screenLeft, screenTop, width, height), + new Rectangle(screenLeft - (int)rainOffset.X, screenTop - (int)rainOffset.Y, width, height), + Color.White, 0, new Vector2(1 - rainOffset.X % 1, 1 - rainOffset.Y % 1), SpriteEffects.None, 0); + + if (_currentState == States.OceanCamera) + { + // draw the thunder + for (var i = 0; i < _thunder.Length; i++) + _thunder[i].DrawBasic(spriteBatch, _thunderPositions[i] + new Vector2(cloudOffset, 0), Color.White); + } + else if (_currentState == States.OceanThunder) + { + // draw the thunder on top of the boat + _thunder[0].DrawBasic(spriteBatch, _thunderPositions[0] + new Vector2(cloudOffset, 0), Color.White); + + if (_thunderTransition > 0) + { + var white = MathHelper.Clamp(_thunderTransition * 1.5f, 0, 1); + spriteBatch.Draw(Resources.SprWhite, new Rectangle(screenLeft, screenTop, width, height), Color.White * white); + + // draw the boat + var boatWhite = MathHelper.Clamp(1.5f - _thunderTransition * 1.5f, 0, 1); + DrawHelper.DrawNormalized(spriteBatch, _spriteOceanBoat, _oceanBoatPosition, Color.White * boatWhite); + } + } + + //spriteBatch.Draw(Resources.SprWhite, new Rectangle(-2, 72, 4, 4), Color.Red); + } + + private void DrawBeach(SpriteBatch spriteBatch) + { + if (_currentState != States.StrandFading && _currentState != States.StrandCamera && + _currentState != States.StrandMarin && _currentState != States.StrandLogo) + return; + + var screenLeft = (int)Math.Floor(_cameraCenter.X) - (int)Math.Ceiling(Game1.WindowWidth / (double)_scale / 2.0); + var screenRight = (int)Math.Ceiling(_cameraCenter.X) + (int)Math.Ceiling(Game1.WindowWidth / (double)_scale / 2.0); + var screenTop = (int)Math.Floor(_cameraCenter.Y) - (int)Math.Ceiling(Game1.WindowHeight / (double)_scale / 2.0); + var screenBottom = (int)Math.Ceiling(_cameraCenter.Y) + (int)Math.Ceiling(Game1.WindowHeight / (double)_scale / 2.0); + var width = screenRight - screenLeft + 2; + var height = screenBottom - screenTop + 1; + + // draw the sky white + spriteBatch.Draw(Resources.SprWhite, new Rectangle( + screenLeft, screenTop, width, -screenTop + 47), new Color(248, 248, 248)); + + var mountainOffset = new Vector2((float)(Math.Round(_cameraCenter.X * 0.5f * _scale) / _scale), 0); + + // draw the clouds on the left + var cloudLeft = -_spriteBackground.ScaledRectangle.Width / 2; + if (screenLeft < cloudLeft + (int)mountainOffset.X) + spriteBatch.Draw(_sprCloud, + new Rectangle(screenLeft, (int)_cloundLeftPosition.Y, (cloudLeft + (int)mountainOffset.X) - screenLeft, _sprCloud.Height), + new Rectangle(screenLeft - (int)mountainOffset.X, 0, (cloudLeft + (int)mountainOffset.X) - screenLeft, _sprCloud.Height), + Color.White, 0, new Vector2(-mountainOffset.X % 1, 0), SpriteEffects.None, 0); + + // draw the clouds on the right + var cloudRight = _spriteBackground.ScaledRectangle.Width / 2; + if (cloudRight + (int)mountainOffset.X < screenRight) + spriteBatch.Draw(_sprCloud, + new Rectangle(cloudRight + (int)mountainOffset.X, (int)_cloundLeftPosition.Y, screenRight - (cloudRight + (int)mountainOffset.X), _sprCloud.Height), + new Rectangle(0, 0, screenRight - (cloudRight + (int)mountainOffset.X), _sprCloud.Height), + Color.White, 0, new Vector2(-mountainOffset.X % 1, 0), SpriteEffects.None, 0); + + // draw the top of the mountain + spriteBatch.Draw(_sprIntro, new Vector2(-_spriteBackground.ScaledRectangle.Width / 2, 0) + mountainOffset, _spriteBackground.ScaledRectangle, Color.White); + + // draw the left side of the mountain + spriteBatch.Draw(_sprIntro, _mountainLeftPosition + mountainOffset, _spriteMountain.SourceRectangle, + Color.White, 0, Vector2.Zero, 1, SpriteEffects.FlipHorizontally, 0); + + // draw the right side of the mountain + spriteBatch.Draw(_sprIntro, _mountainRightPosition + mountainOffset, _spriteMountain.SourceRectangle, Color.White); + + // draw the trees + var treeOffset = new Vector2(_cameraCenter.X * 0.075f, 0); + spriteBatch.Draw(_sprWaves, + new Rectangle(screenLeft, (int)_treePosition.Y, width, _treesRectangle.Height), + new Rectangle(_treesRectangle.X + screenLeft - (int)treeOffset.X, _treesRectangle.Y, width, _treesRectangle.Height), + Color.White, 0, new Vector2(1 - treeOffset.X % 1, 0), SpriteEffects.None, 0); + + // draw the strand + var strandOffset = new Vector2(-_cameraCenter.X * 0.025f, 0); + spriteBatch.Draw(_sprWaves, + new Rectangle(screenLeft, (int)_treePosition.Y + _treesRectangle.Height, width, _sandRectangle.Height), + new Rectangle(_sandRectangle.X + screenLeft - (int)strandOffset.X, _sandRectangle.Y, width, _sandRectangle.Height), + Color.White, 0, new Vector2(1 - strandOffset.X % 1, 0), SpriteEffects.None, 0); + + // draw the waves + spriteBatch.Draw(_sprWaves, + new Rectangle(screenLeft, (int)_wavePosition.Y, width, _waveRectangle.Height), + new Rectangle(_waveRectangle.X + screenLeft - (int)strandOffset.X, _waveRectangle.Y + _currentFrame * 32, width, _waveRectangle.Height), + Color.White, 0, new Vector2(1 - strandOffset.X % 1, 0), SpriteEffects.None, 0); + + // draw marin + _marinAnimator.DrawBasic(spriteBatch, _marinPosition, Color.White); + + // draw link + _linkAnimator.DrawBasic(spriteBatch, new Vector2(-8, 225), Color.White); + + // draw the logo + { + var logoHeight = (int)(_spriteLogo0.SourceRectangle.Height * (MathF.Sin(_logoState * MathF.PI - MathF.PI / 2) * 0.5f + 0.5f)); + logoHeight += logoHeight % 2; + + spriteBatch.Draw(_spriteLogo0.Texture, + new Rectangle((int)_logoPosition.X, (int)_logoPosition.Y + _spriteLogo0.SourceRectangle.Height / 2 - logoHeight / 2, + _spriteLogo0.SourceRectangle.Width, logoHeight), _spriteLogo0.ScaledRectangle, Color.White); + + var textTransparency = Math.Clamp((_logoState - 0.5f) * 2, 0, 1); + DrawHelper.DrawNormalized(spriteBatch, _spriteLogo1, _logoPosition, Color.White * textTransparency); + } + + var lightPosition = _logoPosition + _ligthPosition; + + // draw the light around the logo + if (_lightAnimation.IsPlaying) + _lightAnimation.DrawBasic(spriteBatch, lightPosition, Color.White); + + // draw the white forground for the fadein + if (_strandFadeCount > 0) + { + var white = MathHelper.Clamp(_strandFadeCount / StrandFadeTime, 0, 1); + spriteBatch.Draw(Resources.SprWhite, new Rectangle(screenLeft, screenTop, width, height), Color.White * white); + } + } + } +} \ No newline at end of file diff --git a/InGame/Screens/MenuScreen.cs b/InGame/Screens/MenuScreen.cs new file mode 100644 index 0000000..df41d07 --- /dev/null +++ b/InGame/Screens/MenuScreen.cs @@ -0,0 +1,173 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.Pages; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Screens +{ + public class MenuScreen : Screen + { + private Matrix _animationMatrix => Game1.GetMatrix * Matrix.CreateScale(Game1.UiScale); + private Animator _linkAnimation = new Animator(); + private Texture2D _sprBackground; + private Rectangle _menuRectangle; + + private Vector2 _linkPosition; + private bool _linkVisible; + + private int _scale = 3; + private int _menuWidth; + private int _menuHeight; + private int _backgroundWidth; + + private int _leftBar; + private int _rightBar; + private int _topBar; + private int _bottomBar; + private int _posX; + + public MenuScreen(string screenId) : base(screenId) { } + + public override void Load(ContentManager content) + { + _sprBackground = content.Load("Menu/menuBackground"); + + _linkAnimation = AnimatorSaveLoad.LoadAnimator("menu_link"); + _linkAnimation.Play("idle"); + + _menuWidth = Values.MinWidth - 32; + _menuHeight = Values.MinHeight - 32; + } + + public override void OnLoad() + { + Game1.UiPageManager.ClearStack(); + Game1.UiPageManager.ChangePage(typeof(MainMenuPage), null, PageManager.TransitionAnimation.TopToBottom, PageManager.TransitionAnimation.TopToBottom); + + Game1.GameManager.ResetMusic(); + Game1.GameManager.SetMusic(16, 0); + + Game1.GbsPlayer.SetVolumeMultiplier(1.0f); + Game1.GbsPlayer.Play(); + } + + public override void Update(GameTime gameTime) + { + _scale = Game1.UiScale; + + if (_scale <= 0) + _scale = 1; + + _backgroundWidth = (int)Math.Ceiling(Game1.WindowWidth / (double)(32 * _scale) + 1) * 32 * _scale; + + _menuRectangle = new Rectangle( + Game1.WindowWidth / 2 - _menuWidth * _scale / 2, + Game1.WindowHeight / 2 - _menuHeight * _scale / 2, _menuWidth * _scale, _menuHeight * _scale); + + _menuRectangle.X = _menuRectangle.X / _scale * _scale; + _menuRectangle.Y = _menuRectangle.Y / _scale * _scale; + + _topBar = (int)Math.Ceiling((Game1.WindowHeight / 2 - _menuHeight * _scale / 2) / (float)_scale / _sprBackground.Height) * _sprBackground.Height; + _bottomBar = (int)Math.Ceiling((Game1.WindowHeight / 2 - _menuHeight * _scale / 2) / (float)_scale / _sprBackground.Height) * _sprBackground.Height; + + _posX = (int)Math.Ceiling(_menuRectangle.X / (float)_scale / 32) * 32 - _menuRectangle.X / _scale; + + _leftBar = (int)Math.Ceiling((Game1.WindowWidth / 2 - _menuWidth * _scale / 2) / (float)_scale / _sprBackground.Width) * _sprBackground.Width; + _rightBar = _leftBar; + + { + // update the animation + _linkAnimation.Update(); + + _linkVisible = false; + var mainMenuPage = (MainMenuPage)Game1.UiPageManager.GetPage(typeof(MainMenuPage)); + + if (Game1.UiPageManager.PageStack.Count == 1) + foreach (var saveButton in mainMenuPage.SaveEntries) + { + if (saveButton.Selected) + { + _linkVisible = true; + _linkPosition = new Vector2(saveButton.Position.X + 22, saveButton.Position.Y + 22); + } + } + } + } + + public override void Draw(SpriteBatch spriteBatch) + { + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, Game1.GetMatrix); + + // draw the black background + spriteBatch.Draw(Resources.SprWhite, _menuRectangle, Color.Black); + + // input helper + { + var backStr = ""; + if (ControlHandler.LastKeyboardDown && ControlHandler.ButtonDictionary[CButtons.B].Keys.Length > 0) + backStr = ControlHandler.ButtonDictionary[CButtons.B].Keys[0].ToString(); + if (!ControlHandler.LastKeyboardDown && ControlHandler.ButtonDictionary[CButtons.B].Buttons.Length > 0) + backStr = ControlHandler.ButtonDictionary[CButtons.B].Buttons[0].ToString(); + var backHelp = backStr + " Back"; + + var backTextSize = Resources.GameFont.MeasureString(backHelp); + spriteBatch.DrawString(Resources.GameFont, backHelp, + new Vector2(_menuRectangle.X + 2 * _scale, _menuRectangle.Bottom - backTextSize.Y * _scale), Color.White, 0, Vector2.Zero, _scale, SpriteEffects.None, 0); + } + + { + var selectStr = ""; + if (ControlHandler.LastKeyboardDown && ControlHandler.ButtonDictionary[CButtons.A].Keys.Length > 0) + selectStr = ControlHandler.ButtonDictionary[CButtons.A].Keys[0].ToString(); + if (!ControlHandler.LastKeyboardDown && ControlHandler.ButtonDictionary[CButtons.A].Buttons.Length > 0) + selectStr = ControlHandler.ButtonDictionary[CButtons.A].Buttons[0].ToString(); + var inputHelper = selectStr + " Select"; + + var selectTextSize = Resources.GameFont.MeasureString(inputHelper); + spriteBatch.DrawString(Resources.GameFont, inputHelper, + new Vector2(_menuRectangle.Right - (selectTextSize.X + 2) * _scale, _menuRectangle.Bottom - 9 * _scale), Color.White, 0, Vector2.Zero, _scale, SpriteEffects.None, 0); + } + + spriteBatch.End(); + } + + public override void DrawTop(SpriteBatch spriteBatch) + { + spriteBatch.End(); + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, Game1.GetMatrix); + + // top + spriteBatch.Draw(_sprBackground, new Rectangle( + -_posX * _scale, _menuRectangle.Y - _topBar * _scale, _backgroundWidth, _topBar * _scale), + new Rectangle(0, 0, _backgroundWidth / _scale, _topBar), Color.White); + // bottom + spriteBatch.Draw(_sprBackground, new Rectangle( + -_posX * _scale, _menuRectangle.Bottom, _backgroundWidth, _bottomBar * _scale), + new Rectangle(0, 0, _backgroundWidth / _scale, _bottomBar), Color.White); + + // left + spriteBatch.Draw(_sprBackground, new Rectangle( + _menuRectangle.X - _leftBar * _scale, _menuRectangle.Y, _leftBar * _scale, _menuHeight * _scale), + new Rectangle(0, 0, _leftBar, _menuHeight), Color.White); + // right + spriteBatch.Draw(_sprBackground, new Rectangle( + _menuRectangle.Right, _menuRectangle.Y, _rightBar * _scale, _menuHeight * _scale), + new Rectangle(0, 0, _rightBar, _menuHeight), Color.White); + + spriteBatch.End(); + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, _animationMatrix); + + //if (_linkVisible) + // _linkAnimation.Draw(spriteBatch, new Vector2( + // _menuRectangle.X / _scale + _linkPosition.X + 8, _menuRectangle.Y / _scale + _linkPosition.Y + 32), Color.White); + + spriteBatch.End(); + spriteBatch.Begin(); + } + } +} \ No newline at end of file diff --git a/InGame/Screens/Screen.cs b/InGame/Screens/Screen.cs new file mode 100644 index 0000000..75d7527 --- /dev/null +++ b/InGame/Screens/Screen.cs @@ -0,0 +1,32 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; + +namespace ProjectZ.InGame.Screens +{ + public class Screen + { + public string Id; + + public Screen(string screenId) + { + Id = screenId.ToUpper(); + } + + public virtual void Load(ContentManager content) { } + + public virtual void Update(GameTime gameTime) { } + + public virtual void Draw(SpriteBatch spriteBatch) { } + + public virtual void DrawTop(SpriteBatch spriteBatch) { } + + public virtual void DrawRenderTarget(SpriteBatch spriteBatch) { } + + public virtual void OnResize(int newWidth, int newHeight) { } + + public virtual void OnResizeEnd(int newWidth, int newHeight) { } + + public virtual void OnLoad() { } + } +} diff --git a/InGame/Screens/ScreenManager.cs b/InGame/Screens/ScreenManager.cs new file mode 100644 index 0000000..8f3e463 --- /dev/null +++ b/InGame/Screens/ScreenManager.cs @@ -0,0 +1,124 @@ +using System.Collections.Generic; +using System.Linq; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.Editor; +using ProjectZ.InGame.Things; + +namespace ProjectZ.InGame.Screens +{ + public class ScreenManager + { + public string CurrentScreenId { get; private set; } + + private readonly List _screens = new List(); + private readonly List _newScreens = new List(); + + private Screen _currentScreen; + private Screen _nextScreen; + + private bool _changeScreen; + private bool _finishedLoading; + + public void LoadIntro(ContentManager content) + { + var introScreen = new IntroScreen(Values.ScreenNameIntro); + introScreen.Load(content); + + _screens.Add(introScreen); + + ChangeScreen(Values.ScreenNameIntro); + } + + public void Load(ContentManager content) + { + // game screens + _newScreens.Add(new MenuScreen(Values.ScreenNameMenu)); + _newScreens.Add(new GameScreen(Values.ScreenNameGame)); + _newScreens.Add(new EndingScreen(Values.ScreenEnding)); + + // editor screens + if (Game1.EditorMode) + { + _newScreens.Add(new MapEditorScreen(Values.ScreenNameEditor)); + _newScreens.Add(new TilesetEdit(Values.ScreenNameEditorTileset)); + _newScreens.Add(new TileExtractor(Values.ScreenNameEditorTilesetExtractor)); + _newScreens.Add(new AnimationScreen(Values.ScreenNameEditorAnimation)); + _newScreens.Add(new SpriteAtlasScreen(Values.ScreenNameSpriteAtlasEditor)); + } + + foreach (var screen in _newScreens) + screen.Load(content); + + _finishedLoading = true; + } + + public void Update(GameTime gameTime) + { + // add the screens after finishing the loading + // prevents problems with thread loading + if (_finishedLoading && _newScreens.Count > 0) + { + _screens.AddRange(_newScreens); + _newScreens.Clear(); + } + + if (_changeScreen) + { + _changeScreen = false; + _currentScreen = _nextScreen; + _currentScreen.OnLoad(); + } + + _currentScreen.Update(gameTime); + } + + public void Draw(SpriteBatch spriteBatch) + { + _currentScreen.Draw(spriteBatch); + } + + public void DrawTop(SpriteBatch spriteBatch) + { + _currentScreen.DrawTop(spriteBatch); + } + + public void DrawRT(SpriteBatch spriteBatch) + { + _currentScreen.DrawRenderTarget(spriteBatch); + } + + public void OnResize(int newWidth, int newHeight) + { + foreach (var screen in _screens) + screen.OnResize(newWidth, newHeight); + } + + public void OnResizeEnd(int newWidth, int newHeight) + { + foreach (var screen in _screens) + screen.OnResizeEnd(newWidth, newHeight); + } + + public void ChangeScreen(string nextScreen) + { + CurrentScreenId = nextScreen.ToUpper(); + + foreach (var screen in _screens) + { + if (screen.Id == CurrentScreenId) + { + _changeScreen = true; + _nextScreen = screen; + return; + } + } + } + + public Screen GetScreen(string screenId) + { + return _screens.FirstOrDefault(t => t.Id == screenId.ToUpper()); + } + } +} diff --git a/InGame/Tests/DialogTester.cs b/InGame/Tests/DialogTester.cs new file mode 100644 index 0000000..ac5f057 --- /dev/null +++ b/InGame/Tests/DialogTester.cs @@ -0,0 +1,50 @@ +using Microsoft.Xna.Framework.Input; +using ProjectZ.Base; +using ProjectZ.InGame.Controls; +using System.Linq; + +namespace ProjectZ.InGame.Tests +{ + public class DialogTester + { + private string[] _keyList; + private int _keyIndex; + + private const int TextboxSpeed = 8; // 250 + private float _counterA; + private bool _isRunning; + + public DialogTester() + { + _keyList = Game1.LanguageManager.Strings.Keys.ToArray(); + } + + public void Update() + { + if (InputHandler.KeyPressed(Keys.U)) + _isRunning = !_isRunning; + + if (_isRunning) + { + _counterA -= Game1.DeltaTime; + if (_counterA < 0) + { + _counterA += TextboxSpeed; + ControlHandler.DebugButtons |= CButtons.A; + + if (!Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen) + StartNextDialog(); + } + } + } + + private void StartNextDialog() + { + _keyIndex++; + if (_keyIndex >= _keyList.Length) + return; + + Game1.GameManager.StartDialog(_keyList[_keyIndex]); + } + } +} diff --git a/InGame/Tests/MapTest.cs b/InGame/Tests/MapTest.cs new file mode 100644 index 0000000..de4c66b --- /dev/null +++ b/InGame/Tests/MapTest.cs @@ -0,0 +1,405 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; +using ProjectZ.Base; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.GameObjects.Base; +using ProjectZ.InGame.GameObjects.Base.Components; +using ProjectZ.InGame.GameObjects.Dungeon; +using ProjectZ.InGame.GameObjects.Things; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; +using ProjectZ.InGame.Things; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; + +namespace ProjectZ.InGame.Tests +{ + public class MapTest + { + private Dictionary _keyList = new Dictionary(); + + private List _doorSaveList = new List(); + private List _doorList = new List(); + + private List _mapList = new List(); + private const int StartIndex = 5; + private int _currentMapIndex = StartIndex; + + private Vector2 _cameraPosition; + + private float _counter; + private float ChangeTime = 25; + + private float DigTime = 500; + private bool _hasDug; + + private float BombTime = 650; + private bool _hasBombed; + + private float BallTime = 350; + private bool _hasSpawnedBalls; + + private bool _isRunning; + private bool _paused = true; + + public MapTest() + { + var mapPaths = Directory.GetFiles(Values.PathMapsFolder); + + for (var i = 0; i < mapPaths.Length; i++) + { + if (mapPaths[i].EndsWith(".map") && !mapPaths[i].Contains("test map")) + { + _mapList.Add(mapPaths[i]); + } + } + } + + private void Start() + { + _isRunning = true; + _counter = ChangeTime; + + Game1.ScreenManager.ChangeScreen(Values.ScreenNameGame); + + LoadMap(_mapList[_currentMapIndex]); + } + + public void Update() + { + if (InputHandler.KeyPressed(Keys.V)) + SpawnCurrentTester(); + if (InputHandler.KeyPressed(Keys.B)) + SpawnBalls(); + + return; + + if (!_isRunning) + { + if (Game1.FinishedLoading) + Start(); + + return; + } + + if (InputHandler.KeyPressed(Keys.Space)) + { + _paused = !_paused; + InputHandler.ResetInputState(); + } + if (InputHandler.KeyPressed(Keys.D1)) + { + _paused = true; + OffsetMap(-1); + } + if (InputHandler.KeyPressed(Keys.D2)) + { + _paused = true; + OffsetMap(1); + } + + var direction = ControlHandler.GetMoveVector2(); + if (direction.Length() > 0) + { + _cameraPosition += direction * Game1.TimeMultiplier * 2.5f; + Game1.GameManager.MapManager.CurrentMap.CameraTarget = _cameraPosition; + MapManager.Camera.ForceUpdate(Game1.GameManager.MapManager.GetCameraTarget()); + } + + // close the textbox overlay + if (Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen) + Game1.GameManager.InGameOverlay.TextboxOverlay.Init(); + + if (!_paused) + _counter -= Game1.DeltaTime; + + + //if (_counter < BombTime && !_hasBombed) + //{ + // Bomb(); + // DestroyStones(); + // _hasBombed = true; + //} + + //if (_counter < DigTime && !_hasDug) + //{ + // Dig(); + // _hasDug = true; + //} + + //if (_counter < BallTime && !_hasSpawnedBalls) + //{ + // SpawnBallsField(); + // _hasSpawnedBalls = true; + //} + + // change map? + if (_counter < 0) + { + _counter = ChangeTime; + _hasDug = false; + _hasBombed = false; + _hasSpawnedBalls = false; + + if (!UpdateView()) + OffsetMap(1); + } + } + + private void OffsetMap(int offset) + { + _currentMapIndex = (_currentMapIndex + offset) % _mapList.Count; + if (_currentMapIndex < 0) + _currentMapIndex += _mapList.Count; + + LoadMap(_mapList[_currentMapIndex]); + } + + private bool UpdateView() + { + _cameraPosition.X += 160; + if (_cameraPosition.X > Game1.GameManager.MapManager.CurrentMap.MapWidth * Values.TileSize) + { + _cameraPosition.X = 80; + _cameraPosition.Y += 128; + } + + if (_cameraPosition.Y - 64 > Game1.GameManager.MapManager.CurrentMap.MapHeight * Values.TileSize) + return false; + + Game1.GameManager.MapManager.CurrentMap.CameraTarget = _cameraPosition; + MapManager.Camera.ForceUpdate(Game1.GameManager.MapManager.GetCameraTarget()); + + return true; + } + + private void LoadMap(string path) + { + if (_currentMapIndex == StartIndex) + { + _keyList.Clear(); + _doorSaveList.Clear(); + _doorList.Clear(); + } + + var mapFileName = Path.GetFileName(path); + + // load the map file + SaveLoadMap.LoadMap(mapFileName, Game1.GameManager.MapManager.NextMap); + + // create the objects + Game1.GameManager.MapManager.NextMap.Objects.LoadObjects(); + + var oldMap = Game1.GameManager.MapManager.CurrentMap; + Game1.GameManager.MapManager.CurrentMap = Game1.GameManager.MapManager.NextMap; + Game1.GameManager.MapManager.NextMap = oldMap; + + // center the camera + _cameraPosition = new Vector2( + 80 + Game1.GameManager.MapManager.CurrentMap.MapOffsetX * Values.TileSize, + 64 + Game1.GameManager.MapManager.CurrentMap.MapOffsetY * Values.TileSize); + Game1.GameManager.MapManager.CurrentMap.CameraTarget = _cameraPosition; + MapManager.Camera.ForceUpdate(Game1.GameManager.MapManager.GetCameraTarget()); + + //CheckMusic(); + + GetDoorList(); + + //CheckKeys(); + } + + private void GetDoorList() + { + var doors = new List(); + Game1.GameManager.MapManager.CurrentMap.Objects.GetObjectsOfType(doors, typeof(ObjDoor), 0, 0, + Game1.GameManager.MapManager.CurrentMap.MapWidth * Values.TileSize, + Game1.GameManager.MapManager.CurrentMap.MapHeight * Values.TileSize); + foreach (var door in doors) + { + var doorObj = ((ObjDoor)door); + if (doorObj._savePosition && doorObj._entryId != null) + { + _doorSaveList.Add(Game1.GameManager.MapManager.CurrentMap.MapName + " : " + doorObj._entryId); + } + if (!doorObj._savePosition && doorObj._entryId != null) + { + _doorList.Add(Game1.GameManager.MapManager.CurrentMap.MapName + " : " + doorObj._entryId); + } + } + } + + /// + /// Check if there are keys that are used in multiple cases + /// + private void CheckKeys() + { + var items = new List(); + Game1.GameManager.MapManager.CurrentMap.Objects.GetObjectsOfType(items, typeof(ObjItem), 0, 0, + Game1.GameManager.MapManager.CurrentMap.MapWidth * Values.TileSize, + Game1.GameManager.MapManager.CurrentMap.MapHeight * Values.TileSize); + foreach (var item in items) + { + var saveKey = ((ObjItem)item).SaveKey; + if (saveKey != null) + { + if (_keyList.ContainsKey(saveKey)) + { + Debug.Assert(false); + _keyList[saveKey]++; + } + else + _keyList.Add(saveKey, 1); + } + } + + var chests = new List(); + Game1.GameManager.MapManager.CurrentMap.Objects.GetObjectsOfType(chests, typeof(ObjChest), 0, 0, + Game1.GameManager.MapManager.CurrentMap.MapWidth * Values.TileSize, + Game1.GameManager.MapManager.CurrentMap.MapHeight * Values.TileSize); + foreach (var chest in chests) + { + var saveKey = ((ObjChest)chest).ItemKey; + if (saveKey != null) + { + if (_keyList.ContainsKey(saveKey)) + { + Debug.Assert(false); + _keyList[saveKey]++; + } + else + _keyList.Add(saveKey, 1); + } + } + + var barriers = new List(); + Game1.GameManager.MapManager.CurrentMap.Objects.GetObjectsOfType(barriers, typeof(ObjDestroyableBarrier), 0, 0, + Game1.GameManager.MapManager.CurrentMap.MapWidth * Values.TileSize, + Game1.GameManager.MapManager.CurrentMap.MapHeight * Values.TileSize); + foreach (var barrier in barriers) + { + var saveKey = ((ObjDestroyableBarrier)barrier).SaveKey; + if (saveKey != null) + { + if (_keyList.ContainsKey(saveKey)) + { + Debug.Assert(false); + _keyList[saveKey]++; + } + else + _keyList.Add(saveKey, 1); + } + } + } + + private void CheckMusic() + { + if (Game1.GameManager.MapManager.CurrentMap.MapMusic[0] == -1) + _paused = true; + } + + private void SpawnBalls() + { + for (var i = 0; i < 100; i++) + { + var ball = new ObjTestObject(Game1.GameManager.MapManager.CurrentMap, (int)_cameraPosition.X, (int)_cameraPosition.Y); + Game1.GameManager.MapManager.CurrentMap.Objects.SpawnObject(ball); + } + } + + private void SpawnCurrentTester() + { + for (var y = -10; y < 10; y++) + for (var x = -10; x < 10; x++) + { + var posX = (int)(MapManager.ObjLink.EntityPosition.X / 16) * 16 + 8; + var posY = (int)(MapManager.ObjLink.EntityPosition.Y / 16) * 16 + 8; + var ball = new ObjWaterCurrentTester(Game1.GameManager.MapManager.CurrentMap, posX + x * 16, posY + y * 16); + Game1.GameManager.MapManager.CurrentMap.Objects.SpawnObject(ball); + } + } + + private void SpawnBallsField() + { + for (var y = 0; y < 8; y++) + { + for (var x = 0; x < 10; x++) + { + var ballPosition = new Vector2( + (int)(_cameraPosition.X - 80) + x * Values.TileSize + 8, + (int)(_cameraPosition.Y - 64) + y * Values.TileSize + 8); + + Box box = Box.Empty; + if (!Game1.GameManager.MapManager.CurrentMap.Objects.Collision( + new Box(ballPosition.X - 2, ballPosition.Y - 2, 0, 4, 4, 8), Box.Empty, Values.CollisionTypes.Normal, 0, 0, ref box)) + { + for (int i = 0; i < 5; i++) + { + var ball = new ObjTestObject(Game1.GameManager.MapManager.CurrentMap, (int)ballPosition.X, (int)ballPosition.Y); + Game1.GameManager.MapManager.CurrentMap.Objects.SpawnObject(ball); + } + } + } + } + } + + private void Bomb() + { + for (var y = 0; y < 8; y++) + { + for (var x = 0; x < 10; x++) + { + var bombPosition = new Vector2( + (int)(_cameraPosition.X - 80) + x * Values.TileSize, + (int)(_cameraPosition.Y - 64) + y * Values.TileSize); + + Game1.GameManager.MapManager.CurrentMap.Objects.Hit(MapManager.ObjLink, new Vector2(bombPosition.X + 8, bombPosition.Y + 8), + new Box(bombPosition.X, bombPosition.Y, 0, 16, 16, 16), HitType.Bomb, 2, false); + } + } + } + + private void DestroyStones() + { + for (var y = 0; y < 8; y++) + { + for (var x = 0; x < 10; x++) + { + var position = new Vector2( + (int)(_cameraPosition.X - 80) + x * Values.TileSize, + (int)(_cameraPosition.Y - 64) + y * Values.TileSize); + + var recInteraction = new RectangleF(position.X + 4, position.Y + 4, 8, 8); + + // find an object to carry + var grabbedObject = Game1.GameManager.MapManager.CurrentMap.Objects.GetCarryableObjects(recInteraction); + if (grabbedObject != null) + { + var carriableComponent = grabbedObject.Components[CarriableComponent.Index] as CarriableComponent; + if (carriableComponent != null && carriableComponent.Owner is ObjStone) + { + carriableComponent.StartGrabbing?.Invoke(); + carriableComponent.Throw?.Invoke(new Vector2(0, 0)); + } + } + } + } + } + + private void Dig() + { + for (var y = 0; y < 8; y++) + { + for (var x = 0; x < 10; x++) + { + var digPosition = new Point( + (int)(_cameraPosition.X - 80) / Values.TileSize + x, + (int)(_cameraPosition.Y - 64) / Values.TileSize + y); + + if (Game1.GameManager.MapManager.CurrentMap.CanDig(digPosition)) + Game1.GameManager.MapManager.CurrentMap.Dig(digPosition, new Vector2(digPosition.X, digPosition.Y + 8), 0); + } + } + } + } +} diff --git a/InGame/Tests/SequenceTester.cs b/InGame/Tests/SequenceTester.cs new file mode 100644 index 0000000..08b701a --- /dev/null +++ b/InGame/Tests/SequenceTester.cs @@ -0,0 +1,59 @@ +using Microsoft.Xna.Framework.Input; +using ProjectZ.Base; +using ProjectZ.InGame.Controls; +using ProjectZ.InGame.Map; + +namespace ProjectZ.InGame.Tests +{ + public class SequenceTester + { + private int _currentSequence = 2; + + private string[] _sequences = new string[] { "bowWow", "weatherBird", "castle", "gravestone", "marinCliff", "marinBeach", "map", "towerCollapse", "shrine", "picture", "photo", "final" }; + private string _strCurrentSequence; + + private float _counterA; + private float _counterB; + + private bool _isRunning; + + public void Update() + { + if (InputHandler.KeyPressed(Keys.Z)) + { + _isRunning = !_isRunning; + } + + if (_isRunning) + { + if (!Game1.GameManager.DialogIsRunning() && + (MapManager.ObjLink.CurrentState == GameObjects.ObjLink.State.Idle || MapManager.ObjLink.CurrentState == GameObjects.ObjLink.State.Sequence) && + Game1.GameManager.InGameOverlay.GetCurrentGameSequence() == null) + { + StartNextSequence(); + } + + _counterA -= Game1.DeltaTime; + _counterB -= Game1.DeltaTime; + + if (_counterA < 0 && _strCurrentSequence != "map") + { + _counterA += 75; + ControlHandler.DebugButtons |= CButtons.A; + } + if (_counterB < 0) + { + _counterB += 150; + ControlHandler.DebugButtons |= CButtons.B; + } + } + } + + private void StartNextSequence() + { + _strCurrentSequence = _sequences[_currentSequence]; + Game1.GameManager.InGameOverlay.StartSequence(_strCurrentSequence); + _currentSequence = (_currentSequence + 1) % _sequences.Length; + } + } +} diff --git a/InGame/Things/AnimationHelper.cs b/InGame/Things/AnimationHelper.cs new file mode 100644 index 0000000..9446a27 --- /dev/null +++ b/InGame/Things/AnimationHelper.cs @@ -0,0 +1,72 @@ +using System; +using Microsoft.Xna.Framework; + +namespace ProjectZ.InGame.Things +{ + class AnimationHelper + { + public static Vector2[] DirectionOffset = + { + new Vector2(-1, 0), new Vector2(0, -1), new Vector2(1, 0), new Vector2(0, 1) + }; + + /// + /// Offsets the direction and make sure if stays between 0 and 3 + /// + /// Init direction Value before the offset gets added + /// Values between -3 and 3 + /// Returns the direction value with the offset added and looped to be between 0 and 3 + public static int OffsetDirection(int direction, int offset) + { + direction += offset; + + if (direction >= 4) + direction %= 4; + if (direction < 0) + direction += 4; + + return direction; + } + + public static int GetDirection(Vector2 direction, float rotationOffset = MathF.PI * 1.25f) + { + var degree = MathHelper.ToDegrees((float)(Math.Atan2(direction.Y, direction.X) + rotationOffset)); + + while (degree >= 360) + degree -= 360; + + return (int)(degree / 90); + } + + public static Vector2 RotateVector(Vector2 input, float angle) + { + return new Vector2( + (float)(Math.Cos(angle) * input.X - Math.Sin(angle) * input.Y), + (float)(Math.Sin(angle) * input.X + Math.Cos(angle) * input.Y)); + } + + public static float MoveToTarget(float currentValue, float targetValue, float maxAmount) + { + if (Math.Abs(currentValue - targetValue) < maxAmount) + return targetValue; + + if (currentValue < targetValue) + currentValue += maxAmount; + if (currentValue > targetValue) + currentValue -= maxAmount; + + return currentValue; + } + + public static Vector2 MoveToTarget(Vector2 currentVelocity, Vector2 targetVelocity, float maxAmount) + { + var direction = targetVelocity - currentVelocity; + if (direction.Length() <= maxAmount) + return targetVelocity; + + direction.Normalize(); + var newVelocity = currentVelocity + direction * maxAmount; + return newVelocity; + } + } +} diff --git a/InGame/Things/CollisionTypes.cs b/InGame/Things/CollisionTypes.cs new file mode 100644 index 0000000..4bea0fe --- /dev/null +++ b/InGame/Things/CollisionTypes.cs @@ -0,0 +1,71 @@ +using System; + +namespace ProjectZ.InGame.Things +{ + public partial class Values + { + [Flags] + public enum CollisionTypes + { + None = 0x00, + Normal = 0x01, + Hole = 0x02, + PlayerItem = 0x04, + Player = 0x08, + Enemy = 0x10, + Ladder = 0x20, + LadderTop = 0x40, + NPCWall = 0x80, + Item = 0x100, + DrownExclude = 0x200, + Hookshot = 0x400, + DeepWater = 0x800, + MovingPlatform = 0x1000, + RaftExit = 0x2000, + PushIgnore = 0x4000, // objects the player should not push (play the push animation) + Destroyable = 0x8000, + ThrowIgnore = 0x10000, + ThrowWeaponIgnore = 0x20000 + } + + [Flags] + public enum BodyCollision + { + None = 0, + Floor = 1, + Left = 2, + Right = 4, + Top = 8, + Bottom = 16, + Horizontal = 32, + Vertical = 64 + } + + [Flags] + public enum HitCollision + { + None, + Enemy = 1, + Blocking = 2, + NoneBlocking = 4, // weapons like the boomerang will move through the object + Particle = 8, + Repelling = 16, + RepellingParticle = 8 + 16, + + Repelling0 = 32, // repell much + Repelling1 = 64, // repell not so much + } + + [Flags] + public enum GameObjectTag + { + None = 0, + Enemy = 1, + Trap = 2, + Damage = 4, + Hole = 8, + Lamp = 16, + Ocarina = 32 + } + } +} diff --git a/InGame/Things/CubicBezier.cs b/InGame/Things/CubicBezier.cs new file mode 100644 index 0000000..b7ee10e --- /dev/null +++ b/InGame/Things/CubicBezier.cs @@ -0,0 +1,95 @@ +using System; +using Microsoft.Xna.Framework; + +namespace ProjectZ.InGame.Things +{ + class CubicBezier + { + private Vector2 _firstPoint; + private Vector2 _secondPoint; + + private readonly int _dataCount; + public float[] Data; + + public CubicBezier(int dataCount, Vector2 firstPoint, Vector2 secondPoint) + { + _dataCount = dataCount; + Data = new float[_dataCount]; + + SetData(firstPoint, secondPoint); + } + + public void SetData(Vector2 firstPoint, Vector2 secondPoint) + { + _firstPoint = firstPoint; + _secondPoint = secondPoint; + FillData(); + } + + private void FillData() + { + var lastValue = EvaluatePosition(0); + var dataSize = 1 / (float)(Data.Length - 1); + var stepSize = 1 / (float)_dataCount / 2; + var position = stepSize; + var dataIndex = 0; + + for (var i = 0; i < Data.Length; i++) + Data[i] = 0; + Data[_dataCount - 1] = 1; + + while (true) + { + var newValue = EvaluatePosition(position); + position += stepSize; + + while (newValue.X >= dataIndex * dataSize) + { + var distance = newValue.X - lastValue.X; + var indexDistance = dataIndex * dataSize - lastValue.X; + var percentage = indexDistance / distance; + + Data[dataIndex] = Vector2.Lerp(lastValue, newValue, percentage).Y; + dataIndex++; + } + + lastValue = newValue; + + if (position >= 1 || dataIndex >= Data.Length - 1) + break; + } + } + + /// + /// Get the interpolated y value from the given x value. + /// + /// The value on the x axis where we want to get the y value. + /// + public float EvaluateX(float x) + { + x = MathHelper.Clamp(x, 0, 1); + + // interpolate between two points to get the value at "time" + var index = (int)(x * (_dataCount - 1)); + var dataSize = 1 / (_dataCount - 1.0f); + var percentage = (x % dataSize) / dataSize; + var value = Data[index] * (1 - percentage); + if (index < _dataCount - 1) + value += Data[index + 1] * percentage; + + return value; + } + + public Vector2 EvaluatePosition(float time) + { + time = MathHelper.Clamp(time, 0, 1); + + var point = // (float)Math.Pow(1 - time, 3) * Vector2.Zero + + (float)(3 * Math.Pow(1 - time, 2) * time) * _firstPoint + + ((3 * (1 - time) * time * time) * _secondPoint) + + (float)Math.Pow(time, 3) * Vector2.One; + + return point; + } + } +} diff --git a/InGame/Things/DrawHelper.cs b/InGame/Things/DrawHelper.cs new file mode 100644 index 0000000..6993f48 --- /dev/null +++ b/InGame/Things/DrawHelper.cs @@ -0,0 +1,200 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; + +namespace ProjectZ.InGame.Things +{ + class DrawHelper + { + // more then 1000 will only make sense on a high resolution with a small game scale + public const int MaxShadowIndices = 1000; + public static int CurrentShadowIndex; + public static short[] IndexDataShadow = new short[MaxShadowIndices * 6]; + public static float ShadowHeight; + public static float ShadowOffset; + public static Texture2D LastShadowTexture; + + private static Matrix projectionMatrix; + private static Matrix outMatrix; + public static VertexPositionPositionColorTexture[] ShadowVertexArray = new VertexPositionPositionColorTexture[MaxShadowIndices * 4]; + + public static void StartShadowDrawing() + { + //projectionMatrix = Matrix.CreateOrthographicOffCenter(0, + // Game1.Graphics.PreferredBackBufferWidth, Game1.Graphics.PreferredBackBufferHeight, 0, 0, -1); + //outMatrix = MapManager.Camera.TransformMatrix * projectionMatrix; + + //Resources.NextShadowEffect.Parameters["WorldViewProjection"].SetValue(outMatrix); + + //Game1.SpriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, Resources.NextShadowEffect, MapManager.Camera.TransformMatrix); + + LastShadowTexture = null; + CurrentShadowIndex = 0; + } + + public static void EndShadowDrawing() + { + //Game1.SpriteBatch.End(); + + if (CurrentShadowIndex > 0) + DrawIndexedDataNew(); + } + + // TODO_End: this should be done using normal spritebatch.Draw() + public static void DrawShadow(Texture2D sprImage, Vector2 drawPosition, Rectangle sourceRectangle, + float drawWidth, float drawHeight, bool mirror, float height, float rotation, Color color) + { + //Game1.SpriteBatch.Draw(sprImage, drawPosition, sourceRectangle, color); + + if (LastShadowTexture != null && (LastShadowTexture != sprImage || + CurrentShadowIndex >= MaxShadowIndices || ShadowHeight != height || ShadowOffset != rotation)) + { + // draw the stored data + DrawIndexedDataNew(); + CurrentShadowIndex = 0; + } + + SetVertexPtIndexed(ShadowVertexArray, CurrentShadowIndex * 4, drawPosition, sourceRectangle, + drawWidth, drawHeight, sprImage.Width, sprImage.Height, mirror, color); + + SetIndexBuffer(IndexDataShadow, CurrentShadowIndex * 6, CurrentShadowIndex * 4); + + CurrentShadowIndex++; + + ShadowHeight = height; + ShadowOffset = rotation; + LastShadowTexture = sprImage; + } + + public struct VertexPositionPositionColorTexture : IVertexType + { + public Vector2 Position; + public Vector2 TextureCoordinate; + public Vector2 UpperLeftPosition; + public Vector2 SourceSize; + public Color Color; + + public VertexPositionPositionColorTexture( + Vector2 position, Vector2 textureCoordinate, Vector2 upperLeftPosition, Vector2 sourceSize, Color color) + { + Position = position; + TextureCoordinate = textureCoordinate; + UpperLeftPosition = upperLeftPosition; + SourceSize = sourceSize; + Color = color; + } + + public static readonly VertexDeclaration VertexDeclaration; + + VertexDeclaration IVertexType.VertexDeclaration => VertexDeclaration; + + static VertexPositionPositionColorTexture() + { + var elements = new[] + { + new VertexElement(0, VertexElementFormat.Vector2, VertexElementUsage.Position, 0), + new VertexElement(8, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0), + new VertexElement(16, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 1), + new VertexElement(24, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 2), + new VertexElement(32, VertexElementFormat.Color, VertexElementUsage.Color, 0), + }; + VertexDeclaration = new VertexDeclaration(elements); + } + } + + public static void SetVertexPtIndexed( + VertexPositionPositionColorTexture[] buffer, int index, + Vector2 position, Rectangle sourceRectangle, float drawWidth, float drawHeight, + int textureWidth, int textureHeight, bool mirror, Color color) + { + var posLeft = position.X; + var posRight = position.X + drawWidth;// sourceRectangle.Width; + var posTop = position.Y; + var posBottom = position.Y + drawHeight;// sourceRectangle.Height; + + var left = (!mirror ? sourceRectangle.X : sourceRectangle.Right) / (float)textureWidth; + var right = (!mirror ? sourceRectangle.Right : sourceRectangle.X) / (float)textureWidth; + var top = sourceRectangle.Y / (float)textureHeight; + var bottom = sourceRectangle.Bottom / (float)textureHeight; + + buffer[index + 0] = new VertexPositionPositionColorTexture( + new Vector2(posLeft, posTop), new Vector2(left, top), position, + new Vector2(sourceRectangle.Width, sourceRectangle.Height), color); + buffer[index + 1] = new VertexPositionPositionColorTexture( + new Vector2(posRight, posTop), new Vector2(right, top), position, + new Vector2(sourceRectangle.Width, sourceRectangle.Height), color); + buffer[index + 2] = new VertexPositionPositionColorTexture( + new Vector2(posLeft, posBottom), new Vector2(left, bottom), position, + new Vector2(sourceRectangle.Width, sourceRectangle.Height), color); + buffer[index + 3] = new VertexPositionPositionColorTexture( + new Vector2(posRight, posBottom), new Vector2(right, bottom), position, + new Vector2(sourceRectangle.Width, sourceRectangle.Height), color); + } + + public static void DrawIndexedDataNew() + { + projectionMatrix = Matrix.CreateOrthographicOffCenter(0, + Game1.GameManager.CurrentRenderWidth, Game1.GameManager.CurrentRenderHeight, 0, 0, -1); + outMatrix = MapManager.Camera.TransformMatrix * projectionMatrix; + + Resources.FullShadowEffect.Parameters["xViewProjection"].SetValue(outMatrix); + Resources.FullShadowEffect.Parameters["height"].SetValue(ShadowHeight); + Resources.FullShadowEffect.Parameters["offsetX"].SetValue(ShadowOffset); + + foreach (var pass in Resources.FullShadowEffect.CurrentTechnique.Passes) + { + pass.Apply(); + Game1.Graphics.GraphicsDevice.Textures[0] = LastShadowTexture; + Game1.Graphics.GraphicsDevice.DrawUserIndexedPrimitives( + PrimitiveType.TriangleList, ShadowVertexArray, 0, CurrentShadowIndex * 4, IndexDataShadow, 0, CurrentShadowIndex * 2); + } + } + + public static void SetIndexBuffer(short[] buffer, int position, int offset) + { + buffer[position + 0] = (short)(offset + 0); + buffer[position + 1] = (short)(offset + 1); + buffer[position + 2] = (short)(offset + 2); + + buffer[position + 3] = (short)(offset + 2); + buffer[position + 4] = (short)(offset + 1); + buffer[position + 5] = (short)(offset + 3); + } + + public static void DrawLight(SpriteBatch spriteBatch, Rectangle lightRectangle, Color lightColor) + { + spriteBatch.Draw(Resources.SprLight, lightRectangle, lightColor); + } + + public static void DrawCenter(SpriteBatch spriteBatch, Texture2D sprTexture, Point offset, + Rectangle centerRectangle, Rectangle sourceRectangle, int scale) + { + spriteBatch.Draw(sprTexture, new Rectangle( + offset.X + (centerRectangle.X + centerRectangle.Width / 2 - sourceRectangle.Width / 2) * scale, + offset.Y + (centerRectangle.Y + centerRectangle.Height / 2 - sourceRectangle.Height / 2) * scale, + sourceRectangle.Width * scale, + sourceRectangle.Height * scale), sourceRectangle, Color.White); + } + + public static void DrawNormalized(SpriteBatch spriteBatch, Texture2D texture, + Vector2 position, Rectangle sourceRectangle, Color color, float scale = 1.0f) + { + var normalizedPosition = new Vector2( + (float)Math.Round(position.X * MapManager.Camera.Scale) / MapManager.Camera.Scale, + (float)Math.Round(position.Y * MapManager.Camera.Scale) / MapManager.Camera.Scale); + + spriteBatch.Draw(texture, normalizedPosition, sourceRectangle, color, 0, Vector2.Zero, new Vector2(scale), SpriteEffects.None, 0); + } + + public static void DrawNormalized(SpriteBatch spriteBatch, DictAtlasEntry sprite, Vector2 position, Color color) + { + var normalizedPosition = new Vector2( + (float)Math.Round(position.X * MapManager.Camera.Scale) / MapManager.Camera.Scale, + (float)Math.Round(position.Y * MapManager.Camera.Scale) / MapManager.Camera.Scale); + + spriteBatch.Draw(sprite.Texture, normalizedPosition, sprite.ScaledRectangle, color, 0, sprite.Origin, new Vector2(sprite.Scale), SpriteEffects.None, 0); + } + } +} diff --git a/InGame/Things/GameItem.cs b/InGame/Things/GameItem.cs new file mode 100644 index 0000000..fc9670b --- /dev/null +++ b/InGame/Things/GameItem.cs @@ -0,0 +1,87 @@ +using Microsoft.Xna.Framework; +using ProjectZ.InGame.SaveLoad; + +namespace ProjectZ.InGame.Things +{ + public class GameItem + { + public readonly DictAtlasEntry Sprite; + public readonly Rectangle? SourceRectangle; + + // show a different sprite when drawn on the map compared to the one shown in the inventory + public readonly DictAtlasEntry MapSprite; + public readonly bool AnimateSprite; + + public readonly string Name; + public readonly string PickUpDialog; + + public readonly string SoundEffectName; + public readonly int MusicName; + public readonly bool TurnDownMusic; + + public readonly int Level; + + public readonly int Count; + public readonly int MaxCount; + public readonly int DrawLength; + + public readonly bool IsRelict; + public readonly bool Equipable; + + public readonly bool ShowEffect; + public readonly int ShowAnimation; + public readonly int ShowTime; + + public GameItem( + DictAtlasEntry sprite = null, + DictAtlasEntry mapSprite = null, + bool animateSprite = false, + string name = null, string pickUpDialog = null, + string soundEffectName = null, int musicName = -1, bool turnDownMusic = false, + int level = 0, + int count = 0, int maxCount = 0, int drawLength = 2, + bool isRelict = false, bool equipable = false, + bool showEffect = false, int showAnimation = 0, int showTime = 250) + { + Sprite = sprite; + MapSprite = mapSprite; + + if (sprite != null) + SourceRectangle = sprite.SourceRectangle; + + AnimateSprite = animateSprite; + + Name = name; + PickUpDialog = pickUpDialog; + + SoundEffectName = soundEffectName; + MusicName = musicName; + TurnDownMusic = turnDownMusic; + + Level = level; + + Count = count; + MaxCount = maxCount; + DrawLength = drawLength; + + IsRelict = isRelict; + Equipable = equipable; + + ShowEffect = showEffect; + ShowAnimation = showAnimation; + ShowTime = showTime; + } + } + + public class GameItemCollected + { + public string Name; + public string LocationBounding; + public int Count; + + public GameItemCollected(string name) + { + Name = name; + } + } +} diff --git a/InGame/Things/GameManager.cs b/InGame/Things/GameManager.cs new file mode 100644 index 0000000..ebf93ba --- /dev/null +++ b/InGame/Things/GameManager.cs @@ -0,0 +1,1501 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Audio; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.GameSystems; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.Overlay; +using ProjectZ.InGame.SaveLoad; + +namespace ProjectZ.InGame.Things +{ + public class GameManager + { + public struct MiniMapTile + { + public int TileIndex; + public bool DiscoveryState; + + public int HintTileIndex; + public string HintKey; + } + + public struct MiniMapOverrides + { + public string SaveKey; + public int PosX; + public int PosY; + public int TileIndex; + } + + public class MiniMap + { + public int OffsetX; + public int OffsetY; + + public MiniMapTile[,] Tiles; + + public MiniMapOverrides[] Overrides; + } + + private class PlayingSoundEffect + { + public bool LowerMusicVolume; + + public float Volume; + public double EndTime; + + public SoundEffectInstance Instance; + } + + // _activeRenderTarget == null ??? + public Matrix GetMatrix => Matrix.CreateScale(new Vector3( + (float)_activeRenderTarget.Width / (int)(Game1.WindowWidth * _scaleMultiplier), + (float)_activeRenderTarget.Height / (int)(Game1.WindowHeight * _scaleMultiplier), 0)); + + public int CurrentRenderWidth; + public int CurrentRenderHeight; + public float CurrentRenderScale; + + public int BlurRenderTargetWidth => (int)(Game1.RenderWidth / MapManager.Camera.Scale / 2) + 8; + public int BlurRenderTargetHeight => (int)(Game1.RenderHeight / MapManager.Camera.Scale / 2) + 8; + + public int SideBlurRenderTargetWidth => BlurRenderTargetWidth * 2; + public int SideBlurRenderTargetHeight => BlurRenderTargetHeight * 2; + + public MapManager MapManager = new MapManager(); + public OverlayManager InGameOverlay = new OverlayManager(); + public SaveManager SaveManager = new SaveManager(); + public ItemManager ItemManager = new ItemManager(); + + public float ForestColorState; + public bool UseShockEffect; + + public const int EquipmentSlots = 12; + public GameItemCollected[] Equipment = new GameItemCollected[EquipmentSlots]; + public List CollectedItems = new List(); + + // sound effects that are currently playing + private Dictionary CurrentSoundEffects = new Dictionary(); + + // dungeon maps + public Dictionary DungeonMaps = new Dictionary(); + + public Dictionary GameSystems = new Dictionary(); + + public Point PlayerDungeonPosition; + + // can be null if the player never left the house in the beginning + public Point? PlayerMapPosition; + + public bool[,] MapVisibility; + + public string SaveName = "Link"; + + public float DrawPlayerOnTopPercentage; + + public bool FreezeWorldAroundPlayer; + + // save game data + public string LoadedMap; + public int SavePositionX; + public int SavePositionY; + public int SaveDirection; + public int SaveSlot; + + private float _shakeCountX; + private float _shakeCountY; + private float _shakeSpeedX; + private float _shakeSpeedY; + private int _maxOffsetX; + private int _maxOffsetY; + + public int DeathCount; + + public int MaxHearths = 3; + public int CurrentHealth = 4 * 3; + + public int SwordLevel; + public int ShieldLevel; + public int StoneGrabberLevel; + + public bool HasMagnifyingLens; + + public bool DebugMode; + + // 0: marin + // 1: mambo + // 2: frog + public int[] OcarinaSongs = new int[3]; + public int SelectedOcarinaSong = 0; + + public static int CloakGreen = 0; + public static int CloakBlue = 1; + public static int CloakRed = 2; + + public int CloakType; + public Color CloakColor => ItemDrawHelper.CloakColors[CloakType]; + + public bool GuardianAcornIsActive; + public int GuardianAcornCount; + public int GuardianAcornDamageCount; + + public bool PieceOfPowerIsActive; + public int PieceOfPowerCount; + public int PieceOfPowerDamageCount; + + private readonly Dictionary> _dialogPaths = new Dictionary>(); + private DialogPath _currentDialogPath; + private readonly Queue _dialogPathQueue = new Queue(); + + private RenderTarget2D _activeRenderTarget; + private RenderTarget2D _inactiveRenderTarget1; + private RenderTarget2D _inactiveRenderTarget2; + private RenderTarget2D _shadowRenderTarget; + private RenderTarget2D _shadowRenderTargetBlur; + private RenderTarget2D _lightRenderTarget; + + // used for the blured tile layer; use usage of the render targets should probably be optimized + public RenderTarget2D TempRT0; + public RenderTarget2D TempRT1; + public RenderTarget2D TempRT2; + + public float _scaleMultiplier; + private int _currentDialogPathState; + + // 0: map music, 1: guardian acorn/piece of power, 2: maria singing + private const int MusicChannels = 3; + private int[] _musicArray = new int[MusicChannels]; + // counters used to stop music + private float[] _musicCounter = new float[MusicChannels]; + + public GameManager() + { + ResetMusic(); + + GameSystems.Add(typeof(MapTransitionSystem), new MapTransitionSystem(MapManager)); + GameSystems.Add(typeof(GameOverSystem), new GameOverSystem()); + GameSystems.Add(typeof(EndingSystem), new EndingSystem()); + GameSystems.Add(typeof(MapShowSystem), new MapShowSystem()); + } + + public void Load(ContentManager content) + { + ItemDrawHelper.Load(); + + InGameOverlay.Load(content); + MapManager.Load(); + ItemManager.Load(); + + // load the dialog paths + DialogPathLoader.LoadScripts(Values.PathContentFolder + "scripts.zScript", _dialogPaths); + } + + public void OnLoad() + { + InGameOverlay.OnLoad(); + + _currentDialogPath = null; + _dialogPathQueue.Clear(); + + // this leads to the music not starting after switching from edit mode and reloading objects + // not so sure if this is a problem or not + ResetMusic(); + + foreach (var gameSystem in GameSystems) + gameSystem.Value.OnLoad(); + } + + public void UpdateGame() + { + InGameOverlay.Update(); + + UpdateSoundEffects(); + + UpdateMusic(); + + ItemDrawHelper.Update(); + + // update the dialogs; forced dialog update is used in sequences where the dialog should be updated but not the normal game + // needs to come after the ingame overlay update because Game1.UpdateGame can be set to false by it + if (Game1.UpdateGame || Game1.ForceDialogUpdate) + { + UpdateDialog(); + Game1.ForceDialogUpdate = false; + } + + if (Game1.UpdateGame && Game1.TotalGameTime > Game1.FreezeTime) + { + // update the game-systems + foreach (var gameSystem in GameSystems) + gameSystem.Value.Update(); + + if (Game1.UpdateGame) + MapManager.Update(false); + } + else if (Game1.GameManager.InGameOverlay.UpdateCameraAndAnimation()) + { + MapManager.Update(true); + MapManager.UpdateAnimation(); + } + + // update screen shake + if (Game1.UpdateGame) + UpdateShake(); + } + + public void DrawGame(SpriteBatch spriteBatch) + { + if (GameSettings.EnableShadows && MapManager.CurrentMap.UseShadows && !UseShockEffect) + { + // render the shadows + RenderShadows(spriteBatch); + + Resources.BlurEffectH.Parameters["pixelX"].SetValue(1.0f / _shadowRenderTarget.Width); + Resources.BlurEffectV.Parameters["pixelY"].SetValue(1.0f / _shadowRenderTarget.Height); + + Resources.BlurEffectH.Parameters["mult0"].SetValue(0.35f); + Resources.BlurEffectH.Parameters["mult1"].SetValue(0.15f); + Resources.BlurEffectV.Parameters["mult0"].SetValue(0.35f); + Resources.BlurEffectV.Parameters["mult1"].SetValue(0.15f); + + // v blur + Game1.Graphics.GraphicsDevice.SetRenderTarget(_shadowRenderTargetBlur); + Game1.Graphics.GraphicsDevice.Clear(Color.Transparent); + spriteBatch.Begin(SpriteSortMode.Immediate, null, SamplerState.AnisotropicClamp, null, null, Resources.BlurEffectV, null); + spriteBatch.Draw(_shadowRenderTarget, Vector2.Zero, Color.White); + spriteBatch.End(); + + // h blur + Game1.Graphics.GraphicsDevice.SetRenderTarget(_shadowRenderTarget); + Game1.Graphics.GraphicsDevice.Clear(Color.Transparent); + spriteBatch.Begin(SpriteSortMode.Immediate, null, SamplerState.AnisotropicClamp, null, null, Resources.BlurEffectH, null); + spriteBatch.Draw(_shadowRenderTargetBlur, Vector2.Zero, Color.White); + spriteBatch.End(); + + MapManager.CurrentMap.Objects.ShadowTexture = _shadowRenderTarget; + } + + ChangeRenderTarget(); + Game1.Graphics.GraphicsDevice.Clear(Color.Black); + + // draw the map + MapManager.Draw(spriteBatch); + + if (UseShockEffect) + { + ChangeRenderTarget(); + + var usedShader = MapManager.CurrentMap.UseLight ? Resources.ShockShader1 : Resources.ShockShader0; + ObjectManager.SetSpriteShader(usedShader); + + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, usedShader.Effect); + spriteBatch.Draw(_inactiveRenderTarget1, Vector2.Zero, Color.White); + spriteBatch.End(); + } + + // @Move into the World class? + if (MapManager.CurrentMap.UseLight && !UseShockEffect) + { + // draw the lights + ChangeRenderTarget(); + MapManager.DrawLight(spriteBatch); + + // combine the light with the game + ChangeRenderTarget(); + _lightRenderTarget = _inactiveRenderTarget1; + + Game1.Graphics.GraphicsDevice.Clear(Color.Black); + Resources.LightShader.Parameters["sprLight"].SetValue(_lightRenderTarget); + Resources.LightShader.Parameters["lightState"].SetValue(MapManager.CurrentMap.LightState); + Resources.LightShader.Parameters["mode"].SetValue(0); + Resources.LightShader.Parameters["width"].SetValue(_lightRenderTarget.Width); + Resources.LightShader.Parameters["height"].SetValue(_lightRenderTarget.Height); + + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.AnisotropicClamp, null, null, Resources.LightShader); + spriteBatch.Draw(_inactiveRenderTarget2, Vector2.Zero, Color.White); + spriteBatch.End(); + } + + // update the game-systems + foreach (var gameSystem in GameSystems) + gameSystem.Value.Draw(spriteBatch); + + if (MapManager.CurrentMap.UseLight && !UseShockEffect && DrawPlayerOnTopPercentage > 0 && _lightRenderTarget != null) + { + Resources.LightShader.Parameters["sprLight"].SetValue(_lightRenderTarget); + Resources.LightShader.Parameters["lightState"].SetValue(DrawPlayerOnTopPercentage); + Resources.LightShader.Parameters["mode"].SetValue(1); + Resources.LightShader.Parameters["width"].SetValue(_lightRenderTarget.Width); + Resources.LightShader.Parameters["height"].SetValue(_lightRenderTarget.Height); + + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, Resources.LightShader, MapManager.Camera.TransformMatrix); + MapManager.ObjLink.DrawTransition(spriteBatch); + spriteBatch.End(); + } + else if (DrawPlayerOnTopPercentage > 0) + { + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, MapManager.Camera.TransformMatrix); + MapManager.ObjLink.DrawTransition(spriteBatch); + spriteBatch.End(); + } + + // draw the output of the light and the dark shader passes + ChangeRenderTarget(); + Game1.Graphics.GraphicsDevice.SetRenderTarget(Game1.MainRenderTarget); + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.AnisotropicWrap); + + spriteBatch.Draw(_inactiveRenderTarget1, new Rectangle(0, 0, Game1.Graphics.PreferredBackBufferWidth, Game1.Graphics.PreferredBackBufferHeight), Color.White); + + // debug stuff + MapManager.Camera.Draw(spriteBatch); + + spriteBatch.End(); + } + + public void StartDialogPath(string dialogKey) + { + _dialogPathQueue.Enqueue(dialogKey); + } + + public void AddFirstDialogPath(string dialogKey) + { + // @HACK + var items = _dialogPathQueue.ToArray(); + _dialogPathQueue.Clear(); + + _dialogPathQueue.Enqueue(dialogKey); + foreach (var item in items) + _dialogPathQueue.Enqueue(item); + } + + // @TODO: this should probably be removed and replaced with StartDialogPath + public void StartDialog(string dialogKey) + { + InGameOverlay.TextboxOverlay.StartDialog(Game1.LanguageManager.GetString(dialogKey, "error")); + } + + /// + /// @HACK: used by the map overlay to completly run a dialog path; this does only work for single dialogs + /// the problem is that the current game dialog should be unaffected by the dialogs run by the map overlay + /// + /// + public void RunDialog(string dialogKey) + { + // look if a dialog path exists for the key + DialogPath dialogPath = null; + if (dialogKey != null && _dialogPaths.ContainsKey(dialogKey)) + { + var paths = _dialogPaths[dialogKey]; + for (var i = 0; i < paths.Count; i++) + { + if (SaveManager.GetString(paths[i].VariableKey) == null && paths[i].Condition == "0" || + SaveManager.GetString(paths[i].VariableKey) == paths[i].Condition) + { + dialogPath = paths[i]; + break; + } + } + } + + // try to start a new dialog box + if (dialogPath == null && !Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen) + { + // directly start a dialog + string stateString = null; + if (dialogKey != null) + stateString = SaveManager.GetString(dialogKey); + + InGameOverlay.TextboxOverlay.StartDialog( + Game1.LanguageManager.GetString(dialogKey + (stateString != null ? "_" + stateString : ""), "error")); + } + + while (dialogPath != null) + { + var breakLoop = true; + var dialogPathState = 0; + + // execute the current dialog path + if (dialogPath != null) + { + while (dialogPath.Action.Count > dialogPathState && + dialogPath.Action[dialogPathState].Execute()) + { + dialogPathState++; + + // init the next dialog action + if (dialogPath.Action.Count > dialogPathState) + dialogPath.Action[dialogPathState].Init(); + } + + // do not stop executing at a empty dialog path + if (dialogPath.Action.Count == 0) + breakLoop = false; + + // finished current path? + if (dialogPath.Action.Count <= dialogPathState) + { + breakLoop = false; + dialogPath = null; + } + } + + // exit the loop if there is nothing to do + if (breakLoop) + break; + } + } + + public bool DialogIsRunning() + { + return _currentDialogPath != null || _dialogPathQueue.Count > 0; + } + + public bool FinalDialogAction() + { + return false; + } + + private void UpdateDialog() + { + while (_currentDialogPath != null || _dialogPathQueue != null) + { + var breakLoop = true; + + // start a new dialog path? + if (_dialogPathQueue.Count > 0 && _currentDialogPath == null) + { + _currentDialogPath = DequeueDialogPath(); + _currentDialogPathState = 0; + + if (_currentDialogPath != null && _currentDialogPath.Action.Count > _currentDialogPathState) + _currentDialogPath.Action[_currentDialogPathState].Init(); + } + + // execute the current dialog path + if (_currentDialogPath != null) + { + while (_currentDialogPath.Action.Count > _currentDialogPathState && + _currentDialogPath.Action[_currentDialogPathState].Execute()) + { + _currentDialogPathState++; + + // init the next dialog action + if (_currentDialogPath.Action.Count > _currentDialogPathState) + _currentDialogPath.Action[_currentDialogPathState].Init(); + } + + // do not stop executing at a empty dialog path + if (_currentDialogPath.Action.Count == 0) + breakLoop = false; + + // finished current path? + if (_currentDialogPath.Action.Count <= _currentDialogPathState) + { + breakLoop = false; + _currentDialogPath = null; + } + } + + // exit the loop if there is nothing to do + if (breakLoop) + break; + } + } + + private DialogPath DequeueDialogPath() + { + Game1.GameManager.InGameOverlay.TextboxOverlay.UpdateObjects = false; + + var dialogKey = _dialogPathQueue.Peek(); + + // look if a dialog path exists for the key + if (dialogKey != null && _dialogPaths.ContainsKey(dialogKey)) + { + var paths = _dialogPaths[dialogKey]; + for (var i = 0; i < paths.Count; i++) + { + if (SaveManager.GetString(paths[i].VariableKey) == null && paths[i].Condition == "0" || + SaveManager.GetString(paths[i].VariableKey) == paths[i].Condition) + { + _dialogPathQueue.Dequeue(); + return paths[i]; + } + } + } + + // try to start a new dialog box + if (!Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen) + { + _dialogPathQueue.Dequeue(); + + // directly start a dialog + string stateString = null; + if (dialogKey != null) + stateString = SaveManager.GetString(dialogKey); + + InGameOverlay.TextboxOverlay.StartDialog( + Game1.LanguageManager.GetString(dialogKey + (stateString != null ? "_" + stateString : ""), "error")); + } + + return null; + } + + public void RenderShadows(SpriteBatch spriteBatch) + { + Game1.Graphics.GraphicsDevice.SetRenderTarget(_shadowRenderTarget); + Game1.Graphics.GraphicsDevice.Clear(Color.Transparent); + Game1.Graphics.GraphicsDevice.DepthStencilState = DepthStencilState.Default; + Game1.Graphics.GraphicsDevice.SamplerStates[0] = SamplerState.AnisotropicClamp; + Game1.Graphics.GraphicsDevice.BlendState = BlendState.NonPremultiplied; + Game1.Graphics.GraphicsDevice.RasterizerState = RasterizerState.CullNone; + + MapManager.CurrentMap.Objects.DrawShadow(spriteBatch); + } + + public void ChangeRenderTarget() + { + var tempActiveRt = _activeRenderTarget; + _activeRenderTarget = _inactiveRenderTarget2; + _inactiveRenderTarget2 = _inactiveRenderTarget1; + _inactiveRenderTarget1 = tempActiveRt; + + SetActiveRenderTarget(); + } + + public void SetActiveRenderTarget() + { + Game1.Graphics.GraphicsDevice.SetRenderTarget(_activeRenderTarget); + } + + public RenderTarget2D GetLastRenderTarget() + { + return _inactiveRenderTarget1; + } + + public void DrawTop(SpriteBatch spriteBatch) + { + // draw the inventory + InGameOverlay.Draw(spriteBatch); + } + + public void DrawRenderTarget(SpriteBatch spriteBatch) + { + // draw the rt stuff of the game ui + InGameOverlay.DrawRenderTarget(spriteBatch); + } + + public void SetGameScale(float scale) + { + _scaleMultiplier = MathF.Ceiling(scale) / scale; + + UpdateRenderTargets(); + } + + public void OnResize() + { + InGameOverlay.ResolutionChanged(); + + Game1.RenderWidth = (int)(Game1.WindowWidth * _scaleMultiplier); + Game1.RenderHeight = (int)(Game1.WindowHeight * _scaleMultiplier); + + MapManager.Camera.SetBounds(Game1.RenderWidth, Game1.RenderHeight); + + // center the player + MapManager.Camera.ForceUpdate(MapManager.GetCameraTarget()); + + UpdateRenderTargets(); + } + + public void OnResizeEnd() + { + InGameOverlay.UpdateRenderTarget(); + + UpdateRenderTargets(); + } + + public void UpdateRenderTargets() + { + if ((CurrentRenderWidth == Game1.RenderWidth && + CurrentRenderHeight == Game1.RenderHeight && + CurrentRenderScale == MapManager.Camera.Scale) || + Game1.RenderWidth == 0 || Game1.RenderHeight == 0) + return; + + CurrentRenderWidth = Game1.RenderWidth; + CurrentRenderHeight = Game1.RenderHeight; + CurrentRenderScale = MapManager.Camera.Scale; + + _activeRenderTarget?.Dispose(); + _inactiveRenderTarget1?.Dispose(); + _inactiveRenderTarget2?.Dispose(); + _shadowRenderTarget?.Dispose(); + _shadowRenderTargetBlur?.Dispose(); + + _activeRenderTarget = new RenderTarget2D(Game1.Graphics.GraphicsDevice, Game1.RenderWidth, Game1.RenderHeight, + false, SurfaceFormat.Color, DepthFormat.None, 0, RenderTargetUsage.PreserveContents); + _inactiveRenderTarget1 = new RenderTarget2D(Game1.Graphics.GraphicsDevice, Game1.RenderWidth, Game1.RenderHeight, + false, SurfaceFormat.Color, DepthFormat.None, 0, RenderTargetUsage.PreserveContents); + _inactiveRenderTarget2 = new RenderTarget2D(Game1.Graphics.GraphicsDevice, Game1.RenderWidth, Game1.RenderHeight, + false, SurfaceFormat.Color, DepthFormat.None, 0, RenderTargetUsage.PreserveContents); + + // shadow render targets + var shadowScale = MathHelper.Clamp(MapManager.Camera.Scale / 2, 1, 10); + var shadowRtWidth = (int)(Game1.RenderWidth / shadowScale); + var shadowRtHeight = (int)(Game1.RenderHeight / shadowScale); + _shadowRenderTarget = new RenderTarget2D(Game1.Graphics.GraphicsDevice, shadowRtWidth, shadowRtHeight, + false, SurfaceFormat.Color, DepthFormat.None, 0, RenderTargetUsage.PreserveContents); + _shadowRenderTargetBlur = new RenderTarget2D(Game1.Graphics.GraphicsDevice, shadowRtWidth, shadowRtHeight, + false, SurfaceFormat.Color, DepthFormat.None, 0, RenderTargetUsage.PreserveContents); + + // temp render targets + TempRT0?.Dispose(); + TempRT1?.Dispose(); + TempRT2?.Dispose(); + + TempRT0 = new RenderTarget2D(Game1.Graphics.GraphicsDevice, BlurRenderTargetWidth, BlurRenderTargetHeight, + false, SurfaceFormat.Color, DepthFormat.None, 0, RenderTargetUsage.PreserveContents); + TempRT1 = new RenderTarget2D(Game1.Graphics.GraphicsDevice, BlurRenderTargetWidth, BlurRenderTargetHeight, + false, SurfaceFormat.Color, DepthFormat.None, 0, RenderTargetUsage.PreserveContents); + TempRT2 = new RenderTarget2D(Game1.Graphics.GraphicsDevice, SideBlurRenderTargetWidth, SideBlurRenderTargetHeight, + false, SurfaceFormat.Color, DepthFormat.None, 0, RenderTargetUsage.PreserveContents); + } + + public void HealPlayer(int hearts) + { + CurrentHealth += hearts; + if (CurrentHealth > MaxHearths * 4) + CurrentHealth = MaxHearths * 4; + } + + public void InflictDamage(int damage) + { + if (DebugMode) + return; + + if (CloakType == CloakBlue) + damage = (int)MathF.Ceiling(damage / 2f); + if (GuardianAcornIsActive) + damage = (int)MathF.Ceiling(damage / 2f); + + CurrentHealth -= damage; + + if (CurrentHealth < 0) + CurrentHealth = 0; + + // reset count for the guardian acorn + GuardianAcornCount = 0; + + if (GuardianAcornIsActive) + { + GuardianAcornDamageCount++; + if (GuardianAcornDamageCount >= 3) + StopGuardianAcorn(); + } + + // piece of power + if (PieceOfPowerIsActive) + { + PieceOfPowerDamageCount++; + if (PieceOfPowerDamageCount >= 3) + StopPieceOfPower(); + } + } + + public void InitGuardianAcorn() + { + if (PieceOfPowerIsActive) + StopPieceOfPower(); + + GuardianAcornIsActive = true; + GuardianAcornDamageCount = 0; + + StartPieceOfPowerMusic(); + } + + public void StopGuardianAcorn() + { + GuardianAcornIsActive = false; + Game1.GameManager.SetMusic(-1, 1, false); + } + + public void InitPieceOfPower() + { + if (GuardianAcornIsActive) + StopGuardianAcorn(); + + PieceOfPowerIsActive = true; + PieceOfPowerDamageCount = 0; + + StartPieceOfPowerMusic(); + } + + public void StartPieceOfPowerMusic() + { + // start playing music + Game1.GameManager.SetMusic(72, 1); + } + + public void StopPieceOfPower() + { + PieceOfPowerIsActive = false; + Game1.GameManager.SetMusic(-1, 1, false); + } + + public void ResetMusic() + { + for (var i = 0; i < MusicChannels; i++) + { + _musicArray[i] = -1; + _musicCounter[i] = 0; + } + } + + public void UpdateMusic() + { + for (var i = 0; i < MusicChannels; i++) + { + if (_musicCounter[i] == 0) + continue; + + _musicCounter[i] -= Game1.DeltaTime; + + // finished playing the music? + if (_musicCounter[i] <= 0) + { + _musicCounter[i] = 0; + _musicArray[i] = -1; + PlayMusic(); + } + } + } + + public void StopMusic(bool reset = false) + { + if (reset) + ResetMusic(); + + Game1.GbsPlayer.Stop(); + } + + public void StopMusic(int time, int priority) + { + _musicCounter[priority] = time; + } + + public void PlayMusic(bool startPlaying = true) + { + for (var i = MusicChannels - 1; i >= 0; i--) + { + if (_musicArray[i] >= 0) + { + var songNumber = (byte)_musicArray[i]; + if (Game1.GbsPlayer.CurrentTrack != songNumber) + Game1.GbsPlayer.StartTrack(songNumber); + + if (startPlaying) + Game1.GbsPlayer.Play(); + + return; + } + } + + // no music is playing? + Game1.GbsPlayer.Stop(); + } + + public void SetMusic(int songNr, int priority, bool startPlaying = true) + { + // @HACK: don't restart the overworld track if the version with the intro was already started; + // make sure to not restart the music while showing the overworld in the final sequence + if ((songNr == 4 && _musicArray[priority] == 48) || (priority != 2 && _musicArray[2] == 62)) + return; + + _musicArray[priority] = songNr; + + PlayMusic(startPlaying); + } + + public int GetCurrentMusic() + { + for (var i = _musicArray.Length - 1; i >= 0; i--) + if (_musicArray[i] >= 0) + return _musicArray[i]; + + return -1; + } + + public void UpdateSoundEffects() + { + var lowerVolume = false; + + // we use ToList to be able to remove entries in the foreach loop + foreach (var soundEffect in CurrentSoundEffects.ToList()) + { + if (CurrentSoundEffects[soundEffect.Key].LowerMusicVolume) + lowerVolume = true; + + // update the volume of the sound effects to match the current settings + soundEffect.Value.Instance.Volume = CurrentSoundEffects[soundEffect.Key].Volume * GameSettings.EffectVolume / 100 * Values.SoundEffectVolumeMult; + + soundEffect.Value.Instance.IsLooped = false; + + if (soundEffect.Value.EndTime != 0 && + soundEffect.Value.EndTime < Game1.TotalGameTime) + soundEffect.Value.Instance.Stop(); + + // finished playing? + if (soundEffect.Value.Instance.State == SoundState.Stopped) + CurrentSoundEffects.Remove(soundEffect.Key); + } + + if (lowerVolume) + Game1.GbsPlayer.SetVolumeMultiplier(0.35f); + } + + public void PauseSoundEffects() + { + foreach (var soundEffect in CurrentSoundEffects) + if (soundEffect.Value.Instance.State == SoundState.Playing) + soundEffect.Value.Instance.Pause(); + } + + public void ContinueSoundEffects() + { + foreach (var soundEffect in CurrentSoundEffects) + if (soundEffect.Value.Instance.State == SoundState.Paused) + soundEffect.Value.Instance.Resume(); + } + + public void PlaySoundEffect(string name, bool restart, Vector2 position, float range = 256) + { + var playerDistance = MapManager.ObjLink.EntityPosition.Position - position; + var volume = 1 - playerDistance.Length() / range; + + if (volume > 0) + PlaySoundEffect(name, restart, volume); + } + + public void PlaySoundEffect(string name, bool restart = true, float volume = 1, float pitch = 0, bool lowerMusicVolume = false, float playtime = 0) + { + CurrentSoundEffects.TryGetValue(name, out var entry); + + // if the same sound is playing it will be stopped and replaced with the new instance + if (restart && entry!= null && entry.Instance != null) + { + entry.Instance.Stop(); + CurrentSoundEffects.Remove(name); + } + if (!restart && entry != null && entry.Instance != null) + { + entry.Volume = volume; + if (playtime != 0) + entry.EndTime = Game1.TotalGameTime + playtime; + + entry.Instance.Volume = volume * GameSettings.EffectVolume / 100f * Values.SoundEffectVolumeMult; + entry.Instance.Pitch = pitch; + + return; + } + + entry = new PlayingSoundEffect() { Volume = volume, LowerMusicVolume = lowerMusicVolume }; + entry.Instance = Resources.SoundEffects[name].CreateInstance(); + // the volume of the sound effects is higher than the music; so scale effect volume a little down + entry.Instance.Volume = volume * GameSettings.EffectVolume / 100f * Values.SoundEffectVolumeMult; + entry.Instance.Pitch = pitch; + + if (playtime != 0) + { + entry.Instance.IsLooped = true; + entry.EndTime = Game1.TotalGameTime + playtime; + } + + entry.Instance.Play(); + + CurrentSoundEffects.Add(name, entry); + } + + public void StopSoundEffect(string name) + { + if (CurrentSoundEffects.TryGetValue(name, out var entry)) + entry.Instance.Stop(); + } + + public bool IsPlaying(string name) + { + if (CurrentSoundEffects.TryGetValue(name, out var entry)) + return entry.Instance.State == SoundState.Playing; + + return false; + } + + public void ShakeScreenContinue(int time, int maxX, int maxY, float shakeSpeedX, float shakeSpeedY) + { + var periodsX = (_shakeCountX / 100f * _shakeSpeedX) % (MathF.PI * 2); + _shakeCountX = time; + if (_shakeSpeedX > 0) + _shakeCountX += periodsX / _shakeSpeedX * 100f; + + _shakeCountY = time; + _maxOffsetX = maxX; + _maxOffsetY = maxY; + _shakeSpeedX = shakeSpeedX; + _shakeSpeedY = shakeSpeedY; + } + + public void ShakeScreen(int time, int maxX, int maxY, float shakeSpeedX, float shakeSpeedY, int startDirX = 1, int startDirY = 1) + { + _shakeCountX = time; + _shakeCountY = time; + _maxOffsetX = maxX; + _maxOffsetY = maxY; + _shakeSpeedX = shakeSpeedX; + _shakeSpeedY = shakeSpeedY; + + if (_shakeSpeedX > 0) + { + var periodsX = MathF.Round((time / 100f * _shakeSpeedX) / MathF.PI); + if ((startDirX == -1 && periodsX % 2 == 0) || + (startDirX == 1 && periodsX % 2 == 1)) + periodsX += 1; + _shakeCountX = (periodsX * MathF.PI) / _shakeSpeedX * 100f; + } + + if (_shakeSpeedY > 0) + { + var periodsY = MathF.Round((time / 100f * _shakeSpeedY) / MathF.PI); + if ((startDirY == 1 && periodsY % 2 == 0) || + (startDirY == -1 && periodsY % 2 == 1)) + periodsY += 1; + _shakeCountY = (periodsY * MathF.PI) / _shakeSpeedY * 100f; + } + } + + public void UpdateShake() + { + if (_shakeCountX > 0) + { + _shakeCountX -= Game1.DeltaTime; + MapManager.Camera.ShakeOffsetX = (float)Math.Sin(_shakeCountX / 100f * _shakeSpeedX) * _maxOffsetX; + } + + if (_shakeCountY > 0) + { + _shakeCountY -= Game1.DeltaTime; + MapManager.Camera.ShakeOffsetY = (float)Math.Sin(_shakeCountY / 100f * _shakeSpeedY) * _maxOffsetY; + } + } + + public bool LoadMiniMap(string mapName) + { + // already loaded the levels? + if (DungeonMaps.ContainsKey(mapName)) + return true; + + // load the mini map + var fileName = Values.PathMinimapFolder + mapName + ".txt"; + var dungeonMap = SaveLoadMap.LoadMiniMap(fileName); + + if (dungeonMap == null) + return false; + + DungeonMaps.Add(mapName, dungeonMap); + return true; + } + + public void SetDungeon(string dungeonName, int dungeonLevel) + { + // TODO_Opt preload all the minimaps + + var level = 0; + while (true) + { + if (!LoadMiniMap(dungeonName + "_" + level)) + break; + + LoadMiniMap(dungeonName + "_" + level + "_alt"); + + level++; + } + + MapManager.NextMap.DungeonMode = true; + MapManager.NextMap.LocationName = dungeonName; + MapManager.NextMap.LocationFullName = dungeonName + "_" + dungeonLevel; + } + + public void DungeonUpdatePlayerPosition(Point position) + { + // updated map discovery state + if (MapManager.CurrentMap.LocationFullName != null && + DungeonMaps.ContainsKey(MapManager.CurrentMap.LocationFullName) && + position.X >= 0 && position.Y >= 0 && + position.X < DungeonMaps[MapManager.CurrentMap.LocationFullName].Tiles.GetLength(0) && + position.Y < DungeonMaps[MapManager.CurrentMap.LocationFullName].Tiles.GetLength(1)) + DungeonMaps[MapManager.CurrentMap.LocationFullName].Tiles[position.X, position.Y].DiscoveryState = true; + + PlayerDungeonPosition = position; + } + + public void SetMapPosition(Point position) + { + if (MapVisibility == null || + 0 > position.X || position.X >= MapVisibility.GetLength(0) || + 0 > position.Y || position.Y >= MapVisibility.GetLength(1)) + return; + + MapVisibility[position.X, position.Y] = true; + PlayerMapPosition = position; + } + + public GameItemCollected GetItem(string itemId) + { + for (var i = 0; i < Equipment.Length; i++) + { + if (Equipment[i] != null && Equipment[i].Name == itemId && + (string.IsNullOrEmpty(Equipment[i].LocationBounding) || + Equipment[i].LocationBounding == MapManager.CurrentMap.LocationName)) + return Equipment[i]; + } + + for (var i = 0; i < CollectedItems.Count; i++) + { + // player has item + if (CollectedItems[i].Name == itemId && + (string.IsNullOrEmpty(CollectedItems[i].LocationBounding) || + CollectedItems[i].LocationBounding == MapManager.CurrentMap.LocationName)) + return CollectedItems[i]; + } + + return null; + } + + public void CollectItem(GameItemCollected itemCollected, int equipmentSlot = -1) + { + if (itemCollected.LocationBounding == "") + itemCollected.LocationBounding = null; + + var item = Game1.GameManager.ItemManager[itemCollected.Name]; + // the base item has the max count information + var baseItem = Game1.GameManager.ItemManager[item.Name]; + + // make sure to replace then name + // this is used for items that have different variations like the normal powder or powderPD with dialog + itemCollected.Name = item.Name; + + // add the arrow count to the bow and remove the arrows + if (itemCollected.Name == "bow") + { + var arrow = Game1.GameManager.GetItem("arrow"); + if (arrow != null) + { + itemCollected.Count += arrow.Count; + Game1.GameManager.RemoveItem("arrow", arrow.Count); + } + } + // if we have the bow collected change the type to bow + if (itemCollected.Name == "arrow") + { + var bow = Game1.GameManager.GetItem("bow"); + if (bow != null) + { + itemCollected.Name = "bow"; + item = Game1.GameManager.ItemManager[itemCollected.Name]; + baseItem = Game1.GameManager.ItemManager[item.Name]; + } + } + + if (itemCollected.Name == "cloakBlue") + CloakType = CloakBlue; + else if (itemCollected.Name == "cloakRed") + CloakType = CloakRed; + + // unlock the ocarina songs + if (itemCollected.Name == "ocarina_maria") + { + OcarinaSongs[0] = 1; + + if (SelectedOcarinaSong == -1) + SelectedOcarinaSong = 0; + } + if (itemCollected.Name == "ocarina_manbo") + { + OcarinaSongs[1] = 1; + + if (SelectedOcarinaSong == -1) + SelectedOcarinaSong = 1; + } + if (itemCollected.Name == "ocarina_frog") + { + OcarinaSongs[2] = 1; + + if (SelectedOcarinaSong == -1) + SelectedOcarinaSong = 2; + } + + // magnifying lens collected + if (itemCollected.Name == "trade13") + HasMagnifyingLens = true; + + if (baseItem.Equipable) + { + var maxCount = baseItem.MaxCount; + + if (itemCollected.Name == "sword1") + SwordLevel = 1; + else if (itemCollected.Name == "sword2") + SwordLevel = 2; + + if (itemCollected.Name == "shield" || + itemCollected.Name == "mirrorShield") + ShieldLevel = item.Level; + if (itemCollected.Name == "stonelifter" || itemCollected.Name == "stonelifter2") + StoneGrabberLevel = item.Level; + + // powder, bomb or arrow? + // check if the inventory was upgraded or not + if (item.Name == "powder" && SaveManager.GetString("upgradePowder") == "1") + maxCount += 20; + if (item.Name == "bomb" && SaveManager.GetString("upgradeBomb") == "1") + maxCount += 30; + if (item.Name == "bow" && SaveManager.GetString("upgradeBow") == "1") + maxCount += 30; + + // search if the player already owns the equipment + for (var i = 0; i < Equipment.Length; i++) + { + if (Equipment[i] != null && Equipment[i].Name == item.Name) + { + Equipment[i].Count += itemCollected.Count; + + if (maxCount > 0 && Equipment[i].Count > maxCount) + Equipment[i].Count = maxCount; + + return; + } + } + + if (maxCount > 0 && itemCollected.Count > maxCount) + itemCollected.Count = maxCount; + + // requested equipment slot is empty? + if (0 <= equipmentSlot && equipmentSlot < Equipment.Length && Equipment[equipmentSlot] == null) + { + SetEquipment(equipmentSlot, itemCollected); + return; + } + + // add item to the collected item list + var start = equipmentSlot < 0 ? 4 : 0; + for (var i = start; i < Equipment.Length; i++) + { + if (Equipment[i] != null) + continue; + + SetEquipment(i, itemCollected); + return; + } + } + else + { + // search if the player already owns the item + var found = false; + for (var i = 0; i < CollectedItems.Count; i++) + { + if (CollectedItems[i].Name == item.Name && + CollectedItems[i].LocationBounding == itemCollected.LocationBounding) + { + CollectedItems[i].Count += itemCollected.Count; + + if (baseItem.MaxCount > 0 && CollectedItems[i].Count > baseItem.MaxCount) + CollectedItems[i].Count = baseItem.MaxCount; + + found = true; + break; + } + } + + if (!found) + { + // add new item + CollectedItems.Add(itemCollected); + } + + if (item.Name == "heartMeter") + { + var heart = Game1.GameManager.GetItem("heartMeter"); + + // expand hearts? + while (heart?.Count >= 4) + { + heart.Count -= 4; + Game1.GameManager.MaxHearths++; + Game1.GameManager.HealPlayer(99); + ItemDrawHelper.EnableHeartAnimationSound(); + } + } + else if (item.Name == "flippers") + MapManager.ObjLink.HasFlippers = true; + } + } + + public int GetEquipmentSlot(string itemName) + { + for (var i = 0; i < Equipment.Length; i++) + { + if (Equipment[i] != null && Equipment[i].Name == itemName) + return i; + } + + return 0; + } + + public bool RemoveItem(string itemName, int count) + { + // equipment + for (var i = 0; i < Equipment.Length; i++) + { + if (Equipment[i] == null || Equipment[i].Name != itemName || + Game1.GameManager.ItemManager[Equipment[i].Name].Level == 0 && Equipment[i].Count < count) + continue; + + Equipment[i].Count -= count; + + // remove the item from the inventory if the player can only have 1 of it + // bombs, powder, etc will stay in the inventory + if (Equipment[i].Count <= 0 && Game1.GameManager.ItemManager[Equipment[i].Name].MaxCount == 1) + Equipment[i] = null; + + // remove the item? + // not sure what to do here + // in the original powder gets removed but bombs not; what happens to arrows I do not know + if (itemName == "powder" && Equipment[i] != null && Equipment[i].Count == 0) + Equipment[i] = null; + + return true; + } + + // items + for (var i = 0; i < CollectedItems.Count; i++) + { + if (CollectedItems[i] == null || CollectedItems[i].Name != itemName || + Game1.GameManager.ItemManager[CollectedItems[i].Name].Level == 0 && CollectedItems[i].Count < count || + !string.IsNullOrEmpty(CollectedItems[i].LocationBounding) && CollectedItems[i].LocationBounding != MapManager.CurrentMap.LocationName) + continue; + + CollectedItems[i].Count -= count; + + // remove the item? + if (Game1.GameManager.ItemManager[CollectedItems[i].Name].Level != 0 || CollectedItems[i].Count == 0) + { + CollectedItems.RemoveAt(i); + + if (itemName == "flippers") + MapManager.ObjLink.HasFlippers = false; + } + + return true; + } + + return false; + } + + public void ChangeItem(int oldSlot, int newSlot) + { + var tempAcc = Equipment[oldSlot]; + + SetEquipment(oldSlot, Equipment[newSlot]); + SetEquipment(newSlot, tempAcc); + } + + public void SetEquipment(int index, GameItemCollected item) + { + Equipment[index] = item; + UpdateEquipment(); + } + + private void UpdateEquipment() + { + // check if link is carrying a shield + MapManager.ObjLink.CarrySword = false; + MapManager.ObjLink.CarryShield = false; + + for (var i = 0; i < Values.HandItemSlots; i++) + { + if (Equipment[i]?.Name == "sword1" || Equipment[i]?.Name == "sword2") + MapManager.ObjLink.CarrySword = true; + else if (Equipment[i]?.Name == "shield" || Equipment[i]?.Name == "mirrorShield") + MapManager.ObjLink.CarryShield = true; + } + } + + public void StartNewGame(int slot, string slotName) + { + ResetStuff(); + + SaveName = slotName; + + Equipment = new GameItemCollected[EquipmentSlots]; + + UpdateEquipment(); + + SaveManager.Reset(); + + // set up values + // debug fill the inventory + if (SaveName == "DebugMode") + { + DebugMode = true; + + CollectItem(new GameItemCollected("sword1") { Count = 1 }, 0); + CollectItem(new GameItemCollected("shield") { Count = 1 }, 0); + CollectItem(new GameItemCollected("feather") { Count = 1 }, 0); + CollectItem(new GameItemCollected("stonelifter") { Count = 1 }, 0); + CollectItem(new GameItemCollected("pegasusBoots") { Count = 1 }, 0); + CollectItem(new GameItemCollected("shovel") { Count = 1 }, 0); + CollectItem(new GameItemCollected("flippers") { Count = 1 }, 0); + CollectItem(new GameItemCollected("magicRod") { Count = 1 }, 0); + CollectItem(new GameItemCollected("hookshot") { Count = 1 }, 0); + CollectItem(new GameItemCollected("boomerang") { Count = 1 }, 0); + CollectItem(new GameItemCollected("powder") { Count = 999 }, 0); + CollectItem(new GameItemCollected("bomb") { Count = 999 }, 0); + CollectItem(new GameItemCollected("bow") { Count = 999 }, 0); + CollectItem(new GameItemCollected("ocarina") { Count = 1 }, 0); + } + + CollectedItems.Clear(); + + DungeonMaps.Clear(); + + ItemDrawHelper.Init(); + + SwordLevel = 0; + CloakType = CloakGreen; + + SelectedOcarinaSong = 0; + OcarinaSongs[0] = 0; + OcarinaSongs[1] = 0; + OcarinaSongs[2] = 0; + + MaxHearths = 3; + CurrentHealth = MaxHearths * 4; + + PlayerMapPosition = null; + MapVisibility = new bool[16, 16]; + + SaveSlot = slot; + + // randomize the directions of the egg + Game1.GameManager.SaveManager.SetString("eggDirections", Game1.RandomNumber.Next(0, 4).ToString()); + + // create empty map + MapManager.CurrentMap = Map.Map.CreateEmptyMap(); + + MapManager.ObjLink.Map = MapManager.CurrentMap; + MapManager.ObjLink.MapTransitionStart = MapManager.ObjLink.EntityPosition.Position; + MapManager.ObjLink.MapTransitionEnd = MapManager.ObjLink.EntityPosition.Position; + MapManager.ObjLink.EntityPosition.Z = 0; + MapManager.ObjLink.TransitionOutWalking = false; + MapManager.ObjLink.TransitionInWalking = false; + + MapManager.ObjLink.InitGame(); + + MapManager.Camera.ForceUpdate(MapManager.GetCameraTargetLink()); + + // load the map + MapManager.ObjLink.SetNextMapPosition(new Vector2(MapManager.ObjLink.PosX, MapManager.ObjLink.PosY)); + ((MapTransitionSystem)GameSystems[typeof(MapTransitionSystem)]).LoadMapFromFile("house1.map", true, true, Values.MapFirstTransitionColor, false); + ((MapTransitionSystem)GameSystems[typeof(MapTransitionSystem)]).AdditionalBlackScreenDelay = Values.GameSaveBlackScreen; + } + + public void LoadSaveFile(int slot) + { + ResetStuff(); + + MapManager.ObjLink.InitGame(); + + SaveGameSaveLoad.LoadSaveFile(this, slot); + + ItemDrawHelper.Init(); + + UpdateEquipment(); + + // create empty map + MapManager.CurrentMap = Map.Map.CreateEmptyMap(); + MapManager.CurrentMap.Objects.SpawnObject(MapManager.ObjLink); + + MapManager.ObjLink.Map = MapManager.CurrentMap; + MapManager.ObjLink.SetWalkingDirection(SaveDirection); + + MapManager.Camera.ForceUpdate(MapManager.GetCameraTargetLink()); + + MapManager.ObjLink.MapTransitionStart = MapManager.ObjLink.EntityPosition.Position; + MapManager.ObjLink.MapTransitionEnd = MapManager.ObjLink.EntityPosition.Position; + MapManager.ObjLink.DirectionEntry = SaveDirection; + MapManager.ObjLink.EntityPosition.Z = 0; + MapManager.ObjLink.TransitionOutWalking = false; + MapManager.ObjLink.TransitionInWalking = false; + + // load the map + var transitionSystem = ((MapTransitionSystem)GameSystems[typeof(MapTransitionSystem)]); + MapManager.ObjLink.SetNextMapPosition(new Vector2(SavePositionX, SavePositionY)); + transitionSystem.LoadMapFromFile(LoadedMap, true, true, Values.MapFirstTransitionColor, false); + transitionSystem.AdditionalBlackScreenDelay = Values.GameSaveBlackScreen; + } + + public void RespawnPlayer() + { + if (Game1.GameManager.SaveManager.HistoryEnabled) + { + Game1.GameManager.SaveManager.RevertHistory(); + Game1.GameManager.SaveManager.DisableHistory(); + } + + ResetStuff(); + + // create empty map + MapManager.CurrentMap = Map.Map.CreateEmptyMap(); + MapManager.CurrentMap.Objects.SpawnObject(MapManager.ObjLink); + MapManager.ObjLink.Map = MapManager.CurrentMap; + + MapManager.Camera.ForceUpdate(MapManager.GetCameraTargetLink()); + + // respawn the player + MapManager.ObjLink.Respawn(); + + ItemDrawHelper.Init(); + + MapManager.ObjLink.MapTransitionStart = MapManager.ObjLink.EntityPosition.Position; + MapManager.ObjLink.MapTransitionEnd = MapManager.ObjLink.EntityPosition.Position; + + MapManager.ObjLink.TransitionOutWalking = false; + MapManager.ObjLink.TransitionInWalking = false; + + // respawn looking down + MapManager.ObjLink.DirectionEntry = 3; + MapManager.ObjLink.SetWalkingDirection(3); + MapManager.ObjLink.SetNextMapPosition(MapManager.ObjLink.SavePosition); + + // load the map + var transitionSystem = ((MapTransitionSystem)GameSystems[typeof(MapTransitionSystem)]); + transitionSystem.LoadMapFromFile(MapManager.ObjLink.SaveMap, true, true, Values.MapFirstTransitionColor, false); + transitionSystem.AdditionalBlackScreenDelay = Values.GameRespawnBlackScreen; + } + + private void ResetStuff() + { + SaveGameSaveLoad.ClearSaveState(); + Game1.GameManager.SaveManager.DisableHistory(); + + // this was done to support DialogActionCooldown working after loading a new save + Game1.TotalGameTime = 0; + Game1.TotalGameTimeLast = 0; + Game1.FreezeTime = 0; + + _shakeCountX = 0; + _shakeCountY = 0; + } + } +} \ No newline at end of file diff --git a/InGame/Things/GameSettings.cs b/InGame/Things/GameSettings.cs new file mode 100644 index 0000000..1d3cd5f --- /dev/null +++ b/InGame/Things/GameSettings.cs @@ -0,0 +1,32 @@ + +namespace ProjectZ.InGame.Things +{ + class GameSettings + { + public static int UiScale = 0; + public static int GameScale = 11; // autoscale + + public static bool EnableShadows = true; + public static bool LockFps = true; + public static bool Autosave = true; + public static bool SmoothCamera = true; + + public static bool BorderlessWindowed = false; + public static bool IsFullscreen = false; + + private static int _musicVolume = 100; + private static int _effectVolume = 100; + + public static int MusicVolume + { + get => _musicVolume; + set { _musicVolume = value; Game1.GbsPlayer.SetVolume(value / 100.0f); } + } + + public static int EffectVolume + { + get => _effectVolume; + set { _effectVolume = value; } + } + } +} diff --git a/InGame/Things/HitType.cs b/InGame/Things/HitType.cs new file mode 100644 index 0000000..2ded02a --- /dev/null +++ b/InGame/Things/HitType.cs @@ -0,0 +1,32 @@ +using System; + +namespace ProjectZ.InGame.Things +{ + [Flags] + public enum HitType + { + // used to hit enemies + Sword1 = 0x01 << 0, + Sword2 = 0x01 << 1, + Sword = Sword1 | Sword2, + Boomerang = 0x01 << 2, + Bomb = 0x01 << 3, + Bow = 0x01 << 4, + Hookshot = 0x01 << 5, + MagicRod = 0x01 << 6, + MagicPowder = 0x01 << 7, + PegasusBootsSword = 0x01 << 8, + PegasusBootsPush = 0x01 << 9, + ThrownObject = 0x01 << 10, + BowWow = 0x01 << 11, + SwordShot = 0x01 << 12, + SwordHold = 0x01 << 13, + SwordSpin = 0x01 << 14, + + // used to hit the player + Spikes = 0x01 << 15, + Object = 0x01 << 16, + Enemy = 0x01 << 17, + Boss = 0x01 << 18, + } +} diff --git a/InGame/Things/ItemDrawHelper.cs b/InGame/Things/ItemDrawHelper.cs new file mode 100644 index 0000000..2c09940 --- /dev/null +++ b/InGame/Things/ItemDrawHelper.cs @@ -0,0 +1,496 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.Map; +using ProjectZ.InGame.SaveLoad; + +namespace ProjectZ.InGame.Things +{ + class ItemDrawHelper + { + private static DictAtlasEntry SpriteLetter; + private static DictAtlasEntry SpriteHeart; + private static DictAtlasEntry SpriteRubee; + + private static Rectangle RecLetters; + private static Rectangle RecHeart; + private static Rectangle RecRubee; + + private static int _hearthDistance = 1; + private static int _heartsDistance = 1; + + private static readonly int LetterMargin = 1; + + public static Point RubeeSize; + + private static int _paddingHud = 4; + + private static Color _relictColorOne = new Color(0, 135, 115); + private static Color _relictColorTwo = new Color(255, 255, 255); + + public static Color[] CloakColors = { new Color(16, 173, 66), new Color(24, 132, 255), new Color(255, 8, 41) }; + + private static Rectangle _recRelicts = new Rectangle(224, 128, 16, 16); + + private static float _colorCounter; + private const int ColorTime = 8000; + + public static int LetterWidth = 6; + public static int LetterHeight = 6; + + private static float _rubyCounter; + private static float _rubyTime; + private static float _rubySoundIndex; + private static int _rubyStart; + private static int _rubyEnd; + private static int _rubyCount; + private static bool _rubyAnimation; + + private static float _heartCounter; + private static int _heartCount; + private static bool _heartAnimation; + private static bool _heartSounds; + + public static void Load() + { + SpriteLetter = Resources.GetSprite("ui letter"); + SpriteHeart = Resources.GetSprite("ui heart"); + SpriteRubee = Resources.GetSprite("ui ruby"); + + RecLetters = SpriteLetter.ScaledRectangle; + RecHeart = SpriteHeart.ScaledRectangle; + RecRubee = SpriteRubee.ScaledRectangle; + + RubeeSize = new Point((RecLetters.Width + LetterMargin) * 3 + RecRubee.Width, RecRubee.Height); + } + + public static void Init() + { + _rubyAnimation = false; + _heartAnimation = false; + + var item = Game1.GameManager.GetItem("ruby"); + if (item != null) + _rubyCount = item.Count; + else + _rubyCount = 0; + + _heartCount = Game1.GameManager.CurrentHealth; + } + + public static void Update() + { + // rotate color + // @MOVE + _colorCounter += Game1.DeltaTime; + + var upTime = ColorTime / 3; + var timeR = (_colorCounter - upTime) % ColorTime; + var timeG = (_colorCounter) % ColorTime; + var timeB = (_colorCounter - upTime * 2) % ColorTime; + + // rotate through the color wheel + var colorR = MathHelper.Clamp(MathF.Abs(timeR - upTime) / (upTime / 2.25f) - 1, 0, 1); + var colorG = MathHelper.Clamp(MathF.Abs(timeG - upTime) / (upTime / 2.25f) - 1, 0, 1); + var colorB = MathHelper.Clamp(MathF.Abs(timeB - upTime) / (upTime / 2.25f) - 1, 0, 1); + + _relictColorOne = new Color( + MathHelper.Clamp((byte)(colorR * 120), 0, 255), + MathHelper.Clamp((byte)(colorG * 80), 0, 255), + MathHelper.Clamp((byte)(colorB * 140), 0, 255)); + + _relictColorTwo = new Color( + MathHelper.Clamp((byte)(colorR * 220), 0, 255), + MathHelper.Clamp((byte)(colorG * 180), 0, 255), + MathHelper.Clamp((byte)(colorB * 240), 0, 255)); + + UpdateRubyAnimation(); + + UpdateHeartAnimation(); + } + + private static void UpdateRubyAnimation() + { + var item = Game1.GameManager.GetItem("ruby"); + var realCount = 0; + if (item != null) + realCount = item.Count; + + if (!Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen && + !Game1.GameManager.InGameOverlay.MenuIsOpen()) + { + // start the animation? + if (!_rubyAnimation) + { + if (_rubyCount + 1 < realCount) + { + _rubyCounter = 0; + _rubyAnimation = true; + + _rubyStart = _rubyCount; + _rubyEnd = realCount; + + _rubySoundIndex = 0; + + _rubyCount++; + _rubyTime = 32 * (realCount - _rubyCount); + if (_rubyTime > 2000) + _rubyTime = 2000; + } + else if (_rubyCount - 1 > realCount) + { + _rubyCounter = 0; + _rubyAnimation = true; + + _rubyStart = _rubyCount; + _rubyEnd = realCount; + + _rubySoundIndex = 0; + + _rubyCount--; + _rubyTime = 32 * (_rubyCount - realCount); + if (_rubyTime > 2000) + _rubyTime = 2000; + } + else + _rubyCount = realCount; + } + + if (_rubyAnimation && _rubyCount != _rubyEnd) + { + _rubyCounter += Game1.DeltaTime; + if (_rubyCounter > _rubyTime) + _rubyCounter = _rubyTime; + + _rubyCount = (int)MathHelper.Lerp(_rubyStart, _rubyEnd, _rubyCounter / _rubyTime); + + // ruby sound every 2 frames + if ((_rubySoundIndex + 1) * 32 <= _rubyCounter) + { + _rubySoundIndex++; + Game1.GameManager.PlaySoundEffect("D370-05-05"); + } + } + else + { + _rubyAnimation = false; + } + } + } + + public static void EnableHeartAnimationSound() + { + _heartSounds = true; + } + + private static void UpdateHeartAnimation() + { + var realCount = Game1.GameManager.CurrentHealth; + + if (!Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen && + !Game1.GameManager.InGameOverlay.MenuIsOpen()) + { + // start the animation? + if (!_heartAnimation) + { + if (_heartCount + 4 < realCount) + { + _heartCounter = 0; + _heartAnimation = true; + if (!_heartSounds) + _heartCount += 4; + else + _heartCounter = 200; + } + else + _heartCount = realCount; + } + + if (_heartAnimation && _heartCount != realCount) + { + _heartCounter += Game1.DeltaTime; + + if (_heartCounter > 200) + { + _heartCounter -= 200; + _heartCount += 4; + + if (_heartSounds) + Game1.GameManager.PlaySoundEffect("D370-06-06"); + + if (_heartCount >= realCount) + { + _heartCount = realCount; + _heartAnimation = false; + _heartSounds = false; + } + } + } + } + } + + public static void DrawLevel(SpriteBatch spriteBatch, int posX, int posY, int number, int scale, Color textColor) + { + // add L- if the number is < 0 + // L- 0 1 2 3... + var letter0 = number < 0 ? 0 : number / 10 + 1; + var letter1 = number < 0 ? -number + 1 : number % 10 + 1; + + spriteBatch.Draw(SpriteLetter.Texture, new Rectangle(posX, posY, RecLetters.Width * scale, RecLetters.Height * scale), + new Rectangle(RecLetters.X + letter0 * (RecLetters.Width + (int)SpriteLetter.Scale), RecLetters.Y, RecLetters.Width, RecLetters.Height), textColor); + spriteBatch.Draw(SpriteLetter.Texture, new Rectangle(posX + RecLetters.Width * scale, posY, RecLetters.Width * scale, RecLetters.Height * scale), + new Rectangle(RecLetters.X + letter1 * (RecLetters.Width + (int)SpriteLetter.Scale), RecLetters.Y, RecLetters.Width, RecLetters.Height), textColor); + } + + public static void DrawNumber(SpriteBatch spriteBatch, int posX, int posY, int number, int length, int scale, Color textColor) + { + for (var i = 0; i < length; i++) + { + var letter = number / (int)Math.Pow(10, length - i - 1) % 10 + 1; + + spriteBatch.Draw(SpriteLetter.Texture, new Rectangle( + posX + (RecLetters.Width + LetterMargin) * i * scale, + posY, RecLetters.Width * scale, RecLetters.Height * scale), + new Rectangle(RecLetters.X + letter * (RecLetters.Width + (int)SpriteLetter.Scale), RecLetters.Y, RecLetters.Width, RecLetters.Height), textColor); + } + } + + public static void DrawItem(SpriteBatch spriteBatch, GameItem item, Vector2 position, Color color, int scale, bool mapSprite = false) + { + if (item == null) + return; + + var baseItem = item.SourceRectangle.HasValue ? item : Game1.GameManager.ItemManager[item.Name]; + + Rectangle sourceRectangle; + DictAtlasEntry sprite; + + if (baseItem.MapSprite != null && mapSprite) + { + sprite = baseItem.MapSprite; + sourceRectangle = baseItem.MapSprite.ScaledRectangle; + } + else + { + sprite = baseItem.Sprite; + sourceRectangle = baseItem.Sprite.ScaledRectangle; + } + + if (item.Name == "ruby" && item.AnimateSprite) + { + var frameLength = 10 / 60f * 1000; + sourceRectangle.X += (int)((Game1.TotalGameTime % (frameLength * 4)) / frameLength) * (sourceRectangle.Width + sprite.TextureScale); + } + + // draw the item + if ((item.Name == "sword1" || item.Name == "sword2" || item.Name == "sword1PoP" || item.Name == "sword2PoP") && Game1.GameManager.PieceOfPowerIsActive) + { + if (Game1.TotalTime % (16 / 0.06) >= 8 / 0.06) + { + var swordSprite = Resources.GetSprite("swordBlink"); + sourceRectangle = swordSprite.SourceRectangle; + } + + DrawHelper.DrawNormalized(spriteBatch, sprite.Texture, new Vector2(position.X, position.Y), sourceRectangle, color, scale * sprite.Scale); + } + else if (item.Name == "pieceOfPower") + { + if (Game1.TotalTime % (16 / 0.06) >= 8 / 0.06) + sourceRectangle.X += sourceRectangle.Width + sprite.TextureScale; + + DrawHelper.DrawNormalized(spriteBatch, sprite.Texture, new Vector2(position.X, position.Y), sourceRectangle, color, scale * sprite.Scale); + } + else if (item.Name == "cloakBlue") + { + var transparency = color.A / 255f; + DrawHelper.DrawNormalized(spriteBatch, sprite.Texture, new Vector2(position.X, position.Y), sourceRectangle, new Color(253, 188, 140) * transparency, scale * sprite.Scale); + DrawHelper.DrawNormalized(spriteBatch, sprite.Texture, new Vector2(position.X, position.Y), + new Rectangle(sourceRectangle.X, sourceRectangle.Y + sourceRectangle.Height, sourceRectangle.Width, sourceRectangle.Height), CloakColors[1] * transparency, scale * sprite.Scale); + } + else if (item.Name == "cloakRed") + { + var transparency = color.A / 255f; + DrawHelper.DrawNormalized(spriteBatch, sprite.Texture, new Vector2(position.X, position.Y), sourceRectangle, new Color(253, 188, 140) * transparency, scale * sprite.Scale); + DrawHelper.DrawNormalized(spriteBatch, sprite.Texture, new Vector2(position.X, position.Y), + new Rectangle(sourceRectangle.X, sourceRectangle.Y + sourceRectangle.Height, sourceRectangle.Width, sourceRectangle.Height), CloakColors[2] * transparency, scale * sprite.Scale); + } + else if (!item.IsRelict) + { + DrawHelper.DrawNormalized(spriteBatch, sprite.Texture, new Vector2(position.X, position.Y), sourceRectangle, color, scale * sprite.Scale); + } + else + { + var normalizedPosition = new Vector2( + (float)Math.Round(position.X * MapManager.Camera.Scale) / MapManager.Camera.Scale, + (float)Math.Round(position.Y * MapManager.Camera.Scale) / MapManager.Camera.Scale); + + DrawInstrument(spriteBatch, sprite, normalizedPosition); + } + } + + public static void DrawInstrument(SpriteBatch spriteBatch, DictAtlasEntry sprite, Vector2 position) + { + var rectangle = sprite.ScaledRectangle; + + // draw the item + spriteBatch.Draw(Resources.SprItem, position, + new Rectangle(rectangle.X + 0, rectangle.Y, rectangle.Width, rectangle.Height), Color.White, 0, Vector2.Zero, sprite.Scale, SpriteEffects.None, 0); + + spriteBatch.Draw(Resources.SprItem, position, + new Rectangle(rectangle.X + 16 * sprite.TextureScale, rectangle.Y, rectangle.Width, rectangle.Height), _relictColorOne, 0, Vector2.Zero, sprite.Scale, SpriteEffects.None, 0); ; + + spriteBatch.Draw(Resources.SprItem, position, + new Rectangle(rectangle.X + 32 * sprite.TextureScale, rectangle.Y, rectangle.Width, rectangle.Height), _relictColorTwo, 0, Vector2.Zero, sprite.Scale, SpriteEffects.None, 0); + } + + public static void DrawRelictBackground(SpriteBatch spriteBatch, Vector2 position) + { + // draw the background + spriteBatch.Draw(Resources.SprItem, position, _recRelicts, _relictColorOne); + } + + public static void DrawItemWithInfo(SpriteBatch spriteBatch, GameItemCollected itemCollected, Point offset, Rectangle rectangle, int scale, Color color) + { + if (itemCollected == null) + return; + + var item = Game1.GameManager.ItemManager[itemCollected.Name]; + + Rectangle sourceRectangle; + if (item.SourceRectangle.HasValue) + sourceRectangle = item.SourceRectangle.Value; + else + { + // at least the base item needs to have a source rectangle + var baseItem = Game1.GameManager.ItemManager[item.Name]; + sourceRectangle = baseItem.SourceRectangle.Value; + } + + var width = sourceRectangle.Width; + + if (item.Level > 0) + width += 1 + RecLetters.Width * 2 + LetterMargin; + else if (item.MaxCount != 1) + width += 1 + RecLetters.Width * item.DrawLength + LetterMargin; + + var itemPosition = new Point( + offset.X + rectangle.X * scale + rectangle.Width * scale / 2 - width / 2 * scale, + offset.Y + rectangle.Y * scale + rectangle.Height * scale / 2 - sourceRectangle.Height / 2 * scale); + + var textPosition = new Point( + itemPosition.X + (sourceRectangle.Width + 1) * scale, + itemPosition.Y + sourceRectangle.Height * scale - RecLetters.Height * scale); + + // draw the item + DrawItem(spriteBatch, item, new Vector2(itemPosition.X, itemPosition.Y), color, scale); + + if (item.Level > 0) + { + // draw the level of the item + DrawLevel(spriteBatch, + textPosition.X, textPosition.Y, + -item.Level, scale, Color.Black * (color.A / 255f)); + } + else if (item.MaxCount != 1) + { + // draw the count of the item + DrawNumber(spriteBatch, + textPosition.X, textPosition.Y, + itemCollected.Count, item.DrawLength, scale, Color.Black * (color.A / 255f)); + } + } + + public static Rectangle GetRubeeRectangle(Point position, int scale) + { + return new Rectangle( + position.X - _paddingHud * scale, position.Y - _paddingHud * scale, + ((RecLetters.Width + LetterMargin) * 3 + RecRubee.Width + _paddingHud * 2) * scale, + (RecLetters.Height + _paddingHud * 2) * scale); + } + + public static void DrawRubee(SpriteBatch spriteBatch, Point position, int scale, Color color) + { + // draw the number + DrawNumber(spriteBatch, position.X, position.Y, _rubyCount, 3, scale, color); + + // draw the rubee count + spriteBatch.Draw(SpriteRubee.Texture, new Rectangle( + position.X + (RecLetters.Width + LetterMargin) * 3 * scale, + position.Y - 1 * scale, + RecRubee.Width * scale, + RecRubee.Height * scale), RecRubee, Color.White * (color.A / 255f)); + } + + public static Rectangle GetHeartRectangle(Point position, int scale) + { + var width = MathHelper.Clamp(Game1.GameManager.MaxHearths, 0, 7); + var height = (int)Math.Ceiling(Game1.GameManager.MaxHearths / 7.0f); + return new Rectangle(position.X - _paddingHud * scale, position.Y - _paddingHud * scale, + (width * RecHeart.Width + (width - 1) + _paddingHud * 2) * scale, + (RecHeart.Height * height + _paddingHud * 2) * scale); + } + + public static void DrawHearts(SpriteBatch spriteBatch, Point position, int scale, Color color) + { + // draw the hearths + for (var i = 0; i < Game1.GameManager.MaxHearths; i++) + { + var heartValue = _heartCount - i * 4; + var type = 0; + + if (heartValue <= 0) + type = 4; + else if (heartValue <= 3) + type = 4 - heartValue; + + spriteBatch.Draw(SpriteHeart.Texture, new Rectangle( + position.X + (RecHeart.Width + _hearthDistance) * (i % 7) * scale, + position.Y + (RecHeart.Width + _hearthDistance) * (i / 7) * scale, + RecHeart.Width * scale, + RecHeart.Height * scale), + new Rectangle( + RecHeart.X + type * (RecHeart.Width + (int)(_heartsDistance * SpriteHeart.Scale)), + RecHeart.Y, RecHeart.Width, RecHeart.Height), color); + } + } + + //public static void DrawCollectedItem(SpriteBatch spriteBatch, string strName, Point offset, Rectangle drawPosition, int scale, Color backgroundColor) + //{ + + + // var keySourceRec = Game1.GameManager.GetItem(strName); + + // // draw the item + // if (keySourceRec != null) + // { + // var position = new Rectangle( + // drawPosition.X * scale + offset.X, + // drawPosition.Y * scale + offset.Y, + // drawPosition.Width * scale, drawPosition.Height * scale); + + // DrawItemWithInfo(spriteBatch, keySourceRec, position, scale, Color.White); + // } + //} + + //public static void DrawSmallKeys(SpriteBatch spriteBatch, Rectangle position) + //{ + // var keyItem = Game1.GameManager.GetItem("smallkey"); + + // if (keyItem == null) return; + + // var size = new Point(_recKey.Width + _letterSize.X , _recKey.Height ); + + // var drawPosition = new Point(position.X + position.Width / 2 - size.X / 2, position.Y + position.Height / 2 - size.Y / 2); + + // // draw the key icon + // spriteBatch.Draw(Resources.SprUI, new Rectangle( + // drawPosition.X, drawPosition.Y, _recKey.Width , _recKey.Height ), _recKey, Color.White * transparency); + + // // draw the number + // DrawNumber(spriteBatch, + // drawPosition.X + _recKey.Width , + // drawPosition.Y + (_recKey.Height / 2 - Values.LetterHeight / 2) , + // keyItem.Count, 1, _uiScale, Color.White * transparency); + //} + } +} \ No newline at end of file diff --git a/InGame/Things/ItemManager.cs b/InGame/Things/ItemManager.cs new file mode 100644 index 0000000..cdf43d9 --- /dev/null +++ b/InGame/Things/ItemManager.cs @@ -0,0 +1,914 @@ +using System.Collections.Generic; + +namespace ProjectZ.InGame.Things +{ + public class ItemManager + { + public Dictionary Items => _items; + + public GameItem this[string key] => key != null && _items.ContainsKey(key) ? _items[key] : null; + + private readonly Dictionary _items = new Dictionary(); + + public void Load() + { + // TODO_Opt: load all the items from a file + + // dungeon + // same keys but with different sounds and one does show the description + _items.Add("smallkey", new GameItem( + Resources.GetSprite("smallkey"), + name: "smallkey", + count: 1, + maxCount: 9, + drawLength: 1, + soundEffectName: "D370-01-01" + )); + _items.Add("smallkeyChest", new GameItem( + Resources.GetSprite("smallkey"), + name: "smallkey", + pickUpDialog: "smallkey", + count: 1, + drawLength: 1, + soundEffectName: "D360-01-01", + turnDownMusic: true + )); + _items.Add("nightmarekey", new GameItem( + Resources.GetSprite("nightmarekey"), + name: "nightmarekey", + maxCount: 1, + pickUpDialog: "nightmarekey", + soundEffectName: "D360-01-01", + turnDownMusic: true, + level: -1 + )); + _items.Add("compass", new GameItem( + Resources.GetSprite("compass"), + name: "compass", + count: 1, + maxCount: 1, + pickUpDialog: "compass", + soundEffectName: "D360-01-01", + turnDownMusic: true + )); + _items.Add("dmap", new GameItem( + Resources.GetSprite("dmap"), + name: "dmap", + count: 1, + maxCount: 1, + pickUpDialog: "dmap", + soundEffectName: "D360-01-01", + turnDownMusic: true + )); + _items.Add("stonebeak", new GameItem( + Resources.GetSprite("stonebeak"), + name: "stonebeak", + count: 1, + maxCount: 1, + pickUpDialog: "stonebeak", + soundEffectName: "D360-01-01", + turnDownMusic: true + )); + + _items.Add("potion", new GameItem( + Resources.GetSprite("potion"), + name: "potion", + count: 1, + maxCount: 1, + pickUpDialog: "potion", + soundEffectName: "D360-01-01", + turnDownMusic: true + )); + _items.Add("potion_show", new GameItem( + name: "potion", + count: 1, + showAnimation: 1, + soundEffectName: "D360-01-01", + turnDownMusic: true + )); + _items.Add("shell", new GameItem( + Resources.GetSprite("shell"), + Resources.GetSprite("shellMap"), + name: "shell", + pickUpDialog: "seashell", + count: 1, + soundEffectName: "D370-01-01" + )); + _items.Add("shellChest", new GameItem( + Resources.GetSprite("shell"), + Resources.GetSprite("shellMap"), + name: "shell", + pickUpDialog: "seashell", + count: 1, + soundEffectName: "D360-01-01", + turnDownMusic: true + )); + _items.Add("shellPresent", new GameItem( + Resources.GetSprite("shell_present"), + name: "shell", + pickUpDialog: "seashell", + count: 1, + showAnimation: 3, + soundEffectName: "D370-01-01" + )); + + // not sure why there are two differently colored versions + // I am using the same version ingame and in the menu + _items.Add("goldLeaf", new GameItem( + Resources.GetSprite("goldLeaf"), // icon used ingame, in the menu the less colorfull version is used + name: "goldLeaf", + pickUpDialog: "goldLeaf", + soundEffectName: "D368-16-10", + turnDownMusic: true, + count: 1, + showAnimation: 1, + showTime: 1500 + )); + + // instruments + _items.Add("instrument0", new GameItem( + Resources.GetSprite("instrument0"), + name: "instrument0", + pickUpDialog: "instrument0", + count: 1, + maxCount: 1, + isRelict: true, + showAnimation: 1, + showEffect: true, + showTime: 1500 + )); + _items.Add("instrument1", new GameItem( + Resources.GetSprite("instrument1"), + name: "instrument1", + pickUpDialog: "instrument1", + count: 1, + maxCount: 1, + isRelict: true, + showAnimation: 1, + showEffect: true, + showTime: 1500 + )); + _items.Add("instrument2", new GameItem( + Resources.GetSprite("instrument2"), + name: "instrument2", + pickUpDialog: "instrument2", + count: 1, + maxCount: 1, + isRelict: true, + showAnimation: 1, + showEffect: true, + showTime: 1500 + )); + _items.Add("instrument3", new GameItem( + Resources.GetSprite("instrument3"), + name: "instrument3", + pickUpDialog: "instrument3", + count: 1, + maxCount: 1, + isRelict: true, + showAnimation: 1, + showEffect: true, + showTime: 1500 + )); + _items.Add("instrument4", new GameItem( + Resources.GetSprite("instrument4"), + name: "instrument4", + pickUpDialog: "instrument4", + count: 1, + maxCount: 1, + isRelict: true, + showAnimation: 1, + showEffect: true, + showTime: 1500 + )); + _items.Add("instrument5", new GameItem( + Resources.GetSprite("instrument5"), + name: "instrument5", + pickUpDialog: "instrument5", + count: 1, + maxCount: 1, + isRelict: true, + showAnimation: 1, + showEffect: true, + showTime: 1500 + )); + _items.Add("instrument6", new GameItem( + Resources.GetSprite("instrument6"), + name: "instrument6", + pickUpDialog: "instrument6", + count: 1, + maxCount: 1, + isRelict: true, + showAnimation: 1, + showEffect: true, + showTime: 1500 + )); + _items.Add("instrument7", new GameItem( + Resources.GetSprite("instrument7"), + name: "instrument7", + pickUpDialog: "instrument7", + count: 1, + maxCount: 1, + isRelict: true, + showAnimation: 1, + showEffect: true, + showTime: 1500 + )); + + // trade items + _items.Add("trade0", new GameItem( + Resources.GetSprite("trade0"), + name: "trade0", + pickUpDialog: "yoshiPickup", + soundEffectName: "D368-16-10", + turnDownMusic: true, + count: 1, + maxCount: 1, + showAnimation: 1 + )); + _items.Add("trade1", new GameItem( + Resources.GetSprite("trade1"), + name: "trade1", + soundEffectName: "D368-16-10", + turnDownMusic: true, + count: 1, + maxCount: 1, + showAnimation: 1 + )); + _items.Add("trade2", new GameItem( + Resources.GetSprite("trade2"), + name: "trade2", + soundEffectName: "D368-16-10", + turnDownMusic: true, + count: 1, + maxCount: 1, + showAnimation: 1 + )); + _items.Add("trade3", new GameItem( + Resources.GetSprite("trade3"), + name: "trade3", + soundEffectName: "D368-16-10", + turnDownMusic: true, + count: 1, + maxCount: 1, + showAnimation: 1 + )); + _items.Add("trade4", new GameItem( + Resources.GetSprite("trade4"), + name: "trade4", + pickUpDialog: "trade4", + soundEffectName: "D368-16-10", + turnDownMusic: true, + count: 1, + maxCount: 1, + showAnimation: 1 + )); + _items.Add("trade5", new GameItem( + Resources.GetSprite("trade5"), + mapSprite: Resources.GetSprite("trade5Map"), + name: "trade5", + pickUpDialog: "trade5", + soundEffectName: "D368-16-10", + turnDownMusic: true, + count: 1, + maxCount: 1, + showAnimation: 1 + )); + _items.Add("trade6", new GameItem( + Resources.GetSprite("trade6"), + name: "trade6", + pickUpDialog: "trade6Collected", + soundEffectName: "D368-16-10", + turnDownMusic: true, + count: 1, + maxCount: 1, + showAnimation: 1 + )); + _items.Add("trade7", new GameItem( + Resources.GetSprite("trade7"), + name: "trade7", + pickUpDialog: "trade7", + soundEffectName: "D368-16-10", + turnDownMusic: true, + count: 1, + maxCount: 1, + showAnimation: 1 + )); + _items.Add("trade8", new GameItem( + Resources.GetSprite("trade8"), + name: "trade8", + pickUpDialog: "trade8", + soundEffectName: "D368-16-10", + turnDownMusic: true, + count: 1, + maxCount: 1, + showAnimation: 1 + )); + _items.Add("trade9", new GameItem( + // shown icon is browner + Resources.GetSprite("trade9"), + name: "trade9", + pickUpDialog: "trade9", + soundEffectName: "D368-16-10", + turnDownMusic: true, + count: 1, + maxCount: 1, + showAnimation: 1 + )); + _items.Add("trade10", new GameItem( + Resources.GetSprite("trade10"), + name: "trade10", + pickUpDialog: "trade10", + soundEffectName: "D368-16-10", + turnDownMusic: true, + count: 1, + maxCount: 1, + showAnimation: 1 + )); + _items.Add("trade11", new GameItem( + Resources.GetSprite("trade11"), + name: "trade11", + pickUpDialog: "trade11", + soundEffectName: "D368-16-10", + turnDownMusic: true, + count: 1, + maxCount: 1, + showAnimation: 1 + )); + _items.Add("trade12", new GameItem( + Resources.GetSprite("trade12"), + name: "trade12", + pickUpDialog: "trade12", + soundEffectName: "D368-16-10", + turnDownMusic: true, + count: 1, + maxCount: 1, + showAnimation: 1 + )); + _items.Add("trade13", new GameItem( + Resources.GetSprite("trade13"), + name: "trade13", + pickUpDialog: "trade13", + soundEffectName: "D368-16-10", + turnDownMusic: true, + count: 1, + maxCount: 1, + showAnimation: 1 + )); + + _items.Add("marin", new GameItem( + Resources.GetSprite("marin_item"), + name: "marin", + pickUpDialog: "maria_collected", + soundEffectName: "D368-16-10", + turnDownMusic: true, + count: 1, + maxCount: 1, + showAnimation: 1 + )); + _items.Add("rooster", new GameItem( + Resources.GetSprite("marin_item"), + name: "rooster", + pickUpDialog: "rooster", + count: 1, + maxCount: 1 + )); + _items.Add("ghost", new GameItem( + Resources.GetSprite("marin_item"), + name: "ghost", + count: 1, + maxCount: 1 + )); + + // overworld + // TODO: look into the colors + _items.Add("ruby", new GameItem( + Resources.GetSprite("rubyBlue"), + name: "ruby", + count: 1, + maxCount: 999, + soundEffectName: "D370-05-05" + )); + _items.Add("rubyGreen", new GameItem( + Resources.GetSprite("rubyGreen"), + animateSprite: true, + name: "ruby", + count: 5, + soundEffectName: "D370-05-05" + )); + // TODO: shouldnt red be 30? + _items.Add("ruby5", new GameItem( + Resources.GetSprite("rubyRed"), + name: "ruby", + count: 5, + soundEffectName: "D370-05-05" + )); + _items.Add("ruby10", new GameItem( + Resources.GetSprite("rubyBlue"), + name: "ruby", + count: 10, + soundEffectName: "D370-05-05" + )); + _items.Add("ruby20", new GameItem( + name: "ruby", + pickUpDialog: "ruby20", + count: 20, + soundEffectName: "D360-01-01", + turnDownMusic: true + )); + // trendy game ruby + _items.Add("ruby30", new GameItem( + Resources.GetSprite("rubyRed"), + name: "ruby", + pickUpDialog: "ruby30", + count: 30, + soundEffectName: "D370-05-05" + )); + _items.Add("ruby50", new GameItem( + name: "ruby", + pickUpDialog: "ruby50", + count: 50, + soundEffectName: "D360-01-01", + turnDownMusic: true + )); + _items.Add("ruby100", new GameItem( + name: "ruby", + pickUpDialog: "ruby100", + count: 100, + soundEffectName: "D360-01-01", + turnDownMusic: true + )); + _items.Add("ruby200", new GameItem( + Resources.GetSprite("rubyBlue"), + name: "ruby", + pickUpDialog: "ruby200", + count: 200, + soundEffectName: "D360-01-01", + turnDownMusic: true + )); + + _items.Add("heart", new GameItem( + Resources.GetSprite("heart"), + name: "heart", + count: 1, + maxCount: 999, + soundEffectName: "D370-06-06" + )); + _items.Add("heart_1", new GameItem( + Resources.GetSprite("heart"), + name: "heart", + pickUpDialog: "heart", + count: 1, + maxCount: 999, + soundEffectName: "D370-06-06" + )); + _items.Add("heart_3", new GameItem( + Resources.GetSprite("heart"), + name: "heart", + count: 3, + maxCount: 999, + soundEffectName: "D370-01-01" + )); + + _items.Add("heartMeter", new GameItem( + Resources.GetSprite("heartMeter"), + name: "heartMeter", + pickUpDialog: "heartMeter", + count: 1, + maxCount: 99, + showAnimation: 1, + soundEffectName: "D368-16-10", + turnDownMusic: true + )); + _items.Add("heartMeterSilent", new GameItem( + name: "heartMeter", + count: 1 + )); + _items.Add("heartMeterFull", new GameItem( + Resources.GetSprite("heartMeterFull"), + name: "heartMeter", + count: 4, + showAnimation: 1, + showTime: 1750, + pickUpDialog: "heartMeterFull" + )); + + // dungeon keys + _items.Add("dkey1", new GameItem( + Resources.GetSprite("dkey1"), + name: "dkey1", + pickUpDialog: "dkey1", + count: 1, + maxCount: 1, + showAnimation: 1, + soundEffectName: "D368-16-10", + turnDownMusic: true + )); + _items.Add("dkey2", new GameItem( + Resources.GetSprite("dkey2"), + name: "dkey2", + pickUpDialog: "dkey2", + count: 1, + maxCount: 1, + showAnimation: 1, + soundEffectName: "D368-16-10", + turnDownMusic: true + )); + _items.Add("dkey3", new GameItem( + Resources.GetSprite("dkey3"), + name: "dkey3", + pickUpDialog: "dkey3", + count: 1, + maxCount: 1, + showAnimation: 1, + soundEffectName: "D368-16-10", + turnDownMusic: true + )); + _items.Add("dkey4", new GameItem( + Resources.GetSprite("dkey4"), + name: "dkey4", + pickUpDialog: "dkey4", + count: 1, + maxCount: 1, + showAnimation: 1, + soundEffectName: "D368-16-10", + turnDownMusic: true + )); + _items.Add("dkey5", new GameItem( + Resources.GetSprite("dkey5"), + name: "dkey5", + pickUpDialog: "dkey5", + count: 1, + maxCount: 1, + showAnimation: 1, + soundEffectName: "D368-16-10", + turnDownMusic: true + )); + + _items.Add("guardianAcorn", new GameItem( + Resources.GetSprite("guardianAcorn"), + name: "guardianAcorn", + pickUpDialog: "guardianAcorn", + showAnimation: 2, + soundEffectName: "D360-23-17" + )); + _items.Add("pieceOfPower", new GameItem( + Resources.GetSprite("pieceOfPower"), + name: "pieceOfPower", + pickUpDialog: "pieceOfPower", + showAnimation: 2, + soundEffectName: "D360-23-17" + )); + _items.Add("sword1PoP", new GameItem( + Resources.GetSprite("sword1"), + name: "sword1PoP", + pickUpDialog: "pieceOfPower", + showAnimation: 2, + soundEffectName: "D360-23-17" + )); + _items.Add("sword2PoP", new GameItem( + Resources.GetSprite("sword2"), + name: "sword2PoP", + pickUpDialog: "pieceOfPower", + showAnimation: 2, + soundEffectName: "D360-23-17" + )); + + // level: = 0 => item as count + // level > 0 => item has level + // else => item has nothing + // accessories + _items.Add("sword1", new GameItem( + Resources.GetSprite("sword1"), + name: "sword1", + pickUpDialog: "sword1Collected", + count: 1, + maxCount: 1, + level: 1, + showAnimation: 1, + equipable: true, + showEffect: true, + showTime: 4000 + )); + _items.Add("sword2", new GameItem( + Resources.GetSprite("sword2"), + mapSprite: Resources.GetSprite("swordSpawn"), + name: "sword2", + count: 1, + maxCount: 1, + level: 2, + showAnimation: 2, + equipable: true + )); + _items.Add("shield", new GameItem( + Resources.GetSprite("shield"), + name: "shield", + pickUpDialog: "shield_intro", + soundEffectName: "D368-16-10", + turnDownMusic: true, + count: 1, + maxCount: 1, + level: 1, + showAnimation: 1, + equipable: true + )); + _items.Add("shield0", new GameItem( + Resources.GetSprite("shield"), + name: "shield", + pickUpDialog: "shield", + soundEffectName: "D370-01-01", + count: 1, + maxCount: 1, + level: 1, + equipable: true + )); + _items.Add("shieldBack", new GameItem( + Resources.GetSprite("shield"), + name: "shield", + pickUpDialog: "shield_back", + soundEffectName: "D370-01-01", + count: 1, + maxCount: 1, + level: 1, + equipable: true + )); + _items.Add("mirrorShield", new GameItem( + Resources.GetSprite("mirror shield"), + name: "mirrorShield", + pickUpDialog: "mirrorShield", + soundEffectName: "D368-16-10", + turnDownMusic: true, + count: 1, + maxCount: 1, + level: 2, + showAnimation: 1, + equipable: true + )); + _items.Add("toadstool", new GameItem( + Resources.GetSprite("toadstool"), + Resources.GetSprite("toadstoolMap"), + name: "toadstool", + pickUpDialog: "toadstool", + count: 1, + maxCount: 1, + level: -1, + showAnimation: 1, + equipable: true, + soundEffectName: "D368-16-10", + turnDownMusic: true + )); + _items.Add("feather", new GameItem( + Resources.GetSprite("feather"), + name: "feather", + pickUpDialog: "feather", + count: 1, + maxCount: 1, + level: -1, + equipable: true, + soundEffectName: "D368-16-10", + turnDownMusic: true + )); + _items.Add("stonelifter", new GameItem( + Resources.GetSprite("stonelifter0"), + name: "stonelifter", + pickUpDialog: "bracelet0", + count: 1, + maxCount: 1, + level: 1, + showAnimation: 1, + equipable: true, + soundEffectName: "D368-16-10", + turnDownMusic: true + )); + _items.Add("stonelifter2", new GameItem( + Resources.GetSprite("stonelifter1"), + // base is not supported for different sprites + name: "stonelifter2", + pickUpDialog: "bracelet1", + count: 1, + maxCount: 1, + level: 2, + showAnimation: 1, + equipable: true, + soundEffectName: "D368-16-10", + turnDownMusic: true + )); + _items.Add("pegasusBoots", new GameItem( + Resources.GetSprite("pegasusBoots"), + name: "pegasusBoots", + pickUpDialog: "pegasusBoots", + count: 1, + maxCount: 1, + level: -1, + //showAnimation: 1, + equipable: true, + soundEffectName: "D368-16-10", + turnDownMusic: true + )); + _items.Add("shovel", new GameItem( + Resources.GetSprite("shovel"), + name: "shovel", + pickUpDialog: "shovel", + count: 1, + maxCount: 1, + level: -1, + showAnimation: 1, + equipable: true, + soundEffectName: "D368-16-10", + turnDownMusic: true + )); + _items.Add("flippers", new GameItem( + Resources.GetSprite("flippers"), + name: "flippers", + pickUpDialog: "flippers", + count: 1, + maxCount: 1, + soundEffectName: "D368-16-10", + turnDownMusic: true + )); + _items.Add("magicRod", new GameItem( + Resources.GetSprite("magicRod"), + name: "magicRod", + pickUpDialog: "magicRod", + count: 1, + maxCount: 1, + level: -1, + showAnimation: 1, + equipable: true, + soundEffectName: "D368-16-10", + turnDownMusic: true + )); + _items.Add("ocarina", new GameItem( + Resources.GetSprite("ocarina"), + name: "ocarina", + pickUpDialog: "ocarina", + count: 1, + maxCount: 1, + level: -1, + equipable: true, + soundEffectName: "D368-16-10", + turnDownMusic: true + )); + _items.Add("ocarina_frog", new GameItem( + Resources.GetSprite("ocarina"), + name: "ocarina_frog", + pickUpDialog: "ocarina_frog_collected", + count: 1, + maxCount: 1, + showAnimation: 1, + soundEffectName: "D368-16-10", + turnDownMusic: true + )); + _items.Add("ocarina_maria", new GameItem( + Resources.GetSprite("ocarina"), + name: "ocarina_maria", + pickUpDialog: "ocarina_maria_collected", + count: 1, + maxCount: 1, + showAnimation: 1, + soundEffectName: "D368-16-10", + turnDownMusic: true + )); + _items.Add("ocarina_manbo", new GameItem( + Resources.GetSprite("ocarina"), + name: "ocarina_manbo", + pickUpDialog: "ocarina_manbo_collected", + count: 1, + maxCount: 1, + showAnimation: 1, + soundEffectName: "D368-16-10", + turnDownMusic: true + )); + _items.Add("hookshot", new GameItem( + Resources.GetSprite("hookshot"), + name: "hookshot", + pickUpDialog: "hookshot", + count: 1, + maxCount: 1, + level: -1, + showAnimation: 1, + equipable: true, + soundEffectName: "D368-16-10", + turnDownMusic: true + )); + _items.Add("boomerang", new GameItem( + Resources.GetSprite("boomerang"), + name: "boomerang", + pickUpDialog: "boomerang", + count: 1, + maxCount: 1, + level: -1, + showAnimation: 1, + equipable: true, + soundEffectName: "D368-16-10", + turnDownMusic: true + )); + + _items.Add("powder", new GameItem( + Resources.GetSprite("powder"), + name: "powder", + count: 20, + maxCount: 20, + level: 0, + equipable: true, + soundEffectName: "D370-01-01", + turnDownMusic: true + )); + _items.Add("powderTrendy", new GameItem( + Resources.GetSprite("powder"), + soundEffectName: "D370-01-01", + name: "powder", + pickUpDialog: "powder", + count: 10 + )); + _items.Add("powder_1", new GameItem( + name: "powder", + count: 1, + soundEffectName: "D370-01-01" + )); + _items.Add("powder_10", new GameItem( + name: "powder", + count: 10, + soundEffectName: "D370-01-01" + )); + _items.Add("powderPD", new GameItem( + name: "powder", + pickUpDialog: "powder", + count: 20, + showAnimation: 2, + soundEffectName: "D360-01-01", + turnDownMusic: true + )); + _items.Add("bomb", new GameItem( + Resources.GetSprite("bomb"), + name: "bomb", + pickUpDialog: "bomb", + count: 10, + maxCount: 30, + level: 0, + soundEffectName: "D370-01-01", + equipable: true + )); + _items.Add("bombChest", new GameItem( + name: "bomb", + pickUpDialog: "bomb", + count: 1, + soundEffectName: "D360-01-01", + turnDownMusic: true + )); + _items.Add("bomb_1", new GameItem( + name: "bomb", + count: 1, + soundEffectName: "D370-01-01" + )); + _items.Add("bomb_10", new GameItem( + name: "bomb", + count: 10, + soundEffectName: "D370-01-01" + )); + _items.Add("bow", new GameItem( + Resources.GetSprite("bow"), + name: "bow", + count: 10, + maxCount: 30, + level: 0, + equipable: true + )); + _items.Add("arrow", new GameItem( + Resources.GetSprite("arrow"), + name: "arrow", + count: 10, + soundEffectName: "D370-01-01" + )); + _items.Add("arrow_1", new GameItem( + Resources.GetSprite("arrow"), + name: "arrow", + count: 1, + soundEffectName: "D370-01-01" + )); + + _items.Add("cloakRed", new GameItem( + Resources.GetSprite("cloak"), + name: "cloakRed", + pickUpDialog: "cloak_red", + count: 1, + maxCount: 1, + level: -1, + showAnimation: 1, + soundEffectName: "D360-01-01", + turnDownMusic: true + )); + _items.Add("cloakBlue", new GameItem( + Resources.GetSprite("cloak"), + name: "cloakBlue", + pickUpDialog: "cloak_blue", + count: 1, + maxCount: 1, + level: -1, + showAnimation: 1, + soundEffectName: "D360-01-01", + turnDownMusic: true + )); + } + } +} diff --git a/InGame/Things/Language.cs b/InGame/Things/Language.cs new file mode 100644 index 0000000..3dd215c --- /dev/null +++ b/InGame/Things/Language.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace ProjectZ.InGame.Things +{ + public class Language + { + public Dictionary Strings => _languageStrings[CurrentLanguageIndex]; + + private Dictionary[] _languageStrings; + + public int CurrentLanguageIndex; + + public void Load() + { + // go through the .lng files and fill the _languageStrings dictionary array + var files = Directory.GetFiles(Values.PathLanguageFolder); + var languageStrings = new Dictionary>(); + // the default (first) entry is english + languageStrings.Add("eng", new Dictionary()); + + for (var i = 0; i < files.Length; i++) + { + var extension = Path.GetExtension(files[i]); + if (extension == ".lng") + { + var fileName = Path.GetFileNameWithoutExtension(files[i]); + var split = fileName.Split('_'); + var lngName = ""; + + // eng.lng + if (split.Length == 1) + lngName = split[0]; + // dialog_eng.lng + if (split.Length == 2) + lngName = split[1]; + + languageStrings.TryGetValue(lngName, out Dictionary dict); + + if (dict == null) + { + dict = new Dictionary(); + languageStrings.Add(lngName, dict); + } + + if (split.Length == 1 || (split.Length == 2 && split[0] == "dialog")) + LoadFile(dict, files[i]); + } + } + + _languageStrings = languageStrings.Values.ToArray(); + CurrentLanguageIndex = Math.Clamp(CurrentLanguageIndex, 0, _languageStrings.Length - 1); + } + + public void LoadFile(Dictionary dictionary, string fileName) + { + var reader = new StreamReader(fileName); + + while (!reader.EndOfStream) + { + var strLine = reader.ReadLine(); + var spacePosition = strLine.IndexOf(' '); + + if (spacePosition < 0 || strLine.StartsWith("//")) + continue; + + var strKey = strLine.Substring(0, spacePosition); + + // empty string + if (spacePosition + 1 >= strLine.Length) + { + dictionary.Add(strKey, ""); + continue; + } + + var strValue = strLine.Substring(spacePosition + 1); + + dictionary.Add(strKey, strValue); + } + + reader.Close(); + } + + public string GetString(string strKey, string defaultString) + { + if (strKey == null) + return "null"; + + if (Strings.ContainsKey(strKey)) + defaultString = Strings[strKey]; + + // use the english text if there is no translation + else if (_languageStrings[0].ContainsKey(strKey)) + defaultString = _languageStrings[0][strKey]; + + return defaultString; + } + + public void ToggleLanguage() + { + CurrentLanguageIndex = (CurrentLanguageIndex + 1) % _languageStrings.Length; + } + } +} diff --git a/InGame/Things/Resources.cs b/InGame/Things/Resources.cs new file mode 100644 index 0000000..b88858b --- /dev/null +++ b/InGame/Things/Resources.cs @@ -0,0 +1,342 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Audio; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using ProjectZ.InGame.SaveLoad; + +namespace ProjectZ.InGame.Things +{ + internal class Resources + { + public class Texture + { + public string Name; + public Texture2D SprTexture; + + public Texture(string name) + { + Name = name; + } + } + + public static Effect RoundedCornerEffect; + + public static Effect BlurEffect; + public static Effect RoundedCornerBlurEffect; + + public static Effect BlurEffectV; + public static Effect BlurEffectH; + public static Effect BBlurEffectV; + public static Effect BBlurEffectH; + public static Effect BBlurMapping; + public static Effect FullShadowEffect; + public static Effect SaturationEffect; + public static Effect WobbleEffect; + public static Effect CircleShader; + public static Effect LightShader; + public static Effect LightFadeShader; + public static Effect ThanosShader; + + // some sprites need different parameters set + // we try to use as little different sprites effects as possible + public static SpriteShader DamageSpriteShader0; + public static SpriteShader DamageSpriteShader1; + public static SpriteShader CloudShader; + public static SpriteShader ThanosSpriteShader0; + public static SpriteShader ThanosSpriteShader1; + public static SpriteShader WindFishShader; + public static SpriteShader ColorShader; + + public static SpriteShader ShockShader0; + public static SpriteShader ShockShader1; + + public static SpriteFont EditorFont, EditorFontMonoSpace, EditorFontSmallMonoSpace; + public static SpriteFont GameFont, GameHeaderFont; + public static SpriteFont FontCredits, FontCreditsHeader; + + public static Texture2D EditorEyeOpen, EditorEyeClosed, EditorIconDelete; + + public static Texture2D SprWhite, SprTiledBlock, SprObjects, SprObjectsAnimated, SprItem, SprNpCs; + public static Texture2D SprEnemies, SprMidBoss, SprNightmares, SprMiniMap; + public static Texture2D SprShadow; + public static Texture2D SprBlurTileset; + public static Texture2D SprPhotos; + public static Texture2D SprLink, SprLinkCloak; + public static Texture2D SprGameSequences; + public static Texture2D SprGameSequencesFinal; + public static Texture2D SprFog; + public static Texture2D SprLight; + public static Texture2D SprLightRoomH; + public static Texture2D SprLightRoomV; + public static Texture2D NoiseTexture; + + public static Texture2D SprIconOptions, SprIconErase, SprIconCopy, EditorIconEdit, EditorIconSelect; + + public static List TextureList = new List(); + + public static Dictionary SpriteAtlas = new Dictionary(); + public static Dictionary TilesetSizes = new Dictionary(); + + public static Dictionary SoundEffects = new Dictionary(); + + public static int GameFontHeight = 10; + public static int EditorFontHeight; + + // resources needed to start showing the intro + public static void LoadIntro(GraphicsDevice graphics, ContentManager content) + { + // TODO: make sure to only load the stuff needed; BlurEffect is not needed but needs changes to not load it here + + SprWhite = new Texture2D(graphics, 1, 1); + SprWhite.SetData(new[] { Color.White }); + + LoadTexturesFromFolder(Values.PathContentFolder + "/Intro/"); + + BlurEffect = content.Load("Shader/EffectBlur"); + RoundedCornerBlurEffect = content.Load("Shader/RoundedCornerEffectBlur"); + + AddSoundEffect(content, "D378-15-0F"); + AddSoundEffect(content, "D378-12-0C"); + AddSoundEffect(content, "D378-25-19"); + } + + public static void LoadTextures(GraphicsDevice graphics, ContentManager content) + { + // load the tileset sizes + LoadTilesetSizes(); + + LoadTexture(out SprGameSequences, Values.PathContentFolder + "Sequences/game sequences.png"); + LoadTexture(out SprGameSequencesFinal, Values.PathContentFolder + "Sequences/end sequence.png"); + LoadTexture(out SprPhotos, Values.PathContentFolder + "Photo Mode/photos.png"); + LoadTexture(out var bigEditorIcons, Values.PathContentFolder + "Editor/editorIcons4x.png"); + LoadTexture(out var SprUI, Values.PathContentFolder + "ui.png"); + + LoadTexturesFromFolder(Values.PathContentFolder + "/Sequences/"); + LoadTexturesFromFolder(Values.PathContentFolder + "/Light/"); + + // load all the tileset textures + LoadTexturesFromFolder(Values.PathTilesetFolder); + + LoadTexturesFromFolder(Values.PathMapObjectFolder); + + SprMiniMap = GetTexture("minimap.png"); + SprItem = GetTexture("items.png"); + + SprLink = GetTexture("link0.png"); + SprLinkCloak = GetTexture("link_cloak.png"); + SprEnemies = GetTexture("enemies.png"); + SprNpCs = GetTexture("npcs.png"); + SprObjects = GetTexture("objects.png"); + SprObjectsAnimated = GetTexture("objects animated.png"); + SprMidBoss = GetTexture("midboss.png"); + SprNightmares = GetTexture("nightmares.png"); + SprBlurTileset = GetTexture("blur tileset.png"); + + // load fonts + EditorFont = content.Load("Fonts/editor font"); + EditorFontHeight = (int)EditorFont.MeasureString("H").Y; + + EditorFontMonoSpace = content.Load("Fonts/editor mono font"); + + EditorFontSmallMonoSpace = content.Load("Fonts/editor small mono font"); + + GameFont = content.Load("Fonts/smallFont"); + GameFont.LineSpacing = GameFontHeight; + + GameHeaderFont = content.Load("Fonts/newHeaderFont"); + + FontCredits = content.Load("Fonts/credits font"); + FontCreditsHeader = content.Load("Fonts/credits header font"); + + // load textures + SprTiledBlock = new Texture2D(graphics, 2, 2); + SprTiledBlock.SetData(new[] { Color.White, Color.LightGray, Color.LightGray, Color.White }); + + EditorEyeOpen = content.Load("Editor/eye_open"); + EditorEyeClosed = content.Load("Editor/eye_closed"); + EditorIconDelete = content.Load("Editor/delete"); + EditorIconEdit = content.Load("Editor/edit"); + EditorIconSelect = content.Load("Editor/select"); + + SprLight = content.Load("Light/light"); + SprLightRoomH = content.Load("Light/ligth room"); + SprLightRoomV = content.Load("Light/ligth room vertical"); + + SprShadow = content.Load("Light/shadow"); + LoadContentTextureWithAtlas(content, "Light/doorLight"); + + SprIconOptions = content.Load("Menu/gearIcon"); + SprIconErase = content.Load("Menu/trashIcon"); + SprIconCopy = content.Load("Menu/copyIcon"); + + // need to have pre multiplied alpha + SprFog = content.Load("Objects/fog"); + + // load shader + RoundedCornerEffect = content.Load("Shader/RoundedCorner"); + BlurEffectH = content.Load("Shader/BlurH"); + BlurEffectV = content.Load("Shader/BlurV"); + BBlurEffectH = content.Load("Shader/BBlurH"); + BBlurEffectV = content.Load("Shader/BBlurV"); + FullShadowEffect = content.Load("Shader/FullShadowEffect"); + // used in the inventory + SaturationEffect = content.Load("Shader/SaturationFilter"); + WobbleEffect = content.Load("Shader/WobbleShader"); + CircleShader = content.Load("Shader/CircleShader"); + LightShader = content.Load("Shader/LightShader"); + LightFadeShader = content.Load("Shader/LightFadeShader"); + + var cloudShader = content.Load("Shader/ColorCloud"); + CloudShader = new SpriteShader(cloudShader); + CloudShader.FloatParameter.Add("scaleX", 1); + CloudShader.FloatParameter.Add("scaleY", 1); + + NoiseTexture = GetTexture("thanos noise.png"); + ThanosShader = content.Load("Shader/ThanosShader"); + ThanosShader.Parameters["NoiceTexture"].SetValue(NoiseTexture); + // only works for sprites using the sequence sprite + ThanosShader.Parameters["Scale"].SetValue(new Vector2( + (float)SprGameSequencesFinal.Width / NoiseTexture.Width, + (float)SprGameSequencesFinal.Height / NoiseTexture.Height)); + + ThanosSpriteShader0 = new SpriteShader(ThanosShader); + ThanosSpriteShader0.FloatParameter.Add("Percentage", 0); + ThanosSpriteShader1 = new SpriteShader(ThanosShader); + ThanosSpriteShader1.FloatParameter.Add("Percentage", 0); + + WindFishShader = new SpriteShader(content.Load("Shader/WaleShader")); + WindFishShader.FloatParameter.Add("Offset", 0); + WindFishShader.FloatParameter.Add("Period", 0); + + ColorShader = new SpriteShader(content.Load("Shader/ColorShader")); + + var damageShader = content.Load("Shader/DamageShader"); + + // crow needs mark1 to have a value bigger than 0.605333 + DamageSpriteShader0 = new SpriteShader(damageShader); + DamageSpriteShader0.FloatParameter.Add("mark0", 0.1f); + DamageSpriteShader0.FloatParameter.Add("mark1", 0.725f); + + // stone hinox needs mark1 to be below 0.553 + DamageSpriteShader1 = new SpriteShader(damageShader); + DamageSpriteShader1.FloatParameter.Add("mark0", 0.1f); + DamageSpriteShader1.FloatParameter.Add("mark1", 0.55f); + + var shockShader = content.Load("Shader/ShockEffect"); + + ShockShader0 = new SpriteShader(shockShader); + ShockShader0.FloatParameter.Add("mark0", 0.0f); + ShockShader0.FloatParameter.Add("mark1", 0.2675f); + ShockShader0.FloatParameter.Add("mark2", 0.725f); + + ShockShader1 = new SpriteShader(shockShader); + ShockShader1.FloatParameter.Add("mark0", 0.0f); + ShockShader1.FloatParameter.Add("mark1", 0.35f); + ShockShader1.FloatParameter.Add("mark2", 0.625f); + } + + public static void LoadSounds(ContentManager content) + { + // load all the sound effects + var soundEffectFiles = Directory.GetFiles(content.RootDirectory + "/SoundEffects").ToList(); + foreach (var path in soundEffectFiles) + { + var fileName = Path.GetFileNameWithoutExtension(path); + AddSoundEffect(content, fileName); + } + } + + public static void AddSoundEffect(ContentManager content, string fileName) + { + var soundEffect = content.Load("SoundEffects/" + fileName); + + // try add is used because some files may already be loaded for the intro sequence + SoundEffects.TryAdd(fileName, soundEffect); + } + + public static void LoadContentTextureWithAtlas(ContentManager content, string filePath) + { + var texture = content.Load(filePath); + + // load the sprite atlas + var atlasPath = Values.PathContentFolder + filePath + ".atlas"; + SpriteAtlasSerialization.LoadSourceDictionary(texture, atlasPath, SpriteAtlas); + } + + public static void LoadTexturesFromFolder(string path) + { + var texturePaths = Directory.GetFiles(path).ToList(); + + foreach (var filePath in texturePaths) + { + if (!filePath.Contains(".png")) + continue; + + var newTexture = new Texture(Path.GetFileName(filePath)); + LoadTexture(out newTexture.SprTexture, filePath); + TextureList.Add(newTexture); + } + } + + public static void LoadTexture(out Texture2D texture, string strFilePath) + { + using Stream stream = File.Open(strFilePath, FileMode.Open); + + texture = Texture2D.FromStream(Game1.Graphics.GraphicsDevice, stream); + + // load the sprite atlas + var atlasFileName = strFilePath.Replace(".png", ".atlas"); + SpriteAtlasSerialization.LoadSourceDictionary(texture, atlasFileName, SpriteAtlas); + } + + public static Texture2D GetTexture(string name) + { + for (var i = 0; i < TextureList.Count; i++) + { + if (TextureList[i].Name == name) + return TextureList[i].SprTexture; + } + + return null; + } + + public static Rectangle SourceRectangle(string id) + { + return SpriteAtlas.ContainsKey(id) ? SpriteAtlas[id].ScaledRectangle : Rectangle.Empty; + } + + public static DictAtlasEntry GetSprite(string id) + { + return SpriteAtlas.ContainsKey(id) ? SpriteAtlas[id] : null; + } + + public static void LoadTilesetSizes() + { + var fileName = Values.PathTilesetFolder + "tileset size.txt"; + + if (File.Exists(fileName)) + { + using var reader = new StreamReader(fileName); + + while (!reader.EndOfStream) + { + var line = reader.ReadLine(); + + // comment? + if (line.StartsWith("//")) + continue; + + var split = line.Split(':'); + if (split.Length != 2) + continue; + + if (int.TryParse(split[1], out var value)) + TilesetSizes.Add(split[0], value); + } + } + } + } +} diff --git a/InGame/Things/SpriteShader.cs b/InGame/Things/SpriteShader.cs new file mode 100644 index 0000000..1f0e10d --- /dev/null +++ b/InGame/Things/SpriteShader.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework.Graphics; + +namespace ProjectZ.InGame.Things +{ + // Maybe this was actually unnecessary and we could have just used variations of Effects. + // Currently we do not need to dynamically set the parameters and only use this for the damage shader that has 2 variants. + public class SpriteShader + { + public Effect Effect; + public Dictionary FloatParameter = new Dictionary(); + + public SpriteShader(Effect effect) + { + Effect = effect; + } + } +} diff --git a/InGame/Things/Values.cs b/InGame/Things/Values.cs new file mode 100644 index 0000000..0083528 --- /dev/null +++ b/InGame/Things/Values.cs @@ -0,0 +1,123 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; + +namespace ProjectZ.InGame.Things +{ + public partial class Values + { + public static string VersionString = "v1.0.0"; + + public static Color ColorBackgroundLight = Color.Black * 0.8f; + public static Color ColorBackgroundDark = Color.Black * 0.85f; + public static Color ColorUiEditor = new Color(41, 57, 85) * 0.85f; + + public static Color MenuButtonColor = new Color(40, 64, 128); + public static Color MenuButtonColorSelected = new Color(112, 144, 216); + public static Color MenuButtonColorSlider = new Color(40, 64, 128); + + public static Color InventoryBackgroundColorTop = new Color(255, 255, 230) * 0.85f; + public static Color InventoryBackgroundColor = new Color(255, 255, 230) * 0.75f; + + public static Color GameMenuBackgroundColor = new Color(255, 255, 255, 255); + + public static Color TextboxBackgroundColor = new Color(0, 0, 0) * 0.85f; + public static Color TextboxBackgroundSideColor = new Color(248, 248, 136) * 0.65f; + public static Color TextboxBlurColor = new Color(255, 255, 255, 255); + public static Color TextboxFontColor = new Color(248, 248, 136); + + public static Color MapTransitionColor = new Color(0, 0, 0, 255); + public static Color MapFirstTransitionColor = new Color(20, 20, 20, 255); + + public static Color OverlayBackgroundColor = new Color(255, 255, 190) * 0.55f; + public static Color OverlayBackgroundBlurColor = new Color(255, 255, 255, 255); + + public static Color[] SkirtColors = { new Color(16, 168, 64), new Color(0, 38, 255), new Color(255, 0, 0) }; + + public static string PathSaveFolder = "SaveFiles/"; + + public static string PathContentFolder = "Data/"; + public static string PathLanguageFolder => PathContentFolder + "Languages/"; + public static string PathMapsFolder => PathContentFolder + "Maps/"; + public static string PathTilesetFolder => PathContentFolder + "Maps/Tilesets/"; + public static string PathMapObjectFolder => PathContentFolder + "Map Objects/"; + public static string PathLightsFolder => PathContentFolder + "Lights/"; + public static string PathAnimationFolder => PathContentFolder + "Animations/"; + public static string PathMinimapFolder => PathContentFolder + "Dungeon/"; + + public const string EditorUiObjectEditor = "objectEditor"; + public const string EditorUiObjectSelection = "objectSelection"; + public const string EditorUiTileEditor = "tileEditor"; + public const string EditorUiTileSelection = "tileSelection"; + public const string EditorUiDigTileEditor = "digTileEditor"; + public const string EditorUiMusicTileEditor = "musicTileEditor"; + public const string EditorUiTileExtractor = "tileExtractor"; + public const string EditorUiTilesetEditor = "tilesetEditor"; + public const string EditorUiAnimation = "animationEditor"; + public const string EditorUiSpriteAtlas = "spriteAtlasEditor"; + + public const string ScreenNameIntro = "INTRO"; + public const string ScreenNameMenu = "MENU"; + public const string ScreenNameGame = "GAME"; + public const string ScreenGameOver = "GAMEOVER"; + public const string ScreenNameMap = "MAP"; + public const string ScreenNameSettings = "SETTINGS"; + public const string ScreenEnding = "ENDING"; + + public const string ScreenNameEditor = "MAP_EDITOR"; + public const string ScreenNameEditorTileset = "TILESET_EDITOR"; + public const string ScreenNameEditorTilesetExtractor = "TILESET_EXTRACTOR"; + public const string ScreenNameEditorAnimation = "ANIMATION_EDITOR"; + public const string ScreenNameSpriteAtlasEditor = "SPRITE_ATLAS_EDITOR"; + + public static Keys DebugToggleDebugText = Keys.F1; + public static Keys DebugToggleDebugModeKey = Keys.F2; + public static Keys DebugBox = Keys.F3; + public static Keys DebugSaveKey = Keys.F5; + public static Keys DebugLoadKey = Keys.F6; + public static Keys DebugShadowKey = Keys.F9; + + public static float ControllerDeadzone = 0.1f; + + public const float UiBackgroundRadius = 2.0f; + public const float UiTextboxRadius = 3.0f; + + public static int TileSize = 16; + public static int FieldWidth = 160; + public static int FieldHeight = 128; + + public static int ToolBarHeight = 40; + + public static int LayerBackground = 0; // layer behind tileset + public static int LayerBottom = 1; // layer under the player (grass, water, flowers, etc.) + public static int LayerPlayer = 2; // same player as the player + public static int LayerTop = 3; // on top of the player + + public static int LightLayer0 = 0; // lamp + public static int LightLayer1 = 1; // teleporter light + public static int LightLayer2 = 2; // dark room + public static int LightLayer3 = 3; + + public static int HandItemSlots = 4; + + public static int MinWidth = 160 * 2 + 60; // 160 + public static int MinHeight = 128 * 2; // 128 + + public static double MenuHeaderSize = 0.2; + public static double MenuContentSize = 0.65; + public static double MenuFooterSize = 0.15; + + public static int LetterWidth = 8; + public static int LetterHeight = 8; + + public static int GameSaveBlackScreen = 250; + public static int GameRespawnBlackScreen = 250; + + public static float ShadowHeightDefault = 0.75f; + public static float ShadowRotationDefault = 0.0f; + + public static int SaveRetries = 10; + public static int LoadRetries = 10; + + public const float SoundEffectVolumeMult = 0.85f; + } +} diff --git a/InGame/Things/Values.cs.bak b/InGame/Things/Values.cs.bak new file mode 100644 index 0000000..e196b69 --- /dev/null +++ b/InGame/Things/Values.cs.bak @@ -0,0 +1,123 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; + +namespace ProjectZ.InGame.Things +{ + public partial class Values + { + public static string VersionString = "v1.0"; + + public static Color ColorBackgroundLight = Color.Black * 0.8f; + public static Color ColorBackgroundDark = Color.Black * 0.85f; + public static Color ColorUiEditor = new Color(41, 57, 85) * 0.85f; + + public static Color MenuButtonColor = new Color(40, 64, 128); + public static Color MenuButtonColorSelected = new Color(112, 144, 216); + public static Color MenuButtonColorSlider = new Color(40, 64, 128); + + public static Color InventoryBackgroundColorTop = new Color(255, 255, 230) * 0.85f; + public static Color InventoryBackgroundColor = new Color(255, 255, 230) * 0.75f; + + public static Color GameMenuBackgroundColor = new Color(255, 255, 255, 255); + + public static Color TextboxBackgroundColor = new Color(0, 0, 0) * 0.85f; + public static Color TextboxBackgroundSideColor = new Color(248, 248, 136) * 0.65f; + public static Color TextboxBlurColor = new Color(255, 255, 255, 255); + public static Color TextboxFontColor = new Color(248, 248, 136); + + public static Color MapTransitionColor = new Color(0, 0, 0, 255); + public static Color MapFirstTransitionColor = new Color(20, 20, 20, 255); + + public static Color OverlayBackgroundColor = new Color(255, 255, 190) * 0.55f; + public static Color OverlayBackgroundBlurColor = new Color(255, 255, 255, 255); + + public static Color[] SkirtColors = { new Color(16, 168, 64), new Color(0, 38, 255), new Color(255, 0, 0) }; + + public static string PathSaveFolder = "SaveFiles/"; + + public static string PathContentFolder = "Data/"; + public static string PathLanguageFolder => PathContentFolder + "Languages/"; + public static string PathMapsFolder => PathContentFolder + "Maps/"; + public static string PathTilesetFolder => PathContentFolder + "Maps/Tilesets/"; + public static string PathMapObjectFolder => PathContentFolder + "Map Objects/"; + public static string PathLightsFolder => PathContentFolder + "Lights/"; + public static string PathAnimationFolder => PathContentFolder + "Animations/"; + public static string PathMinimapFolder => PathContentFolder + "Dungeon/"; + + public const string EditorUiObjectEditor = "objectEditor"; + public const string EditorUiObjectSelection = "objectSelection"; + public const string EditorUiTileEditor = "tileEditor"; + public const string EditorUiTileSelection = "tileSelection"; + public const string EditorUiDigTileEditor = "digTileEditor"; + public const string EditorUiMusicTileEditor = "musicTileEditor"; + public const string EditorUiTileExtractor = "tileExtractor"; + public const string EditorUiTilesetEditor = "tilesetEditor"; + public const string EditorUiAnimation = "animationEditor"; + public const string EditorUiSpriteAtlas = "spriteAtlasEditor"; + + public const string ScreenNameIntro = "INTRO"; + public const string ScreenNameMenu = "MENU"; + public const string ScreenNameGame = "GAME"; + public const string ScreenGameOver = "GAMEOVER"; + public const string ScreenNameMap = "MAP"; + public const string ScreenNameSettings = "SETTINGS"; + public const string ScreenEnding = "ENDING"; + + public const string ScreenNameEditor = "MAP_EDITOR"; + public const string ScreenNameEditorTileset = "TILESET_EDITOR"; + public const string ScreenNameEditorTilesetExtractor = "TILESET_EXTRACTOR"; + public const string ScreenNameEditorAnimation = "ANIMATION_EDITOR"; + public const string ScreenNameSpriteAtlasEditor = "SPRITE_ATLAS_EDITOR"; + + public static Keys DebugToggleDebugText = Keys.F1; + public static Keys DebugToggleDebugModeKey = Keys.F2; + public static Keys DebugBox = Keys.F3; + public static Keys DebugSaveKey = Keys.F5; + public static Keys DebugLoadKey = Keys.F6; + public static Keys DebugShadowKey = Keys.F9; + + public static float ControllerDeadzone = 0.1f; + + public const float UiBackgroundRadius = 2.0f; + public const float UiTextboxRadius = 3.0f; + + public static int TileSize = 16; + public static int FieldWidth = 160; + public static int FieldHeight = 128; + + public static int ToolBarHeight = 40; + + public static int LayerBackground = 0; // layer behind tileset + public static int LayerBottom = 1; // layer under the player (grass, water, flowers, etc.) + public static int LayerPlayer = 2; // same player as the player + public static int LayerTop = 3; // on top of the player + + public static int LightLayer0 = 0; // lamp + public static int LightLayer1 = 1; // teleporter light + public static int LightLayer2 = 2; // dark room + public static int LightLayer3 = 3; + + public static int HandItemSlots = 4; + + public static int MinWidth = 160 * 2 + 60; // 160 + public static int MinHeight = 128 * 2; // 128 + + public static double MenuHeaderSize = 0.2; + public static double MenuContentSize = 0.65; + public static double MenuFooterSize = 0.15; + + public static int LetterWidth = 8; + public static int LetterHeight = 8; + + public static int GameSaveBlackScreen = 250; + public static int GameRespawnBlackScreen = 250; + + public static float ShadowHeightDefault = 0.75f; + public static float ShadowRotationDefault = 0.0f; + + public static int SaveRetries = 10; + public static int LoadRetries = 10; + + public const float SoundEffectVolumeMult = 0.85f; + } +} diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..3cd495e --- /dev/null +++ b/Program.cs @@ -0,0 +1,34 @@ +using System; +using System.Windows.Forms; + +namespace ProjectZ +{ + public static class Program + { + [STAThread] + static void Main(string[] args) + { + var editorMode = false; + var loadFirstSave = false; + + foreach (var arg in args) + { + if (arg == "editor") + editorMode = true; + else if (arg == "loadSave") + loadFirstSave = true; + } + + try + { + using (var game = new Game1(editorMode, loadFirstSave)) + game.Run(); + } + catch (Exception exception) + { + MessageBox.Show(exception.StackTrace, exception.Message, MessageBoxButtons.OK, MessageBoxIcon.Error); + throw; + } + } + } +} \ No newline at end of file diff --git a/ProjectZ.csproj b/ProjectZ.csproj new file mode 100644 index 0000000..0106ff1 --- /dev/null +++ b/ProjectZ.csproj @@ -0,0 +1,82 @@ + + + WinExe + net6.0-windows + win-x64 + false + false + true + Windows + + + + TRACE;WINDOWS + + + + + + + + + + + + + + + + + + + + + + + + + ..\MonoGame\Artifacts\MonoGame.Framework\WindowsDX\Release\MonoGame.Framework.dll + + + ..\MonoGame\Artifacts\MonoGame.Framework\WindowsDX\Release\SharpDX.dll + + + ..\MonoGame\Artifacts\MonoGame.Framework\WindowsDX\Release\SharpDX.Direct2D1.dll + + + ..\MonoGame\Artifacts\MonoGame.Framework\WindowsDX\Release\SharpDX.Direct3D11.dll + + + ..\MonoGame\Artifacts\MonoGame.Framework\WindowsDX\Release\SharpDX.Direct3D9.dll + + + ..\MonoGame\Artifacts\MonoGame.Framework\WindowsDX\Release\SharpDX.DXGI.dll + + + ..\MonoGame\Artifacts\MonoGame.Framework\WindowsDX\Release\SharpDX.Mathematics.dll + + + ..\MonoGame\Artifacts\MonoGame.Framework\WindowsDX\Release\SharpDX.MediaFoundation.dll + + + ..\MonoGame\Artifacts\MonoGame.Framework\WindowsDX\Release\SharpDX.XAudio2.dll + + + ..\MonoGame\Artifacts\MonoGame.Framework\WindowsDX\Release\SharpDX.XInput.dll + + + + dotnet + true + ..\MonoGame\Artifacts\MonoGame.Content.Builder\Debug\mgcb.dll + ProjectZ.Program + Link's Awakening DX HD + true + Resources\Icon.ico + app.manifest + + + TRACE;WINDOWS + + + \ No newline at end of file diff --git a/ProjectZ.sln b/ProjectZ.sln new file mode 100644 index 0000000..a266330 --- /dev/null +++ b/ProjectZ.sln @@ -0,0 +1,34 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32526.322 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProjectZ", "ProjectZ.csproj", "{3A3F8C88-9271-4122-BEA4-377064822A14}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3A3F8C88-9271-4122-BEA4-377064822A14}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3A3F8C88-9271-4122-BEA4-377064822A14}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3A3F8C88-9271-4122-BEA4-377064822A14}.Debug|x86.ActiveCfg = Debug|Any CPU + {3A3F8C88-9271-4122-BEA4-377064822A14}.Debug|x86.Build.0 = Debug|Any CPU + {3A3F8C88-9271-4122-BEA4-377064822A14}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3A3F8C88-9271-4122-BEA4-377064822A14}.Release|Any CPU.Build.0 = Release|Any CPU + {3A3F8C88-9271-4122-BEA4-377064822A14}.Release|x86.ActiveCfg = Release|Any CPU + {3A3F8C88-9271-4122-BEA4-377064822A14}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {63CDECBD-18A4-419A-8FE4-B8F53DDC1778} + EndGlobalSection + GlobalSection(Performance) = preSolution + HasPerformanceSessions = true + EndGlobalSection +EndGlobal diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs new file mode 100644 index 0000000..3083c6e --- /dev/null +++ b/Properties/Resources.Designer.cs @@ -0,0 +1,73 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ProjectZ.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ProjectZ.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). + /// + internal static System.Drawing.Icon Icon { + get { + object obj = ResourceManager.GetObject("Icon", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + } +} diff --git a/Properties/Resources.resx b/Properties/Resources.resx new file mode 100644 index 0000000..653c9e8 --- /dev/null +++ b/Properties/Resources.resx @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/Resources/Icon.ico b/Resources/Icon.ico new file mode 100644 index 0000000..a669e09 Binary files /dev/null and b/Resources/Icon.ico differ diff --git a/app.config b/app.config new file mode 100644 index 0000000..e225dd4 --- /dev/null +++ b/app.config @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/app.manifest b/app.manifest new file mode 100644 index 0000000..0322302 --- /dev/null +++ b/app.manifest @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true/pm + permonitorv2,permonitor + + + + diff --git a/bin/Data/Animations/Enemies/angler fry.ani b/bin/Data/Animations/Enemies/angler fry.ani new file mode 100644 index 0000000..fbd3087 --- /dev/null +++ b/bin/Data/Animations/Enemies/angler fry.ani @@ -0,0 +1,4 @@ +1 +nightmares.png +move_-1;;-1;0;0;2;267;16;112;16;16;0;0;0;0;0;0;False;False;300;34;112;16;16;0;0;0;0;0;0;False;False +move_1;;-1;0;0;2;267;16;112;16;16;0;0;0;0;0;0;False;True;300;34;112;16;16;0;0;0;0;0;0;False;True diff --git a/bin/Data/Animations/Enemies/anti kirby suck.ani b/bin/Data/Animations/Enemies/anti kirby suck.ani new file mode 100644 index 0000000..d8399fc --- /dev/null +++ b/bin/Data/Animations/Enemies/anti kirby suck.ani @@ -0,0 +1,5 @@ +1 +enemies.png +suck_0;;-1;0;0;2;133;196;368;14;20;-7;-20;0;0;0;0;False;False;133;212;368;4;9;-1;-14;0;0;0;0;False;False +suck_1;;-1;0;0;2;133;196;368;14;20;-7;-20;0;0;0;0;False;True;133;212;368;4;9;-2;-14;0;0;0;0;False;False +hidden;;0;0;0;1;83;203;377;2;2;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/anti kirby.ani b/bin/Data/Animations/Enemies/anti kirby.ani new file mode 100644 index 0000000..b09faab --- /dev/null +++ b/bin/Data/Animations/Enemies/anti kirby.ani @@ -0,0 +1,8 @@ +1 +enemies.png +idle_0;;0;0;0;1;83;160;371;16;14;-8;-14;0;0;0;0;False;False +idle_1;;0;0;0;1;83;160;371;16;14;-8;-14;0;0;0;0;False;True +suck_0;;0;0;0;1;83;178;369;16;16;-8;-16;0;0;0;0;False;False +suck_1;;0;0;0;1;83;178;369;16;16;-8;-16;0;0;0;0;False;True +full_0;;0;0;0;1;83;165;387;24;15;-12;-15;0;0;0;0;False;False +full_1;;0;0;0;1;83;165;387;24;15;-12;-15;0;0;0;0;False;True diff --git a/bin/Data/Animations/Enemies/anti-fairy.ani b/bin/Data/Animations/Enemies/anti-fairy.ani new file mode 100644 index 0000000..758ca74 --- /dev/null +++ b/bin/Data/Animations/Enemies/anti-fairy.ani @@ -0,0 +1,3 @@ +1 +enemies.png +idle;;-1;0;0;2;133;114;184;16;16;0;0;0;0;0;0;False;False;133;132;184;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/arm mimic.ani b/bin/Data/Animations/Enemies/arm mimic.ani new file mode 100644 index 0000000..8893014 --- /dev/null +++ b/bin/Data/Animations/Enemies/arm mimic.ani @@ -0,0 +1,6 @@ +1 +enemies.png +walk_3;;-1;0;0;2;133;240;176;16;16;0;0;0;0;0;0;False;False;133;240;176;16;16;0;0;0;0;0;0;False;True +walk_0;;-1;0;0;2;133;209;177;15;15;0;1;0;0;0;0;False;False;133;225;176;14;16;1;0;0;0;0;0;False;False +walk_1;;-1;0;0;2;133;257;176;16;16;0;0;0;0;0;0;False;False;133;257;176;16;16;0;0;0;0;0;0;False;True +walk_2;;-1;0;0;2;133;209;177;15;15;1;1;0;0;0;0;False;True;133;225;176;14;16;1;0;0;0;0;0;False;True diff --git a/bin/Data/Animations/Enemies/armos.ani b/bin/Data/Animations/Enemies/armos.ani new file mode 100644 index 0000000..b0d0003 --- /dev/null +++ b/bin/Data/Animations/Enemies/armos.ani @@ -0,0 +1,8 @@ +1 +enemies.png +idle;;0;0;0;1;83;1;320;16;16;0;0;0;0;0;0;False;False +awaking;;3;0;0;2;67;35;320;16;16;0;0;0;0;0;0;False;False;67;1;320;16;16;0;0;0;0;0;0;False;False +walking;;-1;0;0;2;267;1;320;16;16;0;0;0;0;0;0;False;False;267;18;320;16;16;0;0;0;0;0;0;False;False +idle_dark;;0;0;0;1;83;52;320;16;16;0;0;0;0;0;0;False;False +awaking_dark;;3;0;0;2;67;52;320;16;16;0;0;0;0;0;0;False;False;67;35;320;16;16;0;0;0;0;0;0;False;False +walking_dark;;-1;0;0;2;267;52;320;16;16;0;0;0;0;0;0;False;False;267;69;320;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/beamos.ani b/bin/Data/Animations/Enemies/beamos.ani new file mode 100644 index 0000000..1a36e68 --- /dev/null +++ b/bin/Data/Animations/Enemies/beamos.ani @@ -0,0 +1,3 @@ +1 +enemies.png +idle;;-1;0;2;8;267;385;306;15;14;-8;-14;0;0;0;0;False;False;267;402;304;14;16;-7;-16;0;0;0;0;False;False;267;418;304;14;16;-7;-16;0;0;0;0;False;False;267;402;304;14;16;-7;-16;0;0;0;0;False;True;267;385;306;15;14;-7;-14;0;0;0;0;False;True;267;369;306;14;14;-7;-14;0;0;0;0;False;True;267;353;306;14;14;-7;-14;0;0;0;0;False;False;267;369;306;14;14;-7;-14;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/beetle.ani b/bin/Data/Animations/Enemies/beetle.ani new file mode 100644 index 0000000..6ab946a --- /dev/null +++ b/bin/Data/Animations/Enemies/beetle.ani @@ -0,0 +1,3 @@ +1 +enemies.png +idle;;-1;0;0;2;133;288;99;16;11;0;0;0;0;0;0;False;True;133;288;99;16;11;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/bladetrap.ani b/bin/Data/Animations/Enemies/bladetrap.ani new file mode 100644 index 0000000..5721482 --- /dev/null +++ b/bin/Data/Animations/Enemies/bladetrap.ani @@ -0,0 +1,3 @@ +1 +enemies.png +IDLE;;-1;0;0;1;200;0;112;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/bloober.ani b/bin/Data/Animations/Enemies/bloober.ani new file mode 100644 index 0000000..19a58d3 --- /dev/null +++ b/bin/Data/Animations/Enemies/bloober.ani @@ -0,0 +1,4 @@ +1 +enemies.png +down;;0;0;0;1;83;192;312;16;14;0;0;0;0;0;0;False;False +up;;0;0;0;1;83;210;310;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/bomber.ani b/bin/Data/Animations/Enemies/bomber.ani new file mode 100644 index 0000000..f3ef027 --- /dev/null +++ b/bin/Data/Animations/Enemies/bomber.ani @@ -0,0 +1,3 @@ +1 +enemies.png +idle;;-1;0;0;4;67;22;342;24;16;0;0;0;0;0;0;False;False;67;1;342;20;16;2;0;0;0;0;0;False;False;67;22;342;24;16;0;0;0;0;0;0;False;False;83;47;343;22;15;1;1;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/bombite.ani b/bin/Data/Animations/Enemies/bombite.ani new file mode 100644 index 0000000..077a96b --- /dev/null +++ b/bin/Data/Animations/Enemies/bombite.ani @@ -0,0 +1,4 @@ +1 +enemies.png +idle;;-1;0;0;2;267;48;368;13;16;0;0;0;0;0;0;False;False;267;48;368;13;16;1;0;0;0;0;0;False;True +damage;;-1;0;0;2;83;48;368;13;16;0;0;0;0;0;0;False;False;67;48;368;13;16;1;0;0;0;0;0;False;True diff --git a/bin/Data/Animations/Enemies/bombiteGreen.ani b/bin/Data/Animations/Enemies/bombiteGreen.ani new file mode 100644 index 0000000..000b08d --- /dev/null +++ b/bin/Data/Animations/Enemies/bombiteGreen.ani @@ -0,0 +1,4 @@ +1 +enemies.png +idle;;-1;0;0;2;267;48;385;13;16;0;0;0;0;0;0;False;False;267;48;385;13;16;1;0;0;0;0;0;False;True +timer;;0;0;0;4;3000;63;385;14;16;0;0;0;0;0;0;False;False;1000;111;385;14;16;0;0;0;0;0;0;False;False;1000;95;387;14;14;0;2;0;0;0;0;False;False;1000;79;388;14;13;0;3;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/bone putter.ani b/bin/Data/Animations/Enemies/bone putter.ani new file mode 100644 index 0000000..a41c499 --- /dev/null +++ b/bin/Data/Animations/Enemies/bone putter.ani @@ -0,0 +1,4 @@ +1 +enemies.png +fly;;-1;0;0;2;133;323;330;27;19;-11;-19;0;0;0;0;False;False;133;323;351;27;17;-11;-17;0;0;0;0;False;False +jump;;0;0;0;1;83;352;343;14;16;-6;-16;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/bone.ani b/bin/Data/Animations/Enemies/bone.ani new file mode 100644 index 0000000..495d635 --- /dev/null +++ b/bin/Data/Animations/Enemies/bone.ani @@ -0,0 +1,3 @@ +1 +enemies.png +idle;;-1;0;0;2;133;300;67;10;10;0;0;0;0;0;0;False;False;133;300;67;10;10;0;0;0;0;0;0;True;False diff --git a/bin/Data/Animations/Enemies/boo buddy.ani b/bin/Data/Animations/Enemies/boo buddy.ani new file mode 100644 index 0000000..220e7d8 --- /dev/null +++ b/bin/Data/Animations/Enemies/boo buddy.ani @@ -0,0 +1,5 @@ +1 +enemies.png +attack;;-1;0;0;2;267;319;25;16;16;-8;-16;0;0;0;0;False;False;267;336;25;16;16;-8;-16;0;0;0;0;False;False +hit;;0;0;0;1;83;353;25;16;16;-8;-16;0;0;0;0;False;False +flee;;-1;0;0;2;267;320;42;14;16;-7;-16;0;0;0;0;False;False;267;335;45;16;13;-8;-13;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/buzzblob.ani b/bin/Data/Animations/Enemies/buzzblob.ani new file mode 100644 index 0000000..5899a22 --- /dev/null +++ b/bin/Data/Animations/Enemies/buzzblob.ani @@ -0,0 +1,5 @@ +1 +enemies.png +walk;;-1;0;0;4;133;47;177;13;14;0;2;0;0;0;0;False;False;133;62;175;12;16;0;0;0;0;0;0;False;False;133;47;177;13;14;0;2;0;0;0;0;False;True;133;62;175;12;16;0;0;0;0;0;0;False;False +cukeman;;-1;-1;0;4;133;61;192;14;16;0;0;0;0;0;0;False;False;133;46;192;13;16;0;0;0;0;0;0;False;False;133;61;192;14;16;0;0;0;0;0;0;False;False;133;46;192;13;16;1;0;0;0;0;0;False;True +shock;;2;0;0;4;133;93;192;13;16;-1;0;0;0;0;0;False;False;133;62;175;12;16;0;0;0;0;0;0;False;False;133;93;192;13;16;0;0;0;0;0;0;False;True;83;62;175;12;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/camo goblin.ani b/bin/Data/Animations/Enemies/camo goblin.ani new file mode 100644 index 0000000..a899129 --- /dev/null +++ b/bin/Data/Animations/Enemies/camo goblin.ani @@ -0,0 +1,14 @@ +1 +enemies.png +eyes_red;;0;0;0;1;83;241;360;14;8;-7;-8;0;0;0;0;False;False +spawn_red;;0;0;0;3;133;257;352;16;16;-8;-16;0;0;0;0;False;False;133;275;352;16;16;-8;-16;0;0;0;0;False;False;133;293;336;16;32;-8;-32;0;0;0;0;False;False +wobble_red;;0;0;0;2;133;293;336;16;32;-8;-32;0;0;0;0;False;False;133;293;336;16;32;-8;-32;0;0;0;0;False;True +despawn_red;;0;0;0;3;133;293;336;16;32;-8;-32;0;0;0;0;False;False;133;275;352;16;16;-8;-16;0;0;0;0;False;False;133;257;352;16;16;-8;-16;0;0;0;0;False;False +eyes_green;;0;0;0;1;83;241;394;14;8;-7;-8;0;0;0;0;False;False +spawn_green;;0;0;0;3;133;257;386;16;16;-8;-16;0;0;0;0;False;False;133;275;386;16;16;-8;-16;0;0;0;0;False;False;133;293;370;16;32;-8;-32;0;0;0;0;False;False +wobble_green;;2;0;0;2;133;293;370;16;32;-8;-32;0;0;0;0;False;False;133;293;370;16;32;-8;-32;0;0;0;0;False;True +despawn_green;;0;0;0;3;133;293;370;16;32;-8;-32;0;0;0;0;False;False;133;275;386;16;16;-8;-16;0;0;0;0;False;False;133;257;386;16;16;-8;-16;0;0;0;0;False;False +eyes_blue;;0;0;0;1;83;241;428;14;8;-7;-8;0;0;0;0;False;False +spawn_blue;;0;0;0;3;133;257;420;16;16;-8;-16;0;0;0;0;False;False;133;275;420;16;16;-8;-16;0;0;0;0;False;False;133;293;404;16;32;-8;-32;0;0;0;0;False;False +wobble_blue;;0;0;0;2;133;293;404;16;32;-8;-32;0;0;0;0;False;False;133;293;404;16;32;-8;-32;0;0;0;0;False;True +despawn_blue;;0;0;0;3;133;293;404;16;32;-8;-32;0;0;0;0;False;False;133;275;420;16;16;-8;-16;0;0;0;0;False;False;133;257;420;16;16;-8;-16;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/card boy.ani b/bin/Data/Animations/Enemies/card boy.ani new file mode 100644 index 0000000..afe5bce --- /dev/null +++ b/bin/Data/Animations/Enemies/card boy.ani @@ -0,0 +1,6 @@ +1 +enemies.png +1;;-1;0;0;2;133;245;1;16;16;0;0;0;0;0;0;False;False;133;245;1;16;16;0;0;0;0;0;0;False;True +2;;-1;0;0;2;133;209;1;16;16;0;0;0;0;0;0;False;False;133;209;1;16;16;0;0;0;0;0;0;False;True +3;;-1;0;0;2;133;227;1;16;16;0;0;0;0;0;0;False;False;133;227;1;16;16;0;0;0;0;0;0;False;True +4;;-1;0;0;2;133;263;1;16;16;0;0;0;0;0;0;False;False;133;263;1;16;16;0;0;0;0;0;0;False;True diff --git a/bin/Data/Animations/Enemies/cheep cheep.ani b/bin/Data/Animations/Enemies/cheep cheep.ani new file mode 100644 index 0000000..88e90a4 --- /dev/null +++ b/bin/Data/Animations/Enemies/cheep cheep.ani @@ -0,0 +1,6 @@ +1 +enemies.png +idle_2;;-1;0;0;2;133;240;311;16;16;0;0;0;0;0;0;False;False;133;258;311;16;16;0;0;0;0;0;0;False;False +idle_0;;-1;0;0;2;133;240;311;16;16;0;0;0;0;0;0;False;True;133;258;311;16;16;0;0;0;0;0;0;False;True +dead_2;;0;0;0;1;83;240;311;16;16;0;0;0;0;0;0;True;False +dead_0;;0;0;0;1;83;240;311;16;16;0;0;0;0;0;0;True;True diff --git a/bin/Data/Animations/Enemies/crab.ani b/bin/Data/Animations/Enemies/crab.ani new file mode 100644 index 0000000..91eb731 --- /dev/null +++ b/bin/Data/Animations/Enemies/crab.ani @@ -0,0 +1,4 @@ +1 +enemies.png +walk;;-1;0;0;2;133;0;80;16;16;0;0;0;0;0;0;False;False;133;16;80;16;16;0;0;0;0;0;0;False;False +fall;;0;0;0;3;200;81;1;10;10;0;0;0;0;0;0;False;False;200;92;1;6;6;2;2;0;0;0;0;False;False;200;99;1;4;4;3;3;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/crow.ani b/bin/Data/Animations/Enemies/crow.ani new file mode 100644 index 0000000..1db5707 --- /dev/null +++ b/bin/Data/Animations/Enemies/crow.ani @@ -0,0 +1,6 @@ +1 +enemies.png +idle_-1;;-1;0;0;1;200;81;64;13;16;0;0;0;0;0;0;False;False +idle_1;;-1;0;0;1;200;81;64;13;16;1;0;0;0;0;0;False;True +fly_-1;;-1;0;0;2;150;81;64;13;16;0;0;0;0;0;0;False;False;150;96;64;16;16;0;-1;0;0;0;0;False;False +fly_1;;-1;0;0;2;150;81;64;13;16;1;0;0;0;0;0;False;True;150;96;64;16;16;-2;-1;0;0;0;0;False;True diff --git a/bin/Data/Animations/Enemies/darknut spear.ani b/bin/Data/Animations/Enemies/darknut spear.ani new file mode 100644 index 0000000..e43f870 --- /dev/null +++ b/bin/Data/Animations/Enemies/darknut spear.ani @@ -0,0 +1,10 @@ +1 +enemies.png +walk_0;;-1;0;0;2;133;321;208;15;16;-7;-16;0;0;0;0;False;False;133;337;209;16;15;-7;-15;0;0;0;0;False;False +walk_1;;-1;0;0;2;133;355;208;16;16;-8;-16;0;0;0;0;False;False;133;373;208;16;16;-8;-16;0;0;0;0;False;False +walk_3;;-1;0;0;2;133;391;208;16;16;-8;-16;0;0;0;0;False;False;133;409;208;16;16;-8;-16;0;0;0;0;False;False +walk_2;;-1;0;0;2;133;321;208;15;16;-8;-16;0;0;0;0;False;True;133;337;209;16;15;-9;-15;0;0;0;0;False;True +stand_0;;0;0;0;1;83;321;208;15;16;-7;-16;0;0;0;0;False;False +stand_1;;0;0;0;1;83;355;208;16;16;-8;-16;0;0;0;0;False;False +stand_2;;0;0;0;1;83;321;208;15;16;-8;-16;0;0;0;0;False;True +stand_3;;0;0;0;1;83;391;208;16;16;-8;-16;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/darknut sword.ani b/bin/Data/Animations/Enemies/darknut sword.ani new file mode 100644 index 0000000..6ddea6f --- /dev/null +++ b/bin/Data/Animations/Enemies/darknut sword.ani @@ -0,0 +1,10 @@ +1 +enemies.png +walk_0;;-1;0;0;2;250;315;256;21;16;-5;0;0;9;15;6;False;False;250;338;257;29;15;-11;1;0;8;15;6;False;False +walk_3;;-1;0;0;2;250;406;249;18;23;-2;0;11;8;6;15;False;False;250;426;243;18;29;-2;0;11;14;6;15;False;False +walk_1;;-1;0;0;2;250;370;243;16;29;0;-13;2;0;6;15;False;False;250;388;249;16;23;0;-7;2;0;6;14;False;False +walk_2;;-1;0;0;2;250;315;256;21;16;0;0;0;9;15;6;False;True;250;338;257;29;15;-2;1;0;8;15;6;False;True +stand_0;;0;0;0;1;83;315;256;21;16;-5;0;0;9;15;6;False;False +stand_3;;0;0;0;1;83;406;249;18;23;-2;0;11;8;6;15;False;False +stand_1;;0;0;0;1;83;370;243;16;29;0;-13;2;0;6;15;False;False +stand_2;;0;0;0;1;83;315;256;21;16;0;0;0;9;15;6;False;True diff --git a/bin/Data/Animations/Enemies/darknut.ani b/bin/Data/Animations/Enemies/darknut.ani new file mode 100644 index 0000000..eead8fe --- /dev/null +++ b/bin/Data/Animations/Enemies/darknut.ani @@ -0,0 +1,10 @@ +1 +enemies.png +walk_0;;-1;0;0;2;250;315;256;21;16;-5;0;0;0;0;0;False;False;250;338;257;29;15;-11;1;0;0;0;0;False;False +walk_3;;-1;0;0;2;250;406;249;18;16;-2;0;0;0;0;0;False;False;250;426;243;18;16;-2;0;0;0;0;0;False;False +walk_1;;-1;0;0;2;250;370;256;16;16;0;0;0;0;0;0;False;False;250;388;256;16;16;0;0;0;0;0;0;False;False +walk_2;;-1;0;0;2;250;320;256;16;16;0;0;0;0;0;0;False;True;250;351;257;16;15;-2;1;0;0;0;0;False;True +stand_0;;0;0;0;1;83;320;256;16;16;0;0;0;0;0;0;False;False +stand_3;;0;0;0;1;83;406;249;18;16;-2;0;0;0;0;0;False;False +stand_1;;0;0;0;1;83;370;256;16;16;0;0;0;0;0;0;False;False +stand_2;;0;0;0;1;83;320;256;16;16;0;0;0;0;0;0;False;True diff --git a/bin/Data/Animations/Enemies/fireball dungeon.ani b/bin/Data/Animations/Enemies/fireball dungeon.ani new file mode 100644 index 0000000..87c6ab4 --- /dev/null +++ b/bin/Data/Animations/Enemies/fireball dungeon.ani @@ -0,0 +1,3 @@ +1 +enemies.png +idle;;-1;0;0;2;133;91;16;10;10;0;0;0;0;0;0;False;False;133;91;16;10;10;0;0;0;0;0;0;True;False diff --git a/bin/Data/Animations/Enemies/fireball.ani b/bin/Data/Animations/Enemies/fireball.ani new file mode 100644 index 0000000..cf672a8 --- /dev/null +++ b/bin/Data/Animations/Enemies/fireball.ani @@ -0,0 +1,3 @@ +1 +enemies.png +IDLE;;-1;0;0;4;50;80;16;10;10;0;0;0;0;0;0;False;False;50;91;16;10;10;0;0;0;0;0;0;False;False;50;80;16;10;10;0;0;0;0;0;0;True;False;50;91;16;10;10;0;0;0;0;0;0;True;False diff --git a/bin/Data/Animations/Enemies/fish.ani b/bin/Data/Animations/Enemies/fish.ani new file mode 100644 index 0000000..843d780 --- /dev/null +++ b/bin/Data/Animations/Enemies/fish.ani @@ -0,0 +1,5 @@ +1 +enemies.png +swim;;-1;0;0;1;267;164;179;8;9;-4;-12;0;0;0;0;False;False +jump_up;;-1;0;0;1;83;160;160;16;16;-8;-16;0;0;0;0;False;False +jump_down;;-1;0;0;1;83;176;160;16;16;-8;-16;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/flame fountain fireball.ani b/bin/Data/Animations/Enemies/flame fountain fireball.ani new file mode 100644 index 0000000..ee6f13a --- /dev/null +++ b/bin/Data/Animations/Enemies/flame fountain fireball.ani @@ -0,0 +1,5 @@ +1 +enemies.png +idle;;0;0;0;3;267;436;52;8;9;-4;-6;0;0;0;0;False;False;267;434;63;12;15;-6;-12;0;0;0;0;False;False;267;432;80;16;16;-8;-12;0;0;0;0;False;False +left;;0;0;0;1;83;432;98;16;16;-8;-8;0;0;0;0;False;False +right;;0;0;0;1;83;432;98;16;16;-8;-8;0;0;0;0;False;True diff --git a/bin/Data/Animations/Enemies/flame fountain.ani b/bin/Data/Animations/Enemies/flame fountain.ani new file mode 100644 index 0000000..6cffcd9 --- /dev/null +++ b/bin/Data/Animations/Enemies/flame fountain.ani @@ -0,0 +1,3 @@ +1 +enemies.png +idle;;-1;0;0;2;117;450;74;16;16;0;0;0;0;0;0;False;False;150;450;56;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/floor layer.ani b/bin/Data/Animations/Enemies/floor layer.ani new file mode 100644 index 0000000..b0c4ddf --- /dev/null +++ b/bin/Data/Animations/Enemies/floor layer.ani @@ -0,0 +1,3 @@ +1 +enemies.png +idle;;-1;0;0;2;267;208;416;16;14;-8;-14;0;0;0;0;False;False;267;209;398;14;16;-7;-16;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/flyingTile.ani b/bin/Data/Animations/Enemies/flyingTile.ani new file mode 100644 index 0000000..10ca042 --- /dev/null +++ b/bin/Data/Animations/Enemies/flyingTile.ani @@ -0,0 +1,7 @@ +1 +enemies.png +fly;;-1;0;0;2;133;282;186;12;13;-6;-7;0;0;0;0;False;False;133;296;185;16;16;-8;-8;0;0;0;0;False;False +idle_0;;0;0;0;1;83;279;168;16;16;-8;-8;0;0;0;0;False;False +idle_1;;0;0;0;1;83;296;168;16;16;-8;-8;0;0;0;0;False;False +idle_2;;0;0;0;1;83;408;184;16;16;-8;-8;0;0;0;0;False;False +fly_1;;-1;0;0;2;133;426;186;12;13;-6;-7;0;0;0;0;False;False;83;440;185;16;16;-8;-8;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/gel.ani b/bin/Data/Animations/Enemies/gel.ani new file mode 100644 index 0000000..ca25ffb --- /dev/null +++ b/bin/Data/Animations/Enemies/gel.ani @@ -0,0 +1,6 @@ +1 +enemies.png +1;;-1;0;0;1;200;0;132;7;7;0;0;0;0;0;0;False;False +-1;;-1;0;0;1;200;9;132;7;7;0;0;0;0;0;0;False;False +JUMP;;-1;0;0;2;66;0;132;7;7;0;0;0;0;0;0;False;False;66;9;132;7;7;-1;0;0;0;0;0;False;False +FALL;;0;0;0;3;200;81;1;10;10;0;0;0;0;0;0;False;False;200;92;1;6;6;2;2;0;0;0;0;False;False;200;99;1;4;4;3;3;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/ghini.ani b/bin/Data/Animations/Enemies/ghini.ani new file mode 100644 index 0000000..668809f --- /dev/null +++ b/bin/Data/Animations/Enemies/ghini.ani @@ -0,0 +1,4 @@ +1 +enemies.png +fly_-1;;-1;0;0;2;200;112;129;16;14;-8;-14;0;0;0;0;False;False;200;128;129;16;14;-8;-14;0;0;0;0;False;False +fly_1;;-1;0;0;2;200;112;129;16;14;-8;-14;0;0;0;0;False;True;200;128;129;16;14;-8;-14;0;0;0;0;False;True diff --git a/bin/Data/Animations/Enemies/ghiniGiant.ani b/bin/Data/Animations/Enemies/ghiniGiant.ani new file mode 100644 index 0000000..911ecfa --- /dev/null +++ b/bin/Data/Animations/Enemies/ghiniGiant.ani @@ -0,0 +1,4 @@ +1 +enemies.png +fly_-1;;-1;0;0;2;267;320;64;31;30;0;0;0;0;0;0;False;True;267;352;64;31;30;0;0;0;0;0;0;False;True +fly_1;;-1;1;0;2;267;320;64;31;30;0;0;0;0;0;0;False;False;267;352;64;31;30;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/giant bubble.ani b/bin/Data/Animations/Enemies/giant bubble.ani new file mode 100644 index 0000000..279c814 --- /dev/null +++ b/bin/Data/Animations/Enemies/giant bubble.ani @@ -0,0 +1,3 @@ +1 +enemies.png +idle;;-1;0;0;4;200;384;7;32;26;-16;-13;0;0;0;0;False;False;200;418;5;30;30;-15;-15;0;0;0;0;False;False;200;384;7;32;26;-16;-13;0;0;0;0;False;False;200;450;4;26;32;-13;-16;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/gibdo.ani b/bin/Data/Animations/Enemies/gibdo.ani new file mode 100644 index 0000000..7882d79 --- /dev/null +++ b/bin/Data/Animations/Enemies/gibdo.ani @@ -0,0 +1,3 @@ +1 +enemies.png +idle;;-1;0;0;2;267;320;384;16;16;0;0;0;0;0;0;False;False;267;320;384;16;16;0;0;0;0;0;0;False;True diff --git a/bin/Data/Animations/Enemies/goomba.ani b/bin/Data/Animations/Enemies/goomba.ani new file mode 100644 index 0000000..f38bdd6 --- /dev/null +++ b/bin/Data/Animations/Enemies/goomba.ani @@ -0,0 +1,4 @@ +1 +enemies.png +walk;;-1;0;0;2;200;160;48;16;16;0;0;0;0;0;0;False;False;200;160;48;16;16;0;0;0;0;0;0;False;True +dead;;-1;0;0;1;200;176;48;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/goponga flower giant.ani b/bin/Data/Animations/Enemies/goponga flower giant.ani new file mode 100644 index 0000000..51981d0 --- /dev/null +++ b/bin/Data/Animations/Enemies/goponga flower giant.ani @@ -0,0 +1,5 @@ +1 +enemies.png +idle;;5;0;2;2;267;289;131;30;28;1;1;0;0;0;0;False;False;267;256;130;32;30;0;0;0;0;0;0;False;False +attack;idle;0;0;0;1;1000;224;128;32;32;0;0;0;0;0;0;False;False +pre_attack;attack;0;0;2;1;267;256;130;32;30;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/goponga flower.ani b/bin/Data/Animations/Enemies/goponga flower.ani new file mode 100644 index 0000000..8dee953 --- /dev/null +++ b/bin/Data/Animations/Enemies/goponga flower.ani @@ -0,0 +1,3 @@ +1 +enemies.png +idle;;-1;0;0;2;783;224;64;16;16;0;0;0;0;0;0;False;False;267;241;65;14;15;1;1;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/green zol.ani b/bin/Data/Animations/Enemies/green zol.ani new file mode 100644 index 0000000..8cfc873 --- /dev/null +++ b/bin/Data/Animations/Enemies/green zol.ani @@ -0,0 +1,7 @@ +1 +enemies.png +SPAWN;;0;0;0;3;150;16;132;7;7;3;9;0;0;0;0;False;False;200;35;128;10;16;1;0;0;0;0;0;False;False;100;50;133;12;11;0;0;0;0;0;0;False;False +JUMP;;-1;0;0;1;200;35;128;10;16;1;0;0;0;0;0;False;False +IDLE;;-1;0;0;1;200;50;133;12;11;0;5;0;0;0;0;False;False +FALL;;0;0;0;3;200;81;1;10;10;0;0;0;0;0;0;False;False;200;92;1;6;6;2;2;0;0;0;0;False;False;200;99;1;4;4;3;3;0;0;0;0;False;False +DESPAWN;;0;0;0;3;200;35;128;10;16;1;0;0;0;0;0;False;False;133;16;132;7;7;3;9;0;0;0;0;False;False;133;25;132;7;7;3;9;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/hardhat beetle.ani b/bin/Data/Animations/Enemies/hardhat beetle.ani new file mode 100644 index 0000000..1a30ce6 --- /dev/null +++ b/bin/Data/Animations/Enemies/hardhat beetle.ani @@ -0,0 +1,4 @@ +1 +enemies.png +walk;;-1;0;0;2;133;0;146;16;14;-8;-14;0;0;0;0;False;False;133;16;144;16;16;-8;-16;0;0;0;0;False;False +stunned;;0;0;0;1;83;0;146;16;14;-8;-14;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/iron mask.ani b/bin/Data/Animations/Enemies/iron mask.ani new file mode 100644 index 0000000..7ed370a --- /dev/null +++ b/bin/Data/Animations/Enemies/iron mask.ani @@ -0,0 +1,7 @@ +1 +enemies.png +walk_0;;-1;0;0;2;133;405;145;15;15;0;0;0;0;0;0;False;False;133;421;145;16;15;0;0;0;0;0;0;False;False +walk_1;;-1;0;0;2;133;455;145;16;15;0;0;0;0;0;0;False;False;133;455;145;16;15;0;0;0;0;0;0;False;True +walk_2;;-1;0;0;2;133;405;145;15;15;1;0;0;0;0;0;False;True;133;421;145;16;15;0;0;0;0;0;0;False;True +walk_3;;-1;0;1;2;133;438;146;16;14;0;0;0;0;0;0;False;False;133;438;146;16;14;0;0;0;0;0;0;False;True +unprotected;;-1;0;3;2;267;405;164;16;12;0;0;0;0;0;0;False;False;267;405;164;16;12;0;0;0;0;0;0;False;True diff --git a/bin/Data/Animations/Enemies/karakoro.ani b/bin/Data/Animations/Enemies/karakoro.ani new file mode 100644 index 0000000..68b52c9 --- /dev/null +++ b/bin/Data/Animations/Enemies/karakoro.ani @@ -0,0 +1,8 @@ +1 +enemies.png +walk_1;;-1;-12;-16;2;133;381;336;24;16;0;0;0;0;0;0;False;False;133;381;336;24;16;0;0;0;0;0;0;False;True +walk_3;;-1;-12;-16;2;133;381;354;24;16;0;0;0;0;0;0;False;False;133;381;354;24;16;0;0;0;0;0;0;False;True +walk_2;;-1;-8;-16;2;133;385;390;16;16;0;0;0;0;0;0;False;False;133;385;372;16;16;0;0;0;0;0;0;False;False +walk_0;;-1;-8;-16;2;133;385;372;16;16;0;0;0;0;0;0;False;True;133;385;390;16;16;0;0;0;0;0;0;False;True +ball;;0;0;0;1;83;386;408;16;16;-8;-16;0;0;0;0;False;False +rotate;;-1;0;0;8;50;385;372;16;16;-8;-16;0;0;0;0;False;True;50;385;390;16;16;-8;-16;0;0;0;0;False;True;50;381;354;24;16;-12;-16;0;0;0;0;False;False;50;381;354;24;16;-12;-16;0;0;0;0;False;True;50;385;390;16;16;-8;-16;0;0;0;0;False;False;50;385;372;16;16;-8;-16;0;0;0;0;False;False;50;381;336;24;16;-12;-16;0;0;0;0;False;False;50;381;336;24;16;-12;-16;0;0;0;0;False;True diff --git a/bin/Data/Animations/Enemies/keese.ani b/bin/Data/Animations/Enemies/keese.ani new file mode 100644 index 0000000..89f84b0 --- /dev/null +++ b/bin/Data/Animations/Enemies/keese.ani @@ -0,0 +1,5 @@ +1 +enemies.png +FLY;;-1;0;0;2;133;36;19;8;10;4;0;0;0;0;0;False;False;133;48;21;16;8;0;0;0;0;0;0;False;False +IDLE;;-1;0;0;1;200;36;19;8;10;4;0;0;0;0;0;False;False +FALL;;0;0;0;3;200;81;1;10;10;0;0;0;0;0;0;False;False;200;92;1;6;6;2;2;0;0;0;0;False;False;200;99;1;4;4;3;3;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/leever.ani b/bin/Data/Animations/Enemies/leever.ani new file mode 100644 index 0000000..bad3d39 --- /dev/null +++ b/bin/Data/Animations/Enemies/leever.ani @@ -0,0 +1,6 @@ +1 +enemies.png +SPAWN;;0;0;0;3;200;0;64;16;16;0;0;0;0;0;0;False;False;200;16;64;16;16;0;0;0;0;0;0;False;False;200;32;64;16;16;0;0;0;0;0;0;False;False +MOVE;;-1;0;0;2;116;32;64;16;16;0;0;0;0;0;0;False;False;116;48;64;16;16;0;0;0;0;0;0;False;False +LEAVE;;0;0;0;3;200;32;64;16;16;0;0;0;0;0;0;False;False;200;16;64;16;16;0;0;0;0;0;0;False;False;200;0;64;16;16;0;0;0;0;0;0;False;False +FALL;;0;0;0;3;200;81;1;10;10;0;0;0;0;0;0;False;False;200;92;1;6;6;2;2;0;0;0;0;False;False;200;99;1;4;4;3;3;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/likelike.ani b/bin/Data/Animations/Enemies/likelike.ani new file mode 100644 index 0000000..1c56a3a --- /dev/null +++ b/bin/Data/Animations/Enemies/likelike.ani @@ -0,0 +1,3 @@ +1 +enemies.png +idle;;-1;0;0;2;267;0;177;16;15;0;1;0;0;0;0;False;False;267;17;176;14;16;1;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/mad bomber.ani b/bin/Data/Animations/Enemies/mad bomber.ani new file mode 100644 index 0000000..348f7b4 --- /dev/null +++ b/bin/Data/Animations/Enemies/mad bomber.ani @@ -0,0 +1,5 @@ +1 +enemies.png +come_0;;0;0;0;4;200;54;239;16;8;0;8;0;0;0;0;False;False;200;72;235;14;12;1;4;0;0;0;0;False;False;267;88;231;16;16;0;0;0;0;0;0;False;True;533;88;231;16;16;0;0;0;0;0;0;False;False +come_1;;0;0;0;4;200;54;239;16;8;0;8;0;0;0;0;False;False;200;72;235;14;12;1;4;0;0;0;0;False;False;267;88;231;16;16;0;0;0;0;0;0;False;False;533;88;231;16;16;0;0;0;0;0;0;False;True +leave;;0;0;0;2;133;72;235;14;12;1;4;0;0;0;0;False;False;117;54;239;16;8;0;8;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/mask mimic.ani b/bin/Data/Animations/Enemies/mask mimic.ani new file mode 100644 index 0000000..db154d9 --- /dev/null +++ b/bin/Data/Animations/Enemies/mask mimic.ani @@ -0,0 +1,6 @@ +1 +enemies.png +walk_3;;-1;0;0;2;267;1;256;16;16;-8;-16;0;0;0;0;False;False;267;1;256;16;16;-8;-16;0;0;0;0;False;True +walk_2;;-1;0;0;2;267;36;256;16;16;-8;-16;0;0;0;0;False;False;267;54;256;16;16;-8;-16;0;0;0;0;False;False +walk_1;;-1;0;0;2;267;19;256;15;16;-8;-16;0;0;0;0;False;False;267;19;256;15;16;-7;-16;0;0;0;0;False;True +walk_0;;-1;0;0;2;267;36;256;16;16;-8;-16;0;0;0;0;False;True;267;54;256;16;16;-8;-16;0;0;0;0;False;True diff --git a/bin/Data/Animations/Enemies/mega thwomp.ani b/bin/Data/Animations/Enemies/mega thwomp.ani new file mode 100644 index 0000000..ed9d90b --- /dev/null +++ b/bin/Data/Animations/Enemies/mega thwomp.ani @@ -0,0 +1,4 @@ +1 +enemies.png +idle;;0;0;0;1;83;328;103;32;31;0;0;0;0;0;0;False;False +hit;;0;0;0;1;83;361;103;32;31;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/mini moldorm.ani b/bin/Data/Animations/Enemies/mini moldorm.ani new file mode 100644 index 0000000..b8b6f51 --- /dev/null +++ b/bin/Data/Animations/Enemies/mini moldorm.ani @@ -0,0 +1,10 @@ +1 +enemies.png +1;;-1;0;0;1;200;160;0;16;16;0;0;0;0;0;0;False;False +0;;-1;0;0;1;200;176;0;16;16;0;0;0;0;0;0;False;False +7;;-1;0;0;1;200;160;0;16;16;0;0;0;0;0;0;False;True +6;;-1;0;0;1;200;160;16;16;16;0;0;0;0;0;0;False;True +5;;-1;0;0;1;200;160;0;16;16;0;0;0;0;0;0;True;True +4;;-1;0;0;1;200;176;0;16;16;0;0;0;0;0;0;True;False +3;;-1;0;0;1;200;160;0;16;16;0;0;0;0;0;0;True;False +2;;-1;0;0;1;200;160;16;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/moblin sword sword.ani b/bin/Data/Animations/Enemies/moblin sword sword.ani new file mode 100644 index 0000000..0ac417e --- /dev/null +++ b/bin/Data/Animations/Enemies/moblin sword sword.ani @@ -0,0 +1,10 @@ +1 +enemies.png +walk_0;;-1;0;0;2;250;112;209;29;15;-13;1;0;8;14;6;False;False;250;143;208;23;16;-7;0;0;9;14;6;False;False +walk_3;;-1;0;0;2;250;188;208;18;29;-2;0;11;14;6;15;False;False;250;168;208;18;23;-2;0;11;9;6;14;False;False +walk_1;;-1;0;0;2;250;227;195;16;29;0;-13;2;0;6;14;False;False;250;209;201;16;23;0;-7;2;0;6;9;False;False +walk_2;;-1;0;0;2;250;270;209;29;15;0;1;14;8;15;6;False;False;250;245;208;23;16;0;0;9;9;14;6;False;False +stand_0;;0;0;0;1;83;143;208;23;16;-7;0;0;9;14;6;False;False +stand_3;;0;0;0;1;83;168;208;18;23;-2;0;11;9;6;14;False;False +stand_1;;0;0;0;1;83;209;201;16;23;0;-7;2;0;6;10;False;False +stand_2;;0;0;0;1;83;245;208;23;16;0;0;8;9;15;6;False;False diff --git a/bin/Data/Animations/Enemies/moblin sword.ani b/bin/Data/Animations/Enemies/moblin sword.ani new file mode 100644 index 0000000..a0389bb --- /dev/null +++ b/bin/Data/Animations/Enemies/moblin sword.ani @@ -0,0 +1,10 @@ +1 +enemies.png +walk_0;;-1;0;0;2;250;112;209;29;15;-13;1;8;8;5;6;False;False;250;143;208;23;16;-7;0;8;9;5;6;False;False +walk_3;;-1;0;0;2;250;188;208;18;16;-2;0;11;16;6;5;False;False;250;168;208;18;16;-2;0;11;10;6;5;False;False +walk_1;;-1;0;0;2;250;227;208;16;16;0;0;2;8;6;6;False;False;250;209;208;16;16;0;0;3;7;4;3;False;False +walk_2;;-1;0;0;2;250;270;209;29;15;0;1;16;8;5;6;False;False;250;245;208;23;16;0;0;10;9;5;6;False;False +stand_0;;0;0;0;1;83;143;208;23;16;-7;0;0;0;0;0;False;False +stand_3;;0;0;0;1;83;168;208;18;16;-2;0;0;0;0;0;False;False +stand_1;;0;0;0;1;83;209;201;16;23;0;-7;0;0;0;0;False;False +stand_2;;0;0;0;1;83;245;208;23;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/moblin.ani b/bin/Data/Animations/Enemies/moblin.ani new file mode 100644 index 0000000..ed467f7 --- /dev/null +++ b/bin/Data/Animations/Enemies/moblin.ani @@ -0,0 +1,11 @@ +1 +enemies.png +walk_0;;-1;0;0;2;133;0;96;16;16;0;0;0;0;0;0;False;False;133;16;96;16;16;0;0;0;0;0;0;False;False +walk_1;;-1;0;0;2;133;32;96;16;16;0;0;0;0;0;0;False;False;133;48;96;16;16;0;0;0;0;0;0;False;False +walk_3;;-1;0;0;2;133;64;96;16;16;0;0;0;0;0;0;False;False;133;80;96;16;16;0;0;0;0;0;0;False;False +walk_2;;-1;0;0;2;133;96;96;16;16;0;0;0;0;0;0;False;False;133;112;96;16;16;0;0;0;0;0;0;False;False +fall;;0;0;0;3;200;81;1;10;10;0;0;0;0;0;0;False;False;200;92;1;6;6;2;2;0;0;0;0;False;False;200;99;1;4;4;3;3;0;0;0;0;False;False +stand_0;;0;0;0;1;83;16;96;16;16;0;0;0;0;0;0;False;False +stand_1;;0;0;0;1;83;32;96;16;16;0;0;0;0;0;0;False;False +stand_2;;0;0;0;1;83;96;96;16;16;0;0;0;0;0;0;False;False +stand_3;;0;0;0;1;83;64;96;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/moblinPig sword.ani b/bin/Data/Animations/Enemies/moblinPig sword.ani new file mode 100644 index 0000000..b992463 --- /dev/null +++ b/bin/Data/Animations/Enemies/moblinPig sword.ani @@ -0,0 +1,10 @@ +1 +enemies.png +walk_0;;-1;0;0;2;133;113;245;15;6;-13;9;0;0;15;6;False;False;133;113;245;15;6;-7;9;0;0;15;6;False;False +walk_3;;-1;0;0;2;133;150;240;17;22;-2;7;11;7;6;15;False;False;133;130;240;17;15;-2;8;11;0;6;15;False;False +walk_1;;-1;0;0;2;133;161;247;6;15;1;-13;0;0;6;15;True;False;133;161;247;6;15;1;-7;0;0;6;15;True;False +walk_2;;-1;0;0;2;133;113;245;15;6;14;9;0;0;15;6;False;True;133;113;245;15;6;8;9;0;0;15;6;False;True +stand_0;;0;0;0;1;133;113;245;15;6;-7;9;0;0;15;6;False;False +stand_3;;0;0;0;1;133;130;240;17;15;-2;8;11;0;6;15;False;False +stand_1;;0;0;0;1;133;141;240;6;15;2;-7;0;0;6;15;True;False +stand_2;;0;0;0;1;133;113;245;15;6;8;9;0;0;15;6;False;True diff --git a/bin/Data/Animations/Enemies/moblinPig.ani b/bin/Data/Animations/Enemies/moblinPig.ani new file mode 100644 index 0000000..4cc4a72 --- /dev/null +++ b/bin/Data/Animations/Enemies/moblinPig.ani @@ -0,0 +1,10 @@ +1 +enemies.png +walk_0;;-1;0;0;2;133;143;96;16;16;0;0;0;0;0;0;False;False;133;160;96;16;16;0;0;0;0;0;0;False;False +walk_1;;-1;0;0;2;133;194;96;16;16;0;0;0;0;0;0;False;False;133;194;96;16;16;0;0;0;0;0;0;False;True +walk_3;;-1;0;0;2;133;177;96;16;16;0;0;0;0;0;0;False;False;133;177;96;16;16;0;0;0;0;0;0;False;True +walk_2;;-1;0;0;2;133;143;96;16;16;0;0;0;0;0;0;False;True;133;160;96;16;16;0;0;0;0;0;0;False;True +stand_0;;0;0;0;1;83;160;96;16;16;0;0;0;0;0;0;False;False +stand_1;;0;0;0;1;83;194;96;16;16;0;0;0;0;0;0;False;False +stand_2;;0;0;0;1;83;160;96;16;16;0;0;0;0;0;0;False;True +stand_3;;0;0;0;1;83;177;96;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/monkey.ani b/bin/Data/Animations/Enemies/monkey.ani new file mode 100644 index 0000000..8fe25f1 --- /dev/null +++ b/bin/Data/Animations/Enemies/monkey.ani @@ -0,0 +1,6 @@ +1 +enemies.png +idle;;0;0;2;1;83;288;24;16;14;-8;-16;0;0;0;0;False;False +throwr;;0;0;-6;1;83;288;1;16;22;-8;-16;0;0;0;0;False;False +throwl;;0;0;-6;1;83;288;1;16;22;-8;-16;0;0;0;0;False;True +fall;;0;0;0;1;83;288;24;16;14;-8;-14;0;0;0;0;True;False diff --git a/bin/Data/Animations/Enemies/octorok shot.ani b/bin/Data/Animations/Enemies/octorok shot.ani new file mode 100644 index 0000000..3dfa034 --- /dev/null +++ b/bin/Data/Animations/Enemies/octorok shot.ani @@ -0,0 +1,3 @@ +1 +enemies.png +idle;;0;0;0;1;83;143;45;10;10;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/octorok.ani b/bin/Data/Animations/Enemies/octorok.ani new file mode 100644 index 0000000..eea239c --- /dev/null +++ b/bin/Data/Animations/Enemies/octorok.ani @@ -0,0 +1,10 @@ +1 +enemies.png +walk_0;;-1;0;0;2;200;2;43;15;16;0;0;0;0;0;0;False;False;200;19;44;15;15;0;0;0;0;0;0;False;False +walk_3;;-1;0;0;2;200;54;44;16;15;0;0;0;0;0;0;False;False;200;36;44;16;15;0;0;0;0;0;0;False;False +walk_1;;-1;0;0;2;200;72;44;16;15;0;0;0;0;0;0;False;False;200;90;44;16;15;0;0;0;0;0;0;False;False +walk_2;;-1;1;0;2;200;125;43;15;16;0;0;0;0;0;0;False;False;200;108;44;15;15;0;0;0;0;0;0;False;False +stand_0;;0;0;0;1;83;19;44;15;15;0;0;0;0;0;0;False;False +stand_3;;0;0;0;1;83;36;44;16;15;0;0;0;0;0;0;False;False +stand_1;;0;0;0;1;83;90;44;16;15;0;0;0;0;0;0;False;False +stand_2;;0;0;0;1;83;108;44;15;15;1;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/pairodd projectile.ani b/bin/Data/Animations/Enemies/pairodd projectile.ani new file mode 100644 index 0000000..128ee4f --- /dev/null +++ b/bin/Data/Animations/Enemies/pairodd projectile.ani @@ -0,0 +1,3 @@ +1 +enemies.png +idle;;-1;0;0;2;133;162;354;12;12;-6;-6;0;0;0;0;False;False;133;176;353;14;14;-7;-7;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/pairodd.ani b/bin/Data/Animations/Enemies/pairodd.ani new file mode 100644 index 0000000..d335f96 --- /dev/null +++ b/bin/Data/Animations/Enemies/pairodd.ani @@ -0,0 +1,5 @@ +1 +enemies.png +idle;;-1;0;0;2;267;160;336;16;16;0;0;0;0;0;0;False;False;267;160;336;16;16;0;0;0;0;0;0;False;True +despawn;;0;0;0;3;133;210;336;10;16;3;0;0;0;0;0;False;False;133;178;336;30;10;-7;3;0;0;0;0;False;False;133;185;348;16;5;0;6;0;0;0;0;False;False +spawn;;0;0;0;3;133;185;348;16;5;0;6;0;0;0;0;False;False;133;178;336;30;10;-7;3;0;0;0;0;False;False;133;210;336;10;16;3;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/peahat.ani b/bin/Data/Animations/Enemies/peahat.ani new file mode 100644 index 0000000..3b4223e --- /dev/null +++ b/bin/Data/Animations/Enemies/peahat.ani @@ -0,0 +1,3 @@ +1 +enemies.png +idle;;-1;0;0;2;67;372;144;14;16;1;0;0;0;0;0;False;False;67;387;144;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/pincer.ani b/bin/Data/Animations/Enemies/pincer.ani new file mode 100644 index 0000000..209be48 --- /dev/null +++ b/bin/Data/Animations/Enemies/pincer.ani @@ -0,0 +1,11 @@ +1 +enemies.png +0;;-1;0;0;1;200;152;135;16;15;0;0;0;0;0;0;False;False +1;;-1;0;0;1;200;170;134;16;16;0;0;0;0;0;0;True;False +2;;-1;0;0;1;200;152;116;16;16;0;0;0;0;0;0;False;False +3;;-1;0;0;1;200;170;134;16;16;0;0;0;0;0;0;True;True +eyes;;-1;0;0;1;200;170;123;12;9;2;4;0;0;0;0;False;False +4;;0;0;0;1;83;152;135;16;15;0;0;0;0;0;0;False;True +5;;0;0;0;1;83;170;134;16;16;0;0;0;0;0;0;False;True +6;;0;0;0;1;83;152;116;16;16;0;0;0;0;0;0;True;False +7;;0;0;0;1;83;170;134;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/piranha plant.ani b/bin/Data/Animations/Enemies/piranha plant.ani new file mode 100644 index 0000000..61f4f71 --- /dev/null +++ b/bin/Data/Animations/Enemies/piranha plant.ani @@ -0,0 +1,5 @@ +1 +enemies.png +spawn;idle;0;0;0;4;133;2;277;14;8;1;8;0;0;0;0;False;False;133;2;277;14;16;1;0;0;0;0;0;False;False;133;1;277;16;24;0;-8;0;0;0;0;False;False;133;1;277;16;32;0;-16;0;0;0;0;False;False +idle;despawn;3;0;0;2;267;1;277;16;32;0;-16;0;0;0;0;False;False;267;20;279;16;30;0;-14;0;0;0;0;False;False +despawn;;0;0;0;4;133;1;277;16;32;0;-16;0;0;0;0;False;False;133;1;277;16;24;0;-8;0;0;0;0;False;False;133;1;277;16;16;0;0;0;0;0;0;False;False;133;1;277;16;8;0;8;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/podoboo.ani b/bin/Data/Animations/Enemies/podoboo.ani new file mode 100644 index 0000000..ce2b5e0 --- /dev/null +++ b/bin/Data/Animations/Enemies/podoboo.ani @@ -0,0 +1,5 @@ +1 +enemies.png +idle;;0;0;0;1;83;352;376;16;16;-8;-8;0;0;0;0;False;False +particle;;0;0;0;2;267;354;394;12;12;-6;-6;0;0;0;0;False;False;133;356;408;8;8;-4;-4;0;0;0;0;False;False +splash;;0;0;0;1;83;356;408;8;8;-4;-4;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/pols voice.ani b/bin/Data/Animations/Enemies/pols voice.ani new file mode 100644 index 0000000..47b0011 --- /dev/null +++ b/bin/Data/Animations/Enemies/pols voice.ani @@ -0,0 +1,4 @@ +1 +enemies.png +jump;;0;0;0;1;83;336;0;16;16;0;0;0;0;0;0;False;False +stand;;0;0;0;1;83;353;5;16;11;0;5;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/raven.ani b/bin/Data/Animations/Enemies/raven.ani new file mode 100644 index 0000000..eeec5a4 --- /dev/null +++ b/bin/Data/Animations/Enemies/raven.ani @@ -0,0 +1,6 @@ +1 +enemies.png +idle_0;;0;0;0;1;83;113;64;16;16;0;0;0;0;0;0;False;False +idle_1;;0;0;0;1;83;113;64;16;16;0;0;0;0;0;0;False;True +fly_0;;-1;0;0;2;133;113;64;16;16;0;0;0;0;0;0;False;False;133;130;64;16;16;0;0;0;0;0;0;False;False +fly_1;;0;0;0;2;133;113;64;16;16;0;0;0;0;0;0;False;True;133;130;64;16;16;0;0;0;0;0;0;False;True diff --git a/bin/Data/Animations/Enemies/red zol.ani b/bin/Data/Animations/Enemies/red zol.ani new file mode 100644 index 0000000..7a4ddca --- /dev/null +++ b/bin/Data/Animations/Enemies/red zol.ani @@ -0,0 +1,4 @@ +1 +enemies.png +IDLE;;-1;0;0;1;200;66;133;12;11;0;5;0;0;0;0;False;False +WALK;;-1;0;0;1;200;81;128;8;16;2;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/river zora.ani b/bin/Data/Animations/Enemies/river zora.ani new file mode 100644 index 0000000..3a5f9ff --- /dev/null +++ b/bin/Data/Animations/Enemies/river zora.ani @@ -0,0 +1,5 @@ +1 +enemies.png +SPAWN;;-1;0;0;2;100;0;210;16;14;0;2;0;0;0;0;False;False;100;0;210;16;14;0;2;0;0;0;0;True;False +ATTACK;;-1;0;0;1;200;16;209;16;15;0;1;0;0;0;0;False;False +IDLE;;-1;0;0;1;200;32;208;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/rock.ani b/bin/Data/Animations/Enemies/rock.ani new file mode 100644 index 0000000..0320964 --- /dev/null +++ b/bin/Data/Animations/Enemies/rock.ani @@ -0,0 +1,3 @@ +1 +enemies.png +idle;;-1;-8;-8;4;133;176;416;16;16;0;0;0;0;0;0;False;False;133;176;416;16;16;0;0;0;0;0;0;False;True;133;176;416;16;16;0;0;0;0;0;0;True;True;133;176;416;16;16;0;0;0;0;0;0;True;False diff --git a/bin/Data/Animations/Enemies/rope.ani b/bin/Data/Animations/Enemies/rope.ani new file mode 100644 index 0000000..3ffca9e --- /dev/null +++ b/bin/Data/Animations/Enemies/rope.ani @@ -0,0 +1,4 @@ +1 +enemies.png +move_-1;;-1;0;0;2;133;400;102;16;16;-8;-16;0;0;0;0;False;False;133;401;120;15;16;-8;-16;0;0;0;0;False;False +move_1;;-1;0;0;2;133;400;102;16;16;-8;-16;0;0;0;0;False;True;133;401;120;15;16;-7;-16;0;0;0;0;False;True diff --git a/bin/Data/Animations/Enemies/sea urchin.ani b/bin/Data/Animations/Enemies/sea urchin.ani new file mode 100644 index 0000000..08a23d2 --- /dev/null +++ b/bin/Data/Animations/Enemies/sea urchin.ani @@ -0,0 +1,4 @@ +1 +enemies.png +IDLE;;-1;0;0;4;250;0;0;16;16;0;0;0;0;0;0;False;False;250;16;0;16;16;0;0;0;0;0;0;False;False;250;32;0;16;16;0;0;0;0;0;0;False;False;250;48;0;16;16;0;0;0;0;0;0;False;False +FALL;;0;0;0;3;200;81;1;10;10;0;0;0;0;0;0;False;False;200;92;1;6;6;2;2;0;0;0;0;False;False;200;99;1;4;4;3;3;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/shrouded stalfos.ani b/bin/Data/Animations/Enemies/shrouded stalfos.ani new file mode 100644 index 0000000..d58d962 --- /dev/null +++ b/bin/Data/Animations/Enemies/shrouded stalfos.ani @@ -0,0 +1,6 @@ +1 +enemies.png +walk_3;;-1;0;0;2;133;112;304;16;16;0;0;0;0;0;0;False;False;133;112;304;16;16;0;0;0;0;0;0;False;True +walk_1;;-1;0;0;2;133;129;304;16;16;0;0;0;0;0;0;False;False;133;129;304;16;16;0;0;0;0;0;0;False;True +walk_0;;-1;0;0;2;133;146;304;15;16;0;0;0;0;0;0;False;False;133;162;304;16;16;0;0;0;0;0;0;False;False +walk_2;;-1;0;0;2;133;146;304;15;16;1;0;0;0;0;0;False;True;133;162;304;16;16;0;0;0;0;0;0;False;True diff --git a/bin/Data/Animations/Enemies/spark.ani b/bin/Data/Animations/Enemies/spark.ani new file mode 100644 index 0000000..af5479f --- /dev/null +++ b/bin/Data/Animations/Enemies/spark.ani @@ -0,0 +1,3 @@ +1 +enemies.png +IDLE;;-1;0;0;2;50;48;144;16;16;0;0;0;0;0;0;False;False;50;64;144;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/spiked beetle.ani b/bin/Data/Animations/Enemies/spiked beetle.ani new file mode 100644 index 0000000..96bbd45 --- /dev/null +++ b/bin/Data/Animations/Enemies/spiked beetle.ani @@ -0,0 +1,4 @@ +1 +enemies.png +walk;;-1;0;0;2;133;208;32;16;16;0;0;0;0;0;0;False;False;133;226;33;16;15;0;1;0;0;0;0;False;False +back;;-1;0;0;2;200;244;33;16;15;0;0;0;0;0;0;False;False;200;262;33;16;15;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/spiked thwomp.ani b/bin/Data/Animations/Enemies/spiked thwomp.ani new file mode 100644 index 0000000..ab4eb26 --- /dev/null +++ b/bin/Data/Animations/Enemies/spiked thwomp.ani @@ -0,0 +1,10 @@ +1 +enemies.png +r1;;0;0;0;1;83;8;408;32;32;0;0;0;0;0;0;False;False +r2;;0;0;0;1;83;40;408;32;32;0;0;0;0;0;0;False;False +r3;;0;0;0;1;83;72;408;32;32;0;0;0;0;0;0;False;False +down;;0;0;0;1;83;104;408;32;32;0;0;0;0;0;0;False;False +l1;;0;0;0;1;83;8;408;32;32;0;0;0;0;0;0;False;True +l2;;0;0;0;1;83;40;408;32;32;0;0;0;0;0;0;False;True +l3;;0;0;0;1;83;72;408;32;32;0;0;0;0;0;0;False;True +attack;;0;0;0;1;83;136;408;32;32;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/spiny Beetle.ani b/bin/Data/Animations/Enemies/spiny Beetle.ani new file mode 100644 index 0000000..12bddac --- /dev/null +++ b/bin/Data/Animations/Enemies/spiny Beetle.ani @@ -0,0 +1,3 @@ +1 +enemies.png +idle;;-1;0;0;2;133;80;336;15;13;1;0;0;0;0;0;False;False;133;80;336;15;13;0;0;0;0;0;0;False;True diff --git a/bin/Data/Animations/Enemies/stalfos green.ani b/bin/Data/Animations/Enemies/stalfos green.ani new file mode 100644 index 0000000..5cbf299 --- /dev/null +++ b/bin/Data/Animations/Enemies/stalfos green.ani @@ -0,0 +1,4 @@ +1 +enemies.png +walk;;-1;0;0;2;133;265;55;15;16;0;0;0;0;0;0;False;False;133;265;55;15;16;0;0;0;0;0;0;False;True +jump;;-1;0;0;1;200;282;57;16;14;0;2;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/stalfos knight sword.ani b/bin/Data/Animations/Enemies/stalfos knight sword.ani new file mode 100644 index 0000000..2cedbcb --- /dev/null +++ b/bin/Data/Animations/Enemies/stalfos knight sword.ani @@ -0,0 +1,10 @@ +1 +enemies.png +walk_0;;-1;0;0;2;250;132;272;28;16;-12;0;0;9;15;6;False;False;250;107;273;23;15;-6;1;0;8;15;6;False;False +walk_3;;-1;0;0;2;250;188;272;18;29;-2;0;11;14;6;15;False;False;250;168;272;18;23;-2;0;11;9;6;14;False;False +walk_1;;-1;0;0;2;250;211;259;16;29;0;-13;2;0;6;14;False;False;250;229;265;16;23;0;-7;2;0;6;11;False;False +walk_2;;-1;0;0;2;250;249;272;28;16;0;0;13;9;15;6;False;False;250;279;273;23;15;-1;1;9;8;14;6;False;False +stand_0;;0;0;0;1;83;107;273;23;15;-7;1;0;8;15;6;False;False +stand_3;;0;0;0;1;83;168;272;18;23;-2;0;11;9;6;14;False;False +stand_1;;0;0;0;1;83;229;265;16;23;0;-7;2;0;6;16;False;False +stand_2;;0;0;0;1;83;279;273;23;15;0;1;8;8;15;6;False;False diff --git a/bin/Data/Animations/Enemies/stalfos knight.ani b/bin/Data/Animations/Enemies/stalfos knight.ani new file mode 100644 index 0000000..94feb20 --- /dev/null +++ b/bin/Data/Animations/Enemies/stalfos knight.ani @@ -0,0 +1,10 @@ +1 +enemies.png +walk_0;;-1;0;0;2;250;132;272;28;16;-12;0;0;0;0;0;False;False;250;107;273;23;15;-6;1;0;0;0;0;False;False +walk_3;;-1;0;0;2;250;188;272;18;16;-2;0;0;0;0;0;False;False;250;168;272;18;16;-2;0;0;0;0;0;False;False +walk_1;;-1;0;0;2;250;229;272;16;16;0;0;0;0;0;0;False;False;250;211;272;16;16;0;0;0;0;0;0;False;False +walk_2;;-1;0;0;2;250;249;272;28;16;0;0;0;0;0;0;False;False;250;279;272;23;16;-1;0;0;0;0;0;False;False +stand_0;;0;0;0;1;83;107;273;23;15;-7;1;0;0;0;0;False;False +stand_3;;0;0;0;1;83;170;272;16;16;0;0;0;0;0;0;False;False +stand_1;;0;0;0;1;83;229;272;16;16;0;0;0;0;0;0;False;False +stand_2;;0;0;0;1;83;279;273;16;15;0;1;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/stalfos orange.ani b/bin/Data/Animations/Enemies/stalfos orange.ani new file mode 100644 index 0000000..e162eaf --- /dev/null +++ b/bin/Data/Animations/Enemies/stalfos orange.ani @@ -0,0 +1,4 @@ +1 +enemies.png +walk;;-1;0;0;2;133;265;73;15;16;0;0;0;0;0;0;False;False;133;265;73;15;16;0;0;0;0;0;0;False;True +jump;;-1;0;0;1;200;282;75;16;14;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/star.ani b/bin/Data/Animations/Enemies/star.ani new file mode 100644 index 0000000..32c5cdf --- /dev/null +++ b/bin/Data/Animations/Enemies/star.ani @@ -0,0 +1,3 @@ +1 +enemies.png +idle;;-1;0;0;4;133;316;307;16;13;-8;-14;0;0;0;0;False;False;133;300;306;14;14;-7;-15;0;0;0;0;False;True;133;290;304;8;16;-4;-16;0;0;0;0;False;False;133;300;306;14;14;-7;-15;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/tektite.ani b/bin/Data/Animations/Enemies/tektite.ani new file mode 100644 index 0000000..602d715 --- /dev/null +++ b/bin/Data/Animations/Enemies/tektite.ani @@ -0,0 +1,4 @@ +1 +enemies.png +idle;;-1;0;0;2;267;112;341;16;11;0;5;0;0;0;0;False;False;267;129;336;16;16;0;0;0;0;0;0;False;False +jump;;0;0;0;1;83;129;336;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/thwimp.ani b/bin/Data/Animations/Enemies/thwimp.ani new file mode 100644 index 0000000..2baa400 --- /dev/null +++ b/bin/Data/Animations/Enemies/thwimp.ani @@ -0,0 +1,4 @@ +1 +enemies.png +idle;;0;0;0;1;83;176;24;16;16;0;0;0;0;0;0;False;False +angry;;0;0;0;1;83;159;24;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/vacuum.ani b/bin/Data/Animations/Enemies/vacuum.ani new file mode 100644 index 0000000..936a66e --- /dev/null +++ b/bin/Data/Animations/Enemies/vacuum.ani @@ -0,0 +1,4 @@ +1 +enemies.png +idle;;0;0;0;1;83;49;288;14;15;1;0;0;0;0;0;False;False +vacuum;;7;0;0;2;267;64;288;16;16;0;0;0;0;0;0;False;False;267;49;288;14;15;1;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/vire bat.ani b/bin/Data/Animations/Enemies/vire bat.ani new file mode 100644 index 0000000..331c28a --- /dev/null +++ b/bin/Data/Animations/Enemies/vire bat.ani @@ -0,0 +1,3 @@ +1 +enemies.png +idle;;-1;0;0;2;133;365;48;10;13;-5;-13;0;0;0;0;False;False;133;377;48;16;12;-8;-12;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/vire.ani b/bin/Data/Animations/Enemies/vire.ani new file mode 100644 index 0000000..9f9b0a0 --- /dev/null +++ b/bin/Data/Animations/Enemies/vire.ani @@ -0,0 +1,5 @@ +1 +enemies.png +fly;;-1;0;0;2;133;396;48;24;16;-12;-16;0;0;0;0;False;False;133;396;65;24;15;-12;-15;0;0;0;0;False;False +attack;;0;0;0;1;267;397;81;22;16;-11;-16;0;0;0;0;False;False +idle;;0;0;0;1;83;396;65;24;15;-12;-15;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/vireball.ani b/bin/Data/Animations/Enemies/vireball.ani new file mode 100644 index 0000000..02c506f --- /dev/null +++ b/bin/Data/Animations/Enemies/vireball.ani @@ -0,0 +1,3 @@ +1 +enemies.png +idle;;-1;0;0;2;67;92;28;10;10;-5;-5;0;0;0;0;False;False;67;92;28;10;10;-5;-5;0;0;0;0;False;True diff --git a/bin/Data/Animations/Enemies/water tektite.ani b/bin/Data/Animations/Enemies/water tektite.ani new file mode 100644 index 0000000..44ede9d --- /dev/null +++ b/bin/Data/Animations/Enemies/water tektite.ani @@ -0,0 +1,3 @@ +1 +enemies.png +idle;;-1;0;0;2;267;336;145;16;15;0;0;0;0;0;0;False;False;267;353;146;16;14;0;1;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/wizzrobe.ani b/bin/Data/Animations/Enemies/wizzrobe.ani new file mode 100644 index 0000000..3afc1d4 --- /dev/null +++ b/bin/Data/Animations/Enemies/wizzrobe.ani @@ -0,0 +1,7 @@ +1 +enemies.png +stand_1;;0;0;0;1;83;346;170;16;16;0;-16;0;0;0;0;False;False +stand_3;;0;0;0;1;83;364;170;16;16;0;-16;0;0;0;0;False;False +stand_0;;0;0;0;1;83;381;170;15;16;1;-16;0;0;0;0;False;False +stand_2;;0;0;0;1;83;381;170;15;16;0;-16;0;0;0;0;False;True +head;;0;0;0;1;83;374;189;14;10;1;-10;0;0;0;0;False;False diff --git a/bin/Data/Animations/Enemies/zombie.ani b/bin/Data/Animations/Enemies/zombie.ani new file mode 100644 index 0000000..c88487d --- /dev/null +++ b/bin/Data/Animations/Enemies/zombie.ani @@ -0,0 +1,5 @@ +1 +enemies.png +spawn;;0;0;0;2;250;80;170;16;6;0;8;0;0;0;0;False;False;250;96;165;15;11;0;5;0;0;0;0;False;False +walk;;-1;0;0;2;150;112;160;16;16;0;0;0;0;0;0;False;False;150;128;160;16;16;0;0;0;0;0;0;False;False +despawn;;0;0;0;2;250;96;165;15;11;0;5;0;0;0;0;False;False;250;80;170;16;6;0;10;0;0;0;0;False;False diff --git a/bin/Data/Animations/Intro/light.ani b/bin/Data/Animations/Intro/light.ani new file mode 100644 index 0000000..1ac1530 --- /dev/null +++ b/bin/Data/Animations/Intro/light.ani @@ -0,0 +1,3 @@ +1 +intro.png +idle;;0;0;0;6;133;75;94;4;4;-2;-2;0;0;0;0;False;False;133;81;92;8;8;-4;-4;0;0;0;0;False;False;133;91;91;11;11;-5;-5;0;0;0;0;False;False;133;81;92;8;8;-4;-4;0;0;0;0;False;False;133;75;94;4;4;-2;-2;0;0;0;0;False;False;133;75;94;0;0;-2;-2;0;0;0;0;False;False diff --git a/bin/Data/Animations/Intro/link.ani b/bin/Data/Animations/Intro/link.ani new file mode 100644 index 0000000..b5b1ee3 --- /dev/null +++ b/bin/Data/Animations/Intro/link.ani @@ -0,0 +1,4 @@ +1 +intro.png +pushed;;-1;0;0;1;250;23;97;14;16;2;0;0;0;0;0;False;False +idle;;-1;0;0;1;200;5;97;15;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Intro/link_boat.ani b/bin/Data/Animations/Intro/link_boat.ani new file mode 100644 index 0000000..e0ad241 --- /dev/null +++ b/bin/Data/Animations/Intro/link_boat.ani @@ -0,0 +1,3 @@ +1 +intro.png +run;;0;-64;-56;17;2167;1;209;128;112;0;0;0;0;0;0;False;False;33;130;209;128;112;0;0;0;0;0;0;False;False;33;259;209;128;112;0;0;0;0;0;0;False;False;33;130;209;128;112;0;0;0;0;0;0;False;False;33;388;209;128;112;0;0;0;0;0;0;False;False;33;130;209;128;112;0;0;0;0;0;0;False;False;33;259;209;128;112;0;0;0;0;0;0;False;False;33;130;209;128;112;0;0;0;0;0;0;False;False;33;388;209;128;112;0;0;0;0;0;0;False;False;33;130;209;128;112;0;0;0;0;0;0;False;False;33;259;209;128;112;0;0;0;0;0;0;False;False;33;130;209;128;112;0;0;0;0;0;0;False;False;33;388;209;128;112;0;0;0;0;0;0;False;False;33;130;209;128;112;0;0;0;0;0;0;False;False;33;259;209;128;112;0;0;0;0;0;0;False;False;33;130;209;128;112;0;0;0;0;0;0;False;False;33;388;209;128;112;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Intro/loading.ani b/bin/Data/Animations/Intro/loading.ani new file mode 100644 index 0000000..1df4364 --- /dev/null +++ b/bin/Data/Animations/Intro/loading.ani @@ -0,0 +1,3 @@ +1 +intro.png +idle;;-1;0;0;4;133;18;145;12;4;-12;-4;0;0;0;0;False;False;133;18;150;12;4;-12;-4;0;0;0;0;False;False;133;18;155;12;4;-12;-4;0;0;0;0;False;False;133;18;150;11;4;-11;-4;0;0;0;0;False;True diff --git a/bin/Data/Animations/Intro/maria.ani b/bin/Data/Animations/Intro/maria.ani new file mode 100644 index 0000000..5fe75b9 --- /dev/null +++ b/bin/Data/Animations/Intro/maria.ani @@ -0,0 +1,6 @@ +1 +intro.png +move;;-1;0;0;2;133;22;119;14;16;1;0;0;0;0;0;False;False;133;5;120;16;15;0;1;0;0;0;0;False;False +stand;;-1;0;0;1;200;22;119;14;16;1;0;0;0;0;0;False;False +hold;;0;0;0;1;83;38;119;14;16;0;0;0;0;0;0;False;False +push;;0;0;0;1;83;55;119;14;16;1;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Intro/thunder.ani b/bin/Data/Animations/Intro/thunder.ani new file mode 100644 index 0000000..b6acd9f --- /dev/null +++ b/bin/Data/Animations/Intro/thunder.ani @@ -0,0 +1,8 @@ +1 +intro.png +thunder0;null;0;0;0;1;533;150;97;23;36;-7;0;0;0;0;0;False;False +thunder1;null;0;0;0;1;533;150;97;23;36;0;0;0;0;0;0;False;True +thunder2;null;0;0;0;1;533;178;97;31;52;-7;0;0;0;0;0;False;False +thunder3;null;0;0;0;1;533;178;97;31;52;0;0;0;0;0;0;False;True +null;;0;0;0;1;83;0;0;0;0;0;0;0;0;0;0;False;False +thunderboat;;0;0;0;1;3000;229;96;8;64;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/MidBoss/armosKnight.ani b/bin/Data/Animations/MidBoss/armosKnight.ani new file mode 100644 index 0000000..e59bf38 --- /dev/null +++ b/bin/Data/Animations/MidBoss/armosKnight.ani @@ -0,0 +1,6 @@ +1 +midboss.png +idle;;-1;-16;0;1;267;7;48;32;32;0;0;0;0;0;0;False;False +red;;6;-16;0;2;67;42;48;32;32;0;0;0;0;0;0;False;False;67;7;48;32;32;0;0;0;0;0;0;False;False +angry;;0;-16;0;1;83;77;48;32;32;0;0;0;0;0;0;False;False +broken;;0;-16;0;1;83;112;50;32;30;0;2;0;0;0;0;False;False diff --git a/bin/Data/Animations/MidBoss/ball and chain soldier.ani b/bin/Data/Animations/MidBoss/ball and chain soldier.ani new file mode 100644 index 0000000..1e5727e --- /dev/null +++ b/bin/Data/Animations/MidBoss/ball and chain soldier.ani @@ -0,0 +1,4 @@ +1 +midboss.png +swing0;;0;0;0;1;267;193;192;15;16;1;0;0;0;0;0;False;False +swing1;;0;0;0;1;83;176;192;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/MidBoss/bigMoblin.ani b/bin/Data/Animations/MidBoss/bigMoblin.ani new file mode 100644 index 0000000..561f308 --- /dev/null +++ b/bin/Data/Animations/MidBoss/bigMoblin.ani @@ -0,0 +1,14 @@ +1 +midboss.png +idle_0;;0;-3;-8;2;267;9;12;21;24;0;0;0;0;0;0;False;False;267;57;11;24;25;-2;-1;0;0;0;0;False;False +idle_2;;0;-2;-8;2;267;9;12;21;24;0;0;0;0;0;0;False;True;267;57;11;24;25;-1;-1;0;0;0;0;False;True +attack_0;;-1;-5;0;2;67;83;21;23;15;0;1;0;0;0;0;False;False;67;108;20;24;16;0;0;0;0;0;0;False;False +attack_2;;-1;-2;0;2;83;83;21;23;15;0;1;0;0;0;0;False;True;83;108;20;24;16;-1;0;0;0;0;0;False;True +wall;;-1;-4;0;2;133;134;20;24;16;0;0;0;0;0;0;False;False;133;160;20;24;16;0;0;0;0;0;0;False;False +throw_0;;0;-5;-9;1;200;32;11;23;25;0;0;0;0;0;0;False;False +throw_2;;0;-2;-9;1;200;32;11;23;25;0;0;0;0;0;0;False;True +arm_0;;3;0;-9;2;133;32;11;23;25;-5;0;0;0;0;0;False;False;133;186;39;22;25;-3;0;0;0;0;0;False;False +arm_2;;3;0;-9;2;133;32;11;23;25;-2;0;0;0;0;0;False;True;133;186;39;22;25;-3;0;0;0;0;0;False;True +look_0;;2;0;0;2;267;9;12;21;24;-3;-8;0;0;0;0;False;False;267;158;40;21;24;-3;-8;0;0;0;0;False;False +look_2;;0;0;0;2;267;9;12;21;24;-2;-8;0;0;0;0;False;True;267;158;40;21;24;-2;-8;0;0;0;0;False;True +wait;;0;-3;-8;1;83;9;12;21;24;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/MidBoss/blaino.ani b/bin/Data/Animations/MidBoss/blaino.ani new file mode 100644 index 0000000..fcafb7c --- /dev/null +++ b/bin/Data/Animations/MidBoss/blaino.ani @@ -0,0 +1,9 @@ +1 +midboss.png +jump;;-1;0;0;2;267;250;16;22;16;-15;-16;0;4;11;11;False;False;267;282;16;23;16;-15;-16;0;5;11;11;False;False +box;;0;0;0;3;33;282;36;23;16;-15;-16;0;2;11;11;False;False;217;242;36;31;16;-23;-16;0;2;11;11;False;False;33;282;36;23;16;-15;-16;0;2;11;11;False;False +box_short;;0;0;0;3;33;282;36;23;16;-15;-16;0;2;11;11;False;False;83;242;36;31;16;-23;-16;0;2;11;11;False;False;33;282;36;23;16;-15;-16;0;2;11;11;False;False +hit0;;0;0;0;1;50;317;18;19;16;-11;-16;0;0;0;0;False;False +hit1;;0;0;0;1;83;284;56;20;16;-11;-16;0;0;0;0;False;False +hit2;;0;0;0;1;83;257;56;16;16;-8;-16;0;0;0;0;False;False +prebox;box;0;0;0;1;67;250;16;22;16;-15;-16;0;0;0;0;False;False diff --git a/bin/Data/Animations/MidBoss/cue ball.ani b/bin/Data/Animations/MidBoss/cue ball.ani new file mode 100644 index 0000000..dc516c8 --- /dev/null +++ b/bin/Data/Animations/MidBoss/cue ball.ani @@ -0,0 +1,6 @@ +1 +midboss.png +move_0;;-1;0;0;2;133;257;112;30;32;0;0;0;0;0;0;False;False;133;290;112;28;32;0;0;0;0;0;0;False;False +move_1;;-1;0;0;2;133;256;146;32;30;0;0;0;0;0;0;True;False;133;290;148;32;28;0;0;0;0;0;0;True;False +move_2;;-1;2;0;2;133;257;112;30;32;0;0;0;0;0;0;False;True;133;290;112;28;32;2;0;0;0;0;0;False;True +move_3;;-1;0;2;2;133;256;146;32;30;0;0;0;0;0;0;False;False;133;290;148;32;28;0;2;0;0;0;0;False;False diff --git a/bin/Data/Animations/MidBoss/desertLanmola.ani b/bin/Data/Animations/MidBoss/desertLanmola.ani new file mode 100644 index 0000000..2719c76 --- /dev/null +++ b/bin/Data/Animations/MidBoss/desertLanmola.ani @@ -0,0 +1,11 @@ +1 +midboss.png +head_3;;0;0;0;1;83;254;272;16;16;-8;-16;0;0;0;0;False;False +head_0;;0;0;0;1;83;272;272;16;16;-8;-16;0;0;0;0;False;False +head_2;;0;0;0;1;83;272;272;16;16;-8;-16;0;0;0;0;False;True +body;;0;0;0;1;83;290;273;14;14;-7;-14;0;0;0;0;False;False +tail;;-1;-8;-16;2;133;306;272;16;16;0;0;0;0;0;0;False;False;133;306;272;16;16;0;0;0;0;0;0;False;True +head_1;;0;0;0;1;83;254;272;16;16;-8;-16;0;0;0;0;True;False +sand_up;;0;0;0;1;83;343;273;8;15;-4;-15;0;0;0;0;False;False +sand_down;;0;0;0;1;83;353;276;8;11;-4;-11;0;0;0;0;False;False +ground;;-1;-8;-12;2;217;325;274;16;12;0;0;0;0;0;0;False;False;217;325;274;16;12;0;0;0;0;0;0;False;True diff --git a/bin/Data/Animations/MidBoss/giant buzz blob.ani b/bin/Data/Animations/MidBoss/giant buzz blob.ani new file mode 100644 index 0000000..d1a4d81 --- /dev/null +++ b/bin/Data/Animations/MidBoss/giant buzz blob.ani @@ -0,0 +1,9 @@ +1 +midboss.png +walk;;-1;0;0;4;233;68;257;24;31;-12;-31;0;0;0;0;False;False;233;94;260;22;28;-11;-28;0;0;0;0;False;False;233;68;257;24;31;-12;-31;0;0;0;0;False;False;233;94;260;22;28;-11;-28;0;0;0;0;False;True +slime;;0;0;0;5;67;36;266;16;22;-8;-22;0;0;0;0;False;False;67;10;272;24;16;-12;-16;0;0;0;0;False;False;67;36;266;16;22;-8;-22;0;0;0;0;False;False;67;54;256;12;32;-6;-32;0;0;0;0;False;False;67;36;266;16;22;-8;-22;0;0;0;0;False;False +jump;;0;0;0;1;133;36;266;16;22;-8;-22;0;0;0;0;False;False +fly;;0;0;0;1;83;54;256;12;32;-6;-32;0;0;0;0;False;False +land;;0;0;0;1;100;36;266;16;22;-8;-22;0;0;0;0;False;False +floor;;0;0;0;1;83;10;272;24;16;-12;-16;0;0;0;0;False;False +deslime;;0;0;0;10;633;10;272;24;16;-12;-16;0;0;0;0;False;False;67;36;266;16;22;-8;-22;0;0;0;0;False;False;67;54;256;12;32;-6;-32;0;0;0;0;False;False;67;36;266;16;22;-8;-22;0;0;0;0;False;False;67;10;272;24;16;-12;-16;0;0;0;0;False;False;67;36;266;16;22;-8;-22;0;0;0;0;False;False;67;54;256;12;32;-6;-32;0;0;0;0;False;False;83;36;266;16;22;-8;-22;0;0;0;0;False;False;83;10;272;24;16;-12;-16;0;0;0;0;False;False;67;36;266;16;22;-8;-22;0;0;0;0;False;False diff --git a/bin/Data/Animations/MidBoss/gohma.ani b/bin/Data/Animations/MidBoss/gohma.ani new file mode 100644 index 0000000..4442daf --- /dev/null +++ b/bin/Data/Animations/MidBoss/gohma.ani @@ -0,0 +1,5 @@ +1 +midboss.png +walk;;-1;0;0;3;267;12;144;48;16;-24;0;0;0;0;0;False;False;267;65;145;40;15;-20;1;0;0;0;0;False;False;267;12;144;48;16;-24;0;0;0;0;0;False;True +stand;;0;0;0;1;83;65;145;40;15;-20;1;0;0;0;0;False;False +eye;;0;0;0;1;83;112;144;40;16;-20;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/MidBoss/grim creeper fly.ani b/bin/Data/Animations/MidBoss/grim creeper fly.ani new file mode 100644 index 0000000..bd17c93 --- /dev/null +++ b/bin/Data/Animations/MidBoss/grim creeper fly.ani @@ -0,0 +1,3 @@ +1 +midboss.png +idle;;-1;0;0;2;133;172;256;16;14;-8;-14;0;0;0;0;False;False;133;172;256;16;14;-8;-16;0;0;0;0;True;False diff --git a/bin/Data/Animations/MidBoss/grim creeper.ani b/bin/Data/Animations/MidBoss/grim creeper.ani new file mode 100644 index 0000000..37ff844 --- /dev/null +++ b/bin/Data/Animations/MidBoss/grim creeper.ani @@ -0,0 +1,6 @@ +1 +midboss.png +play;;-1;0;0;2;533;146;256;24;16;-15;-16;0;0;0;0;False;False;533;146;274;24;16;-15;-16;0;0;0;0;False;False +idle;;0;0;0;1;83;146;274;24;16;-15;-16;0;0;0;0;False;False +attack;;0;0;0;1;83;128;256;16;28;-7;-16;0;0;0;0;False;False +stand;;0;0;0;1;83;172;274;16;16;-8;-16;0;0;0;0;False;False diff --git a/bin/Data/Animations/MidBoss/hinox.ani b/bin/Data/Animations/MidBoss/hinox.ani new file mode 100644 index 0000000..e8eaabc --- /dev/null +++ b/bin/Data/Animations/MidBoss/hinox.ani @@ -0,0 +1,7 @@ +1 +midboss.png +idle_0;;-1;-16;-32;2;267;120;220;32;32;0;0;0;0;0;0;False;False;267;120;220;32;32;0;0;0;0;0;0;False;True +idle_1;;-1;-16;-32;2;267;154;220;32;32;0;0;0;0;0;0;False;False;267;154;220;32;32;0;0;0;0;0;0;False;True +idle_2;;-1;-16;-32;2;267;188;220;32;32;0;0;0;0;0;0;False;False;267;188;220;32;32;0;0;0;0;0;0;False;True +throw_1;;0;0;0;2;267;120;220;32;32;-16;-32;0;0;0;0;False;False;400;120;220;32;32;-16;-32;0;0;0;0;False;True +throw_0;;0;0;0;2;267;120;220;32;32;-16;-32;0;0;0;0;False;True;400;120;220;32;32;-16;-32;0;0;0;0;False;False diff --git a/bin/Data/Animations/MidBoss/mbossOne.ani b/bin/Data/Animations/MidBoss/mbossOne.ani new file mode 100644 index 0000000..366c70f --- /dev/null +++ b/bin/Data/Animations/MidBoss/mbossOne.ani @@ -0,0 +1,4 @@ +1 +midboss.png +idle;;-1;0;0;1;200;127;177;16;16;0;0;0;0;0;0;False;False +move;;-1;0;0;2;133;127;177;16;16;0;0;0;0;0;0;False;False;133;145;177;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/MidBoss/mbossOneBoss.ani b/bin/Data/Animations/MidBoss/mbossOneBoss.ani new file mode 100644 index 0000000..ff36daf --- /dev/null +++ b/bin/Data/Animations/MidBoss/mbossOneBoss.ani @@ -0,0 +1,8 @@ +1 +midboss.png +PUSH_0;;0;0;0;1;316;21;181;23;24;-3;0;0;0;0;0;False;False +JUMP_0;;-1;0;0;1;200;51;181;20;24;0;0;0;0;0;0;False;False +PUSH_1;;0;0;0;1;316;21;181;23;24;0;0;0;0;0;0;False;True +JUMP_1;;-1;0;0;1;200;51;181;20;24;0;0;0;0;0;0;False;True +IDLE_0;;-1;0;0;1;200;77;181;20;24;0;0;0;0;0;0;False;False +IDLE_1;;-1;0;0;1;200;77;181;20;24;0;0;0;0;0;0;False;True diff --git a/bin/Data/Animations/MidBoss/smasher.ani b/bin/Data/Animations/MidBoss/smasher.ani new file mode 100644 index 0000000..efa2c58 --- /dev/null +++ b/bin/Data/Animations/MidBoss/smasher.ani @@ -0,0 +1,6 @@ +1 +midboss.png +up_0;;0;0;0;1;83;14;218;22;22;-10;-22;0;0;0;0;False;False +up_1;;0;0;0;1;83;14;218;22;22;-12;-22;0;0;0;0;False;True +idle_0;;0;0;0;1;83;45;218;23;22;-12;-22;0;0;0;0;False;False +idle_1;;0;0;0;1;83;45;218;23;22;-11;-22;0;0;0;0;False;True diff --git a/bin/Data/Animations/MidBoss/stone hinox.ani b/bin/Data/Animations/MidBoss/stone hinox.ani new file mode 100644 index 0000000..954eaf9 --- /dev/null +++ b/bin/Data/Animations/MidBoss/stone hinox.ani @@ -0,0 +1,5 @@ +1 +midboss.png +fast;;-1;0;0;2;117;128;96;32;32;-16;-32;0;0;0;0;False;False;117;128;96;32;32;-16;-32;0;0;0;0;False;True +attack;;0;0;0;1;83;162;97;32;31;-16;-31;0;0;0;0;False;False +idle;;-1;0;0;2;533;128;96;32;32;-16;-32;0;0;0;0;False;False;533;128;96;32;32;-16;-32;0;0;0;0;False;True diff --git a/bin/Data/Animations/MidBoss/turtle rock.ani b/bin/Data/Animations/MidBoss/turtle rock.ani new file mode 100644 index 0000000..056d045 --- /dev/null +++ b/bin/Data/Animations/MidBoss/turtle rock.ani @@ -0,0 +1,7 @@ +1 +midboss.png +stone;;0;0;0;1;83;256;187;28;32;-14;0;0;0;0;0;False;False +closed;;0;0;0;1;83;286;187;28;32;-14;0;0;0;0;0;False;False +opened;;0;0;0;1;83;316;187;28;32;-14;0;0;0;0;0;False;False +open;opened;0;0;0;3;533;316;187;28;32;-14;0;0;0;0;0;False;False;533;286;187;28;32;-14;0;0;0;0;0;False;False;533;316;187;28;32;-14;0;0;0;0;0;False;False +damaged;opened;0;0;0;1;400;286;187;28;32;-14;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/BowWow.ani b/bin/Data/Animations/NPCs/BowWow.ani new file mode 100644 index 0000000..21d90e8 --- /dev/null +++ b/bin/Data/Animations/NPCs/BowWow.ani @@ -0,0 +1,6 @@ +1 +npcs.png +walk_0;;-1;0;0;2;200;318;86;16;16;0;0;0;0;0;0;False;False;200;335;86;16;16;0;0;0;0;0;0;False;False +walk_3;;-1;0;0;2;200;353;86;16;16;0;0;0;0;0;0;False;False;200;371;86;16;16;0;0;0;0;0;0;False;False +walk_1;;-1;0;0;1;200;389;86;16;16;0;0;0;0;0;0;False;False +walk_2;;-1;0;0;2;200;407;86;16;16;0;0;0;0;0;0;False;False;200;424;86;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/alligator.ani b/bin/Data/Animations/NPCs/alligator.ani new file mode 100644 index 0000000..51947f7 --- /dev/null +++ b/bin/Data/Animations/NPCs/alligator.ani @@ -0,0 +1,5 @@ +1 +npcs.png +idle;;-1;0;0;2;267;4;50;23;23;0;0;0;0;0;0;False;False;267;29;50;28;23;0;0;0;0;0;0;False;False +eat;;-1;0;0;4;133;58;49;27;24;1;-1;0;0;0;0;False;False;250;29;50;28;23;0;0;0;0;0;0;False;False;133;4;50;23;23;0;0;0;0;0;0;False;False;133;29;50;28;23;0;0;0;0;0;0;False;False +open;;0;0;-1;1;83;87;49;26;24;2;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/animal 02.ani b/bin/Data/Animations/NPCs/animal 02.ani new file mode 100644 index 0000000..573cddb --- /dev/null +++ b/bin/Data/Animations/NPCs/animal 02.ani @@ -0,0 +1,3 @@ +1 +npcs.png +dance;;-1;0;0;2;567;365;32;15;16;-7;-16;0;0;0;0;False;False;567;382;32;16;16;-8;-16;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/animal 03.ani b/bin/Data/Animations/NPCs/animal 03.ani new file mode 100644 index 0000000..66aba76 --- /dev/null +++ b/bin/Data/Animations/NPCs/animal 03.ani @@ -0,0 +1,3 @@ +1 +npcs.png +dance;;-1;0;0;2;567;400;34;14;14;-7;-14;0;0;0;0;False;False;567;418;35;15;13;-7;-13;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/animal_rabbit.ani b/bin/Data/Animations/NPCs/animal_rabbit.ani new file mode 100644 index 0000000..5fcf872 --- /dev/null +++ b/bin/Data/Animations/NPCs/animal_rabbit.ani @@ -0,0 +1,10 @@ +1 +npcs.png +stand_0;;-1;0;0;2;267;304;32;14;16;-7;-16;0;0;0;0;False;True;267;320;32;13;16;-7;-16;0;0;0;0;False;True +stand_3;;-1;0;0;2;267;335;32;11;16;-6;-16;0;0;0;0;False;False;267;335;32;11;16;-5;-16;0;0;0;0;False;True +stand_1;;-1;1;0;2;267;348;32;11;16;-7;-16;0;0;0;0;False;False;267;348;32;11;16;-6;-16;0;0;0;0;False;True +stand_2;;-1;1;0;2;267;304;32;14;16;-8;-16;0;0;0;0;False;False;267;320;32;13;16;-7;-16;0;0;0;0;False;False +dance_3;;-1;0;0;2;567;335;32;11;16;-6;-16;0;0;0;0;False;False;567;335;32;11;16;-5;-16;0;0;0;0;False;True +dance_1;;-1;0;0;2;567;348;32;11;16;-5;-16;0;0;0;0;False;True;567;348;32;11;16;-6;-16;0;0;0;0;False;False +walk_2;;-1;0;0;2;133;304;32;14;16;-8;-16;0;0;0;0;False;False;133;320;32;13;16;-7;-16;0;0;0;0;False;False +walk_0;;-1;0;0;2;133;304;32;14;16;-7;-16;0;0;0;0;False;True;133;320;32;13;16;-7;-16;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/bat.ani b/bin/Data/Animations/NPCs/bat.ani new file mode 100644 index 0000000..2a7f417 --- /dev/null +++ b/bin/Data/Animations/NPCs/bat.ani @@ -0,0 +1,5 @@ +1 +npcs.png +spawn;;-1;-6;-6;2;133;581;34;12;8;0;0;0;0;0;0;False;False;133;581;34;12;8;0;2;0;0;0;0;True;False +bat;;-1;-8;-8;2;133;535;31;18;16;-1;0;0;0;0;0;False;False;133;554;31;24;16;-4;0;0;0;0;0;False;False +attack;;0;0;0;1;83;554;31;24;16;-12;-8;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/bee target.ani b/bin/Data/Animations/NPCs/bee target.ani new file mode 100644 index 0000000..c2bd048 --- /dev/null +++ b/bin/Data/Animations/NPCs/bee target.ani @@ -0,0 +1,3 @@ +1 +npcs.png +idle;;-1;0;0;1;67;294;174;1;1;-4;-8;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/bee.ani b/bin/Data/Animations/NPCs/bee.ani new file mode 100644 index 0000000..854dcb0 --- /dev/null +++ b/bin/Data/Animations/NPCs/bee.ani @@ -0,0 +1,3 @@ +1 +npcs.png +idle;;-1;0;0;2;67;161;205;7;5;-3;-5;0;0;0;0;False;False;67;161;205;7;5;-3;-2;0;0;0;0;True;False diff --git a/bin/Data/Animations/NPCs/bird.ani b/bin/Data/Animations/NPCs/bird.ani new file mode 100644 index 0000000..5a21661 --- /dev/null +++ b/bin/Data/Animations/NPCs/bird.ani @@ -0,0 +1,6 @@ +1 +npcs.png +IDLE_0;;-1;0;0;1;200;559;4;15;14;0;1;0;0;0;0;False;True +IDLE_1;;-1;0;0;1;200;559;4;15;14;0;1;0;0;0;0;False;False +WALK_0;;-1;0;0;2;133;559;4;15;14;0;1;0;0;0;0;False;True;133;542;3;15;15;0;0;0;0;0;0;False;True +WALK_1;;-1;0;0;2;133;559;4;15;14;0;1;0;0;0;0;False;False;133;542;3;15;15;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/bowWowSmall.ani b/bin/Data/Animations/NPCs/bowWowSmall.ani new file mode 100644 index 0000000..beb04e2 --- /dev/null +++ b/bin/Data/Animations/NPCs/bowWowSmall.ani @@ -0,0 +1,6 @@ +1 +npcs.png +walk_0;;-1;-5;-10;2;200;474;91;10;10;0;0;0;0;0;0;False;True;200;486;91;10;10;0;0;0;0;0;0;False;True +walk_1;;-1;-5;-10;2;200;474;91;10;10;0;0;0;0;0;0;False;False;200;486;91;10;10;0;0;0;0;0;0;False;False +walk_r_0;;-1;-5;-15;2;200;442;86;14;15;0;0;0;0;0;0;False;True;200;458;87;14;14;0;1;0;0;0;0;False;True +walk_r_1;;-1;-9;-15;2;200;442;86;14;15;0;0;0;0;0;0;False;False;200;458;87;14;14;0;1;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/broom.ani b/bin/Data/Animations/NPCs/broom.ani new file mode 100644 index 0000000..1c477aa --- /dev/null +++ b/bin/Data/Animations/NPCs/broom.ani @@ -0,0 +1,3 @@ +1 +items.png +show;;0;0;0;1;83;133;1;12;15;-10;-30;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/butterfly.ani b/bin/Data/Animations/NPCs/butterfly.ani new file mode 100644 index 0000000..b1f09d8 --- /dev/null +++ b/bin/Data/Animations/NPCs/butterfly.ani @@ -0,0 +1,3 @@ +1 +enemies.png +idle;;-1;0;0;2;117;0;24;8;6;-4;-4;0;0;0;0;False;False;117;8;26;8;6;-4;-3;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/cock.ani b/bin/Data/Animations/NPCs/cock.ani new file mode 100644 index 0000000..9dcc06a --- /dev/null +++ b/bin/Data/Animations/NPCs/cock.ani @@ -0,0 +1,8 @@ +1 +npcs.png +skeleton;;0;0;0;1;83;304;176;16;16;-8;-16;0;0;0;0;False;False +spawn;;0;0;0;1;83;322;171;16;21;-10;-21;0;0;0;0;False;False +stand_0;;-1;0;0;2;133;342;176;16;16;-8;-16;0;0;0;0;False;False;133;360;177;16;15;-8;-15;0;0;0;0;False;False +stand_1;;-1;0;0;2;133;414;176;16;16;-8;-16;0;0;0;0;False;False;133;432;178;16;14;-8;-14;0;0;0;0;False;False +stand_2;;-1;0;0;2;133;342;176;16;16;-8;-16;0;0;0;0;False;True;133;360;177;16;15;-8;-15;0;0;0;0;False;True +stand_3;;-1;0;0;2;133;396;176;16;16;-8;-16;0;0;0;0;False;False;133;378;177;16;15;-8;-15;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/dance fish.ani b/bin/Data/Animations/NPCs/dance fish.ani new file mode 100644 index 0000000..2189d2d --- /dev/null +++ b/bin/Data/Animations/NPCs/dance fish.ani @@ -0,0 +1,7 @@ +1 +npcs.png +idle;;-1;0;0;2;350;99;137;21;11;-10;-11;0;0;0;0;False;False;350;124;137;20;12;-10;-11;0;0;0;0;False;False +left;;-1;0;0;2;333;29;135;16;16;-10;-13;0;0;0;0;False;False;333;47;135;15;16;-9;-13;0;0;0;0;False;False +forward;;0;0;0;1;83;66;135;10;16;-5;-13;0;0;0;0;False;False +right;;-1;0;0;2;333;47;135;14;16;-5;-13;0;0;0;0;False;True;333;29;135;16;16;-6;-13;0;0;0;0;False;True +splash;;0;0;0;1;83;80;135;16;16;-6;-13;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/dog.ani b/bin/Data/Animations/NPCs/dog.ani new file mode 100644 index 0000000..9a1694c --- /dev/null +++ b/bin/Data/Animations/NPCs/dog.ani @@ -0,0 +1,4 @@ +1 +npcs.png +idle_0;;-1;0;0;2;100;507;3;16;15;-8;-15;0;0;0;0;False;False;100;525;3;16;15;-8;-15;0;0;0;0;False;False +idle_1;;-1;0;0;2;100;507;3;16;15;-8;-15;0;0;0;0;False;True;100;525;3;16;15;-8;-15;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/fairy.ani b/bin/Data/Animations/NPCs/fairy.ani new file mode 100644 index 0000000..2759bfa --- /dev/null +++ b/bin/Data/Animations/NPCs/fairy.ani @@ -0,0 +1,3 @@ +1 +npcs.png +idle;;-1;0;0;2;133;103;268;21;25;1;0;0;0;0;0;False;False;133;127;268;22;25;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/fish_big.ani b/bin/Data/Animations/NPCs/fish_big.ani new file mode 100644 index 0000000..c6941b9 --- /dev/null +++ b/bin/Data/Animations/NPCs/fish_big.ani @@ -0,0 +1,4 @@ +1 +npcs.png +swim;;-1;0;0;2;133;528;141;16;16;-8;0;0;0;0;0;False;False;133;528;158;16;16;-8;0;0;0;0;0;False;False +bite;;-1;0;0;2;133;546;141;16;16;-8;0;0;0;0;0;False;False;133;546;158;16;16;-8;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/fish_small.ani b/bin/Data/Animations/NPCs/fish_small.ani new file mode 100644 index 0000000..4939894 --- /dev/null +++ b/bin/Data/Animations/NPCs/fish_small.ani @@ -0,0 +1,4 @@ +1 +npcs.png +swim;;-1;0;0;2;133;486;142;16;11;-8;0;0;0;0;0;False;False;133;486;155;16;11;-8;0;0;0;0;0;False;False +bite;;-1;0;0;2;133;504;142;16;11;-8;0;0;0;0;0;False;False;133;504;155;16;11;-8;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/frog.ani b/bin/Data/Animations/NPCs/frog.ani new file mode 100644 index 0000000..52e6934 --- /dev/null +++ b/bin/Data/Animations/NPCs/frog.ani @@ -0,0 +1,10 @@ +1 +npcs.png +sit_0;;0;0;0;1;83;57;28;13;12;1;0;0;0;0;0;False;False +sit_2;;0;0;0;1;83;57;28;13;12;0;0;0;0;0;0;False;True +sit_3;;0;0;0;1;83;84;28;14;12;0;0;0;0;0;0;False;False +sit_1;;0;0;0;1;83;112;28;14;12;0;0;0;0;0;0;False;False +jump_0;;0;0;0;1;83;39;24;16;16;-2;-4;0;0;0;0;False;False +jump_2;;0;0;0;1;83;39;24;16;16;-2;-4;0;0;0;0;False;True +jump_1;;0;0;0;1;83;100;24;10;16;2;-4;0;0;0;0;False;False +jump_3;;0;0;0;1;83;72;24;10;16;2;-4;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/ghost.ani b/bin/Data/Animations/NPCs/ghost.ani new file mode 100644 index 0000000..4e50b07 --- /dev/null +++ b/bin/Data/Animations/NPCs/ghost.ani @@ -0,0 +1,6 @@ +1 +npcs.png +left;;-1;0;0;2;267;448;32;16;16;-8;-16;0;0;0;0;False;False;267;466;32;16;16;-8;-16;0;0;0;0;False;False +up_left;;-1;0;0;2;267;484;32;16;16;-8;-16;0;0;0;0;False;False;267;502;32;16;16;-8;-16;0;0;0;0;False;False +up_right;;-1;0;0;2;267;484;32;16;16;-8;-16;0;0;0;0;False;True;267;502;32;16;16;-8;-16;0;0;0;0;False;True +right;;-1;0;0;2;267;448;32;16;16;-8;-16;0;0;0;0;False;True;267;466;32;16;16;-8;-16;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/letterBird.ani b/bin/Data/Animations/NPCs/letterBird.ani new file mode 100644 index 0000000..2c3a0f9 --- /dev/null +++ b/bin/Data/Animations/NPCs/letterBird.ani @@ -0,0 +1,6 @@ +1 +npcs.png +idle_1;;-1;0;0;2;133;57;225;15;15;0;1;0;0;0;0;False;False;133;74;226;16;14;0;2;0;0;0;0;False;False +idle_0;;-1;0;0;2;133;57;225;15;15;1;0;0;0;0;0;False;True;133;74;226;16;14;0;1;0;0;0;0;False;True +fly_1;;-1;0;0;2;67;57;225;15;15;0;1;0;0;0;0;False;False;67;92;224;16;16;0;0;0;0;0;0;False;False +fly_0;;-1;0;0;2;67;57;225;15;15;1;1;0;0;0;0;False;True;67;92;224;16;16;0;0;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/letterBirdGreen.ani b/bin/Data/Animations/NPCs/letterBirdGreen.ani new file mode 100644 index 0000000..c7b85df --- /dev/null +++ b/bin/Data/Animations/NPCs/letterBirdGreen.ani @@ -0,0 +1,6 @@ +1 +npcs.png +idle_1;;-1;0;0;2;133;57;243;15;15;0;1;0;0;0;0;False;False;133;74;244;16;14;0;2;0;0;0;0;False;False +idle_0;;-1;0;0;2;133;57;243;15;15;1;0;0;0;0;0;False;True;133;74;244;16;14;0;1;0;0;0;0;False;True +fly_1;;-1;0;0;2;67;57;243;15;15;0;1;0;0;0;0;False;False;67;92;242;16;16;0;0;0;0;0;0;False;False +fly_0;;-1;0;0;2;67;57;243;15;15;1;1;0;0;0;0;False;True;67;92;242;16;16;0;0;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/mamu.ani b/bin/Data/Animations/NPCs/mamu.ani new file mode 100644 index 0000000..04768b2 --- /dev/null +++ b/bin/Data/Animations/NPCs/mamu.ani @@ -0,0 +1,7 @@ +1 +npcs.png +idle;;-1;0;0;2;267;343;204;31;32;-15;-32;0;0;0;0;False;False;267;310;204;31;32;-15;-32;0;0;0;0;False;False +left;;0;0;0;1;83;376;204;31;32;-15;-32;0;0;0;0;False;False +right;;0;0;0;1;83;376;204;31;32;-15;-32;0;0;0;0;False;True +idleleft;;0;0;0;1;83;310;204;31;32;-15;-32;0;0;0;0;False;False +idleright;;0;0;0;1;83;310;204;31;32;-15;-32;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/manbo.ani b/bin/Data/Animations/NPCs/manbo.ani new file mode 100644 index 0000000..243cad5 --- /dev/null +++ b/bin/Data/Animations/NPCs/manbo.ani @@ -0,0 +1,11 @@ +1 +npcs.png +fish;;-1;0;0;2;350;40;79;32;48;0;0;0;0;0;0;False;False;350;6;79;32;48;0;0;0;0;0;0;False;False +mouth_open;;0;0;0;1;83;76;86;22;16;0;0;0;0;0;0;False;False +mouth_closed;;0;0;0;1;83;76;103;22;16;0;0;0;0;0;0;False;False +eye;;0;0;0;1;83;101;88;14;14;0;0;0;0;0;0;False;False +eye_roll;;0;0;0;4;333;101;104;14;14;0;0;0;0;0;0;False;False;333;117;88;14;14;0;0;0;0;0;0;False;False;333;117;104;14;14;0;0;0;0;0;0;False;False;333;133;88;14;14;0;0;0;0;0;0;False;False +eye_angry;;0;0;0;1;83;133;104;14;14;0;0;0;0;0;0;False;False +mouth_idle;;-1;0;0;2;133;76;86;22;16;0;0;0;0;0;0;False;False;133;76;103;22;16;0;0;0;0;0;0;False;False +mouth_slow;;-1;0;0;2;350;76;86;22;16;0;0;0;0;0;0;False;False;350;76;103;22;16;0;0;0;0;0;0;False;False +fish_static;;0;0;0;1;83;40;79;32;48;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/marin.ani b/bin/Data/Animations/NPCs/marin.ani new file mode 100644 index 0000000..70dbe9c --- /dev/null +++ b/bin/Data/Animations/NPCs/marin.ani @@ -0,0 +1,26 @@ +1 +npcs.png +stand_0;;-1;0;0;1;200;28;181;14;16;-7;-16;0;0;0;0;False;False +stand_3;;-1;0;0;1;200;62;181;16;16;-8;-16;0;0;0;0;False;False +stand_1;;-1;0;0;1;200;80;181;14;16;-7;-16;0;0;0;0;False;False +stand_2;;-1;0;0;1;200;28;181;14;16;-7;-16;0;0;0;0;False;True +sing;;-1;0;0;4;267;144;181;16;16;-8;-16;0;0;0;0;False;False;800;128;181;15;16;-8;-16;0;0;0;0;False;False;267;144;181;16;16;-8;-16;0;0;0;0;False;False;800;128;181;15;16;-7;-16;0;0;0;0;False;True +idle;;-1;0;0;2;267;62;181;16;16;-8;-16;0;0;0;0;False;False;267;62;181;16;16;-8;-16;0;0;0;0;False;True +walk_0;;-1;0;0;2;133;44;182;16;15;-8;-15;0;0;0;0;False;False;133;28;181;14;16;-7;-16;0;0;0;0;False;False +walk_1;;-1;0;0;2;133;80;181;14;16;-7;-16;0;0;0;0;False;True;133;80;181;14;16;-7;-16;0;0;0;0;False;False +walk_2;;-1;0;0;2;133;44;182;16;15;-8;-15;0;0;0;0;False;True;133;28;181;14;16;-7;-16;0;0;0;0;False;True +walk_3;;-1;0;0;2;133;62;181;16;16;-8;-16;0;0;0;0;False;True;133;62;181;16;16;-8;-16;0;0;0;0;False;False +ocean_sit;;0;0;0;1;83;96;181;14;16;0;0;0;0;0;0;False;False +ocean_look;;0;0;0;3;500;96;181;14;16;0;0;0;0;0;0;False;False;2167;112;181;14;16;0;0;0;0;0;0;False;False;1500;96;181;14;16;0;0;0;0;0;0;False;False +ocean_ask;;0;0;0;1;83;112;181;14;16;0;0;0;0;0;0;False;False +land;;0;0;0;3;200;28;181;14;16;-7;-16;0;0;0;0;False;True;267;44;182;16;15;-8;-15;0;0;0;0;False;True;267;28;181;14;16;-7;-16;0;0;0;0;False;True +jump;;0;0;0;1;83;44;182;16;15;-8;-15;0;0;0;0;False;True +wait;;0;0;0;1;83;162;184;15;13;-7;-13;0;0;0;0;False;False +jump_up_0;;-1;0;0;1;133;44;182;16;15;-8;-15;0;0;0;0;False;False +jump_up_1;;-1;0;0;1;133;80;181;14;16;-7;-16;0;0;0;0;False;False +jump_up_2;;-1;0;0;1;133;44;182;16;15;-8;-15;0;0;0;0;False;True +jump_up_3;;-1;0;0;1;133;62;181;16;16;-8;-16;0;0;0;0;False;False +jump_down_0;;-1;0;0;1;133;28;181;14;16;-7;-16;0;0;0;0;False;False +jump_down_1;;-1;0;0;1;133;80;181;14;16;-7;-16;0;0;0;0;False;False +jump_down_2;;-1;0;0;1;133;28;181;14;16;-7;-16;0;0;0;0;False;True +jump_down_3;;-1;0;0;1;133;62;181;16;16;-8;-16;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/marin_letter.ani b/bin/Data/Animations/NPCs/marin_letter.ani new file mode 100644 index 0000000..ab2f9bb --- /dev/null +++ b/bin/Data/Animations/NPCs/marin_letter.ani @@ -0,0 +1,3 @@ +1 +npcs.png +idle;;0;0;0;1;83;179;186;14;11;-7;-11;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/monkey.ani b/bin/Data/Animations/NPCs/monkey.ani new file mode 100644 index 0000000..1ec8838 --- /dev/null +++ b/bin/Data/Animations/NPCs/monkey.ani @@ -0,0 +1,8 @@ +1 +npcs.png +idle_0;;-1;0;0;2;133;110;3;14;16;1;0;0;0;0;0;False;False;133;126;3;15;16;0;0;0;0;0;0;False;False +idle_1;;-1;0;0;2;133;110;3;14;16;1;0;0;0;0;0;False;True;133;126;3;15;16;1;0;0;0;0;0;False;True +jump_0;;0;0;0;1;83;143;3;16;16;0;0;0;0;0;0;False;False +jump_1;;0;0;0;1;83;143;3;16;16;0;0;0;0;0;0;False;True +idle_u_0;;0;0;0;1;83;161;4;14;15;1;1;0;0;0;0;False;False +idle_u_1;;0;0;0;1;83;161;4;14;15;1;1;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/mouse.ani b/bin/Data/Animations/NPCs/mouse.ani new file mode 100644 index 0000000..a01e530 --- /dev/null +++ b/bin/Data/Animations/NPCs/mouse.ani @@ -0,0 +1,6 @@ +1 +npcs.png +stand_1;;0;0;0;3;517;63;280;15;14;0;0;0;0;0;0;False;False;517;63;280;15;14;3;0;0;0;0;0;False;True;517;63;280;15;14;0;0;0;0;0;0;False;False +stand_0;;0;0;0;3;517;63;280;15;14;3;0;0;0;0;0;False;True;517;63;280;15;14;0;0;0;0;0;0;False;False;517;63;280;15;14;3;0;0;0;0;0;False;True +walk_1;;-1;0;0;1;67;80;280;16;14;0;0;0;0;0;0;False;False +walk_0;;-1;0;0;1;67;80;280;16;14;1;0;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/npc04.ani b/bin/Data/Animations/NPCs/npc04.ani new file mode 100644 index 0000000..fa39617 --- /dev/null +++ b/bin/Data/Animations/NPCs/npc04.ani @@ -0,0 +1,6 @@ +1 +npcs.png +STAND_0;;-1;0;0;2;500;313;57;15;20;-1;0;0;0;0;0;False;False;500;332;56;15;20;0;0;0;0;0;0;False;False +STAND_1;;-1;0;0;2;500;313;57;15;20;-1;0;0;0;0;0;False;False;500;332;56;15;20;0;0;0;0;0;0;False;False +STAND_2;;-1;0;0;2;500;313;57;15;20;-1;0;0;0;0;0;False;False;500;332;56;15;20;0;0;0;0;0;0;False;False +STAND_3;;-1;0;0;2;500;313;57;15;20;-1;0;0;0;0;0;False;False;500;332;56;15;20;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/npc05.ani b/bin/Data/Animations/NPCs/npc05.ani new file mode 100644 index 0000000..71cb79f --- /dev/null +++ b/bin/Data/Animations/NPCs/npc05.ani @@ -0,0 +1,6 @@ +1 +npcs.png +stand_0;;-1;0;0;2;250;388;6;13;14;0;0;0;0;0;0;False;True;250;388;6;13;14;1;0;0;0;0;0;False;False +stand_3;;-1;0;0;2;250;388;6;13;14;0;0;0;0;0;0;False;True;250;388;6;13;14;1;0;0;0;0;0;False;False +stand_1;;-1;0;0;2;250;403;6;14;14;0;0;0;0;0;0;False;False;250;403;6;14;14;0;0;0;0;0;0;False;True +stand_2;;-1;0;0;2;250;388;6;13;14;0;0;0;0;0;0;False;True;250;388;6;13;14;1;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/npc07.ani b/bin/Data/Animations/NPCs/npc07.ani new file mode 100644 index 0000000..3182108 --- /dev/null +++ b/bin/Data/Animations/NPCs/npc07.ani @@ -0,0 +1,3 @@ +1 +npcs.png +stand;;-1;-1;0;2;267;213;2;19;16;0;0;0;0;0;0;False;False;267;234;2;18;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/npc09.ani b/bin/Data/Animations/NPCs/npc09.ani new file mode 100644 index 0000000..4a6dc2b --- /dev/null +++ b/bin/Data/Animations/NPCs/npc09.ani @@ -0,0 +1,6 @@ +1 +npcs.png +stand_0;;-1;0;0;2;200;4;3;15;16;-7;-16;0;0;0;0;False;False;200;21;3;15;16;-7;-16;0;0;0;0;False;False +stand_3;;-1;0;0;2;200;37;3;16;16;-8;-16;0;0;0;0;False;False;200;55;3;16;16;-8;-16;0;0;0;0;False;False +stand_1;;-1;0;0;2;200;73;3;16;16;-8;-16;0;0;0;0;False;False;200;91;3;16;16;-8;-16;0;0;0;0;False;False +stand_2;;-1;0;0;2;200;4;3;15;16;-7;-16;0;0;0;0;False;True;200;21;3;15;16;-7;-16;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/npc_boy_left.ani b/bin/Data/Animations/NPCs/npc_boy_left.ani new file mode 100644 index 0000000..a921c25 --- /dev/null +++ b/bin/Data/Animations/NPCs/npc_boy_left.ani @@ -0,0 +1,4 @@ +1 +npcs.png +idle;;-1;0;0;1;1000;311;6;11;14;-5;-14;0;0;0;0;False;False +throw;idle;0;0;0;1;550;324;7;12;13;-5;-13;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/npc_boy_right.ani b/bin/Data/Animations/NPCs/npc_boy_right.ani new file mode 100644 index 0000000..58890fe --- /dev/null +++ b/bin/Data/Animations/NPCs/npc_boy_right.ani @@ -0,0 +1,4 @@ +1 +npcs.png +idle;;-1;0;0;1;1000;360;6;11;14;-6;-14;0;0;0;0;False;False +throw;idle;0;0;0;1;550;346;7;12;13;-7;-13;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/npc_chef.ani b/bin/Data/Animations/NPCs/npc_chef.ani new file mode 100644 index 0000000..b35b0c4 --- /dev/null +++ b/bin/Data/Animations/NPCs/npc_chef.ani @@ -0,0 +1,4 @@ +1 +npcs.png +idle;;-1;-14;-31;2;550;115;42;28;31;0;0;0;0;0;0;False;False;550;115;42;28;31;0;0;0;0;0;0;False;True +left;;0;0;0;1;83;115;42;28;31;-14;-31;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/npc_chicken_dude.ani b/bin/Data/Animations/NPCs/npc_chicken_dude.ani new file mode 100644 index 0000000..a4b462f --- /dev/null +++ b/bin/Data/Animations/NPCs/npc_chicken_dude.ani @@ -0,0 +1,10 @@ +1 +npcs.png +idle_-1;;0;0;0;1;83;173;157;12;16;-6;-16;0;0;0;0;False;False +fly_stop_-1;;0;0;0;1;83;203;158;15;15;-8;-16;0;0;0;0;False;False +fly_forward_-1;;0;-7;0;1;83;220;157;14;16;0;-16;0;0;0;0;False;False +fly_stop_1;;0;0;0;1;83;203;158;15;15;-7;-16;0;0;0;0;False;True +fly_forward_1;;0;0;0;1;83;220;157;14;16;-7;-16;0;0;0;0;False;True +idle_1;;0;0;0;1;83;173;157;12;16;-6;-16;0;0;0;0;False;True +powder_-1;;0;0;0;1;83;187;157;14;16;-8;-16;0;0;0;0;False;False +powder_1;;0;0;0;1;83;187;157;14;16;-6;-16;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/npc_color_dungeon_blue.ani b/bin/Data/Animations/NPCs/npc_color_dungeon_blue.ani new file mode 100644 index 0000000..f721d6f --- /dev/null +++ b/bin/Data/Animations/NPCs/npc_color_dungeon_blue.ani @@ -0,0 +1,4 @@ +1 +npcs.png +idle;;-1;0;0;2;267;360;282;15;16;-8;-16;0;0;0;0;False;False;267;360;282;15;16;-7;-16;0;0;0;0;False;True +walk;;0;0;0;2;267;377;282;13;16;-6;-16;0;0;0;0;False;False;267;392;283;13;15;-6;-15;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/npc_color_dungeon_red.ani b/bin/Data/Animations/NPCs/npc_color_dungeon_red.ani new file mode 100644 index 0000000..e1712d3 --- /dev/null +++ b/bin/Data/Animations/NPCs/npc_color_dungeon_red.ani @@ -0,0 +1,4 @@ +1 +npcs.png +idle;;-1;0;0;2;267;313;282;15;16;-8;-16;0;0;0;0;False;False;267;313;282;15;16;-7;-16;0;0;0;0;False;True +walk;;0;0;0;2;267;330;282;13;16;-6;-16;0;0;0;0;False;False;267;345;283;13;15;-6;-15;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/npc_fisherman.ani b/bin/Data/Animations/NPCs/npc_fisherman.ani new file mode 100644 index 0000000..983d767 --- /dev/null +++ b/bin/Data/Animations/NPCs/npc_fisherman.ani @@ -0,0 +1,9 @@ +1 +npcs.png +stand;;-1;0;0;2;783;294;144;29;16;-21;-16;0;0;0;0;False;False;267;325;144;30;16;-22;-16;0;0;0;0;False;False +talk;;0;0;0;1;83;357;144;30;16;-22;-16;0;0;0;0;False;False +look;;0;0;0;1;83;357;144;30;16;-22;-16;0;0;0;0;False;False +pull_look;;0;0;0;1;83;389;142;28;18;-20;-18;0;0;0;0;False;False +pull;;0;0;0;1;83;419;142;29;18;-20;-18;0;0;0;0;False;False +idle;;0;0;0;1;83;294;144;29;16;-21;-16;0;0;0;0;False;False +down;;0;0;0;1;83;325;144;30;16;-22;-16;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/npc_frog_boy.ani b/bin/Data/Animations/NPCs/npc_frog_boy.ani new file mode 100644 index 0000000..dd2764d --- /dev/null +++ b/bin/Data/Animations/NPCs/npc_frog_boy.ani @@ -0,0 +1,6 @@ +1 +npcs.png +stand_0;;-1;0;0;2;267;260;20;15;16;-9;-16;0;0;0;0;False;True;267;276;21;16;15;-9;-15;0;0;0;0;False;True +stand_3;;-1;0;0;2;267;260;2;15;16;-7;-16;0;0;0;0;False;False;267;276;2;15;16;-8;-16;0;0;0;0;False;False +stand_2;;-1;0;0;2;267;260;20;15;16;-6;-16;0;0;0;0;False;False;267;276;21;16;15;-7;-15;0;0;0;0;False;False +walk_0;;-1;0;0;2;133;260;20;15;16;-9;-16;0;0;0;0;False;True;133;276;21;16;15;-9;-15;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/npc_green_boy.ani b/bin/Data/Animations/NPCs/npc_green_boy.ani new file mode 100644 index 0000000..692ee2e --- /dev/null +++ b/bin/Data/Animations/NPCs/npc_green_boy.ani @@ -0,0 +1,4 @@ +1 +npcs.png +stand_3;;-1;-7;-14;2;250;388;6;13;14;0;0;0;0;0;0;False;True;250;388;6;13;14;1;0;0;0;0;0;False;False +stand_1;;-1;-7;-14;2;267;403;6;14;14;0;0;0;0;0;0;False;False;267;403;6;14;14;0;0;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/npc_hidden.ani b/bin/Data/Animations/NPCs/npc_hidden.ani new file mode 100644 index 0000000..3949cd9 --- /dev/null +++ b/bin/Data/Animations/NPCs/npc_hidden.ani @@ -0,0 +1,6 @@ +1 +npcs.png +stand_3;;-1;0;0;2;267;462;63;16;16;-8;-16;0;0;0;0;False;False;267;462;63;16;16;-8;-16;0;0;0;0;False;True +stand_0;;-1;0;0;2;267;496;63;16;16;-8;-16;0;0;0;0;False;False;267;513;63;16;16;-8;-16;0;0;0;0;False;False +stand_1;;0;0;0;2;267;479;63;16;16;-8;-16;0;0;0;0;False;False;267;479;63;16;16;-8;-16;0;0;0;0;False;True +stand_2;;0;0;0;2;267;496;63;16;16;-8;-16;0;0;0;0;False;True;267;513;63;16;16;-8;-16;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/npc_hippo.ani b/bin/Data/Animations/NPCs/npc_hippo.ani new file mode 100644 index 0000000..f0f97d1 --- /dev/null +++ b/bin/Data/Animations/NPCs/npc_hippo.ani @@ -0,0 +1,4 @@ +1 +npcs.png +idle_-1;;-1;-1;0;2;133;494;200;19;24;-9;-24;0;0;0;0;False;False;133;515;200;19;24;-9;-24;0;0;0;0;False;False +idle_1;;-1;1;0;2;133;494;200;19;24;-10;-24;0;0;0;0;False;True;133;515;200;19;24;-10;-24;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/npc_letter_boy.ani b/bin/Data/Animations/NPCs/npc_letter_boy.ani new file mode 100644 index 0000000..dc8d82d --- /dev/null +++ b/bin/Data/Animations/NPCs/npc_letter_boy.ani @@ -0,0 +1,5 @@ +1 +npcs.png +idle;;-1;0;0;2;533;160;256;16;18;-8;-18;0;0;0;0;False;False;533;160;256;16;18;-8;-18;0;0;0;0;False;True +look_1;;0;0;0;1;83;178;256;16;18;-8;-18;0;0;0;0;False;False +look_-1;;0;0;0;1;83;178;256;16;18;-8;-18;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/npc_letter_girl.ani b/bin/Data/Animations/NPCs/npc_letter_girl.ani new file mode 100644 index 0000000..63a1058 --- /dev/null +++ b/bin/Data/Animations/NPCs/npc_letter_girl.ani @@ -0,0 +1,3 @@ +1 +npcs.png +idle;;-1;0;0;2;533;32;228;16;21;-8;-18;0;0;0;0;False;False;533;32;228;16;21;-8;-18;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/npc_lost_boy.ani b/bin/Data/Animations/NPCs/npc_lost_boy.ani new file mode 100644 index 0000000..e760f26 --- /dev/null +++ b/bin/Data/Animations/NPCs/npc_lost_boy.ani @@ -0,0 +1,11 @@ +1 +npcs.png +stand_0;;-1;0;0;1;200;143;24;12;16;-6;-16;0;0;0;0;False;False +stand_2;;-1;0;0;1;200;143;24;12;16;-6;-16;0;0;0;0;False;True +wave_0;;-1;0;0;2;133;173;24;15;16;-7;-16;0;0;0;0;False;False;133;189;24;16;16;-8;-16;0;0;0;0;False;False +wave_2;;-1;0;0;2;133;173;24;15;16;-8;-16;0;0;0;0;False;True;133;189;24;16;16;-8;-16;0;0;0;0;False;True +hand_0;;0;0;0;1;83;173;24;15;16;-7;-16;0;0;0;0;False;False +hand_2;;0;0;0;1;83;173;24;15;16;-8;-16;0;0;0;0;False;True +eat_0;;-1;0;0;2;133;207;24;16;16;-8;-16;0;0;0;0;False;False;133;225;24;14;16;-7;-16;0;0;0;0;False;False +eat_2;;-1;0;0;2;133;207;24;16;16;-8;-16;0;0;0;0;False;True;133;225;24;14;16;-7;-16;0;0;0;0;False;True +wave;;-1;0;0;2;267;173;24;15;16;-8;-16;0;0;0;0;False;True;267;189;24;16;16;-8;-16;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/npc_mermaid.ani b/bin/Data/Animations/NPCs/npc_mermaid.ani new file mode 100644 index 0000000..3f69180 --- /dev/null +++ b/bin/Data/Animations/NPCs/npc_mermaid.ani @@ -0,0 +1,8 @@ +1 +npcs.png +leave;;0;0;0;2;133;175;234;15;16;-7;-16;0;0;0;0;False;False;133;175;234;15;16;-8;-16;0;0;0;0;False;True +idle;;-1;0;0;4;267;121;233;16;17;-8;-15;0;0;0;0;False;False;133;139;232;16;18;-8;-16;0;0;0;0;False;False;267;157;231;16;19;-8;-17;0;0;0;0;False;False;133;139;232;16;18;-8;-16;0;0;0;0;False;False +jump;;0;0;0;1;83;192;234;23;16;-12;-16;0;0;0;0;False;False +stone_spawn;;-1;0;0;2;267;218;194;16;30;-8;-30;0;0;0;0;False;False;267;218;194;16;30;-8;-30;0;0;0;0;False;True +sit_-1;;0;0;0;1;83;236;194;17;30;-8;-30;0;0;0;0;False;False +sit_1;;0;0;0;1;83;236;194;17;30;-9;-30;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/npc_painter.ani b/bin/Data/Animations/NPCs/npc_painter.ani new file mode 100644 index 0000000..6fef9ba --- /dev/null +++ b/bin/Data/Animations/NPCs/npc_painter.ani @@ -0,0 +1,5 @@ +1 +npcs.png +idle;;-1;0;0;2;533;514;234;21;22;-13;-22;0;0;0;0;False;False;533;514;234;21;22;-8;-22;0;0;0;0;False;True +talk_-1;;0;0;0;1;83;488;233;24;23;-16;-23;0;0;0;0;False;False +talk_1;;0;0;0;1;83;488;233;24;23;-8;-23;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/npc_raft.ani b/bin/Data/Animations/NPCs/npc_raft.ani new file mode 100644 index 0000000..fdb2e75 --- /dev/null +++ b/bin/Data/Animations/NPCs/npc_raft.ani @@ -0,0 +1,6 @@ +1 +npcs.png +stand_0;;-1;0;0;2;267;250;134;15;16;-8;-16;0;0;0;0;False;False;267;267;135;15;15;-8;-15;0;0;0;0;False;False +stand_3;;-1;0;0;2;267;215;134;16;16;-8;-16;0;0;0;0;False;False;267;215;134;16;16;-8;-16;0;0;0;0;False;True +stand_1;;-1;0;0;2;267;232;134;16;16;-8;-16;0;0;0;0;False;False;267;232;134;16;16;-8;-16;0;0;0;0;False;True +stand_2;;-1;0;0;2;267;250;134;15;16;-7;-16;0;0;0;0;False;True;267;267;135;15;15;-7;-15;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/npc_red_boy.ani b/bin/Data/Animations/NPCs/npc_red_boy.ani new file mode 100644 index 0000000..5254a36 --- /dev/null +++ b/bin/Data/Animations/NPCs/npc_red_boy.ani @@ -0,0 +1,4 @@ +1 +npcs.png +stand_3;;-1;-7;-14;2;267;419;6;13;14;0;0;0;0;0;0;False;True;267;419;6;13;14;1;0;0;0;0;0;False;False +stand_1;;-1;-7;-14;2;267;434;6;14;14;0;0;0;0;0;0;False;False;267;434;6;14;14;0;0;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/npc_tracy.ani b/bin/Data/Animations/NPCs/npc_tracy.ani new file mode 100644 index 0000000..9a05500 --- /dev/null +++ b/bin/Data/Animations/NPCs/npc_tracy.ani @@ -0,0 +1,5 @@ +1 +npcs.png +idle;;0;0;0;1;83;353;56;16;23;-8;-23;0;0;0;0;False;False +left;;0;0;0;1;83;371;56;16;23;-8;-23;0;0;0;0;False;False +right;;0;0;0;1;83;371;56;16;23;-8;-23;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/npc_trendy.ani b/bin/Data/Animations/NPCs/npc_trendy.ani new file mode 100644 index 0000000..7c81b9d --- /dev/null +++ b/bin/Data/Animations/NPCs/npc_trendy.ani @@ -0,0 +1,8 @@ +1 +npcs.png +stand_0;;-1;-8;-16;1;133;181;134;15;16;0;0;0;0;0;0;False;False +stand_3;;-1;-8;-16;2;133;146;134;16;16;0;0;0;0;0;0;False;False;133;146;134;16;16;0;0;0;0;0;0;False;True +stand_1;;-1;-8;-16;2;133;163;134;16;16;0;0;0;0;0;0;False;False;133;163;134;16;16;0;0;0;0;0;0;False;True +stand_2;;-1;-7;-16;2;133;181;134;15;16;0;0;0;0;0;0;False;True;133;198;135;15;15;0;1;0;0;0;0;False;True +grabbed;;-1;0;0;2;267;198;135;15;15;-7;-15;0;0;0;0;False;False;267;198;135;15;15;-8;-15;0;0;0;0;False;True +fall;;0;0;0;1;83;198;135;15;15;-8;-15;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/npc_woman_broom.ani b/bin/Data/Animations/NPCs/npc_woman_broom.ani new file mode 100644 index 0000000..974728b --- /dev/null +++ b/bin/Data/Animations/NPCs/npc_woman_broom.ani @@ -0,0 +1,6 @@ +1 +npcs.png +stand_-1;;-1;-8;-16;2;200;392;63;16;16;0;0;0;0;0;0;False;False;200;409;63;16;16;0;0;0;0;0;0;False;False +stand_1;;-1;-8;-16;2;200;392;63;16;16;0;0;0;0;0;0;False;True;200;409;63;16;16;0;0;0;0;0;0;False;True +missing_broom;;-1;0;0;2;267;426;63;15;15;-8;-16;0;0;0;0;False;False;267;426;63;15;15;-7;-16;0;0;0;0;False;True +show;;0;0;0;1;83;442;63;16;16;-8;-16;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/npc_zora.ani b/bin/Data/Animations/NPCs/npc_zora.ani new file mode 100644 index 0000000..3a55614 --- /dev/null +++ b/bin/Data/Animations/NPCs/npc_zora.ani @@ -0,0 +1,4 @@ +1 +enemies.png +spawn;;-1;0;0;2;83;0;210;16;14;-8;-15;0;0;0;0;False;False;83;0;210;16;14;-8;-15;0;0;0;0;False;True +idle;;0;0;0;1;83;32;208;16;16;-8;-16;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/owl.ani b/bin/Data/Animations/NPCs/owl.ani new file mode 100644 index 0000000..521942c --- /dev/null +++ b/bin/Data/Animations/NPCs/owl.ani @@ -0,0 +1,5 @@ +1 +npcs.png +idle;;-1;0;0;4;1000;314;259;14;16;-7;-16;0;0;0;0;False;False;200;330;259;14;16;-7;-16;0;0;0;0;False;False;317;314;259;14;16;-7;-16;0;0;0;0;False;False;200;330;259;14;16;-7;-16;0;0;0;0;False;False +fly;;-1;0;0;2;133;346;259;24;16;-12;-16;0;0;0;0;False;False;133;314;259;14;16;-7;-16;0;0;0;0;False;False +hover;;-1;0;0;4;133;372;257;20;18;-10;-18;0;0;0;0;False;False;133;394;257;26;18;-13;-18;0;0;0;0;False;False;133;421;258;26;17;-13;-18;0;0;0;0;False;False;133;449;258;26;17;-13;-18;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/photo_mouse.ani b/bin/Data/Animations/NPCs/photo_mouse.ani new file mode 100644 index 0000000..e42af15 --- /dev/null +++ b/bin/Data/Animations/NPCs/photo_mouse.ani @@ -0,0 +1,14 @@ +1 +npcs.png +stand_0;;0;0;0;1;83;99;157;15;16;-7;-16;0;0;0;0;False;False +stand_1;;0;0;0;1;83;117;157;15;16;-8;-16;0;0;0;0;False;False +stand_2;;0;0;0;1;83;99;157;15;16;-8;-16;0;0;0;0;False;True +stand_3;;0;0;0;1;83;63;157;15;16;-7;-16;0;0;0;0;False;False +walk_0;;-1;0;0;2;133;99;157;15;16;-7;-16;0;0;0;0;False;False;133;82;158;14;15;-7;-15;0;0;0;0;False;False +walk_1;;-1;0;0;2;133;117;157;15;16;-8;-16;0;0;0;0;False;False;133;135;157;15;16;-8;-16;0;0;0;0;False;False +walk_2;;-1;0;0;2;133;99;157;15;16;-8;-16;0;0;0;0;False;True;133;82;158;14;15;-7;-15;0;0;0;0;False;True +walk_3;;-1;0;0;2;133;63;157;15;16;-7;-16;0;0;0;0;False;False;133;45;157;15;16;-7;-16;0;0;0;0;False;False +duck;;-1;0;0;1;83;82;158;14;15;-7;-15;0;0;0;0;False;True +swim_-1;;-1;0;0;2;267;26;157;15;16;-7;-16;0;0;0;0;False;False;267;7;157;16;16;-7;-16;0;0;0;0;False;False +swim_1;;-1;0;0;2;267;26;157;15;16;-8;-16;0;0;0;0;False;True;267;7;157;16;16;-9;-16;0;0;0;0;False;True +pulled;;0;0;0;1;83;152;157;16;16;-8;-16;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/raccoon.ani b/bin/Data/Animations/NPCs/raccoon.ani new file mode 100644 index 0000000..5072ed2 --- /dev/null +++ b/bin/Data/Animations/NPCs/raccoon.ani @@ -0,0 +1,5 @@ +1 +npcs.png +idle;;-1;0;0;2;267;125;205;16;16;0;0;0;0;0;0;False;False;267;125;205;16;16;0;0;0;0;0;0;False;True +laugh;;-1;0;0;2;133;125;205;16;16;0;0;0;0;0;0;False;False;133;143;205;16;16;0;0;0;0;0;0;False;False +rotate;;-1;0;0;6;133;125;205;16;16;0;0;0;0;0;0;False;False;133;89;205;16;16;0;0;0;0;0;0;False;False;133;107;205;16;16;0;0;0;0;0;0;False;False;133;107;205;16;16;0;0;0;0;0;0;False;True;133;89;205;16;16;0;0;0;0;0;0;False;True;133;125;205;16;16;0;0;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/shopkeeper.ani b/bin/Data/Animations/NPCs/shopkeeper.ani new file mode 100644 index 0000000..d3cff83 --- /dev/null +++ b/bin/Data/Animations/NPCs/shopkeeper.ani @@ -0,0 +1,6 @@ +1 +npcs.png +stand_0;;-1;0;0;2;200;317;118;12;16;1;0;0;0;0;0;False;False;200;331;118;14;16;0;0;0;0;0;0;False;False +stand_3;;-1;-1;0;2;200;363;118;15;16;0;0;0;0;0;0;False;False;200;363;118;15;16;1;0;0;0;0;0;False;True +stand_1;;-1;0;0;2;200;347;118;14;16;0;0;0;0;0;0;False;False;200;347;118;14;16;0;0;0;0;0;0;False;True +stand_2;;-1;0;0;2;200;317;118;12;16;1;0;0;0;0;0;False;True;200;331;118;14;16;0;0;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/singing frog.ani b/bin/Data/Animations/NPCs/singing frog.ani new file mode 100644 index 0000000..ff781f7 --- /dev/null +++ b/bin/Data/Animations/NPCs/singing frog.ani @@ -0,0 +1,5 @@ +1 +npcs.png +idle;;-1;0;0;2;267;409;220;16;16;-8;-16;0;0;0;0;False;False;833;427;220;16;16;-8;-16;0;0;0;0;False;False +left;;0;0;0;1;83;445;214;16;22;-8;-22;0;0;0;0;False;False +right;;0;0;0;1;83;445;214;16;22;-8;-22;0;0;0;0;False;True diff --git a/bin/Data/Animations/NPCs/tarin mushroom.ani b/bin/Data/Animations/NPCs/tarin mushroom.ani new file mode 100644 index 0000000..4f6963e --- /dev/null +++ b/bin/Data/Animations/NPCs/tarin mushroom.ani @@ -0,0 +1,4 @@ +1 +items.png +show;;0;0;0;1;83;90;40;10;11;-11;-26;0;0;0;0;False;False +hidden;;0;0;0;1;83;90;40;0;0;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/tarin stick.ani b/bin/Data/Animations/NPCs/tarin stick.ani new file mode 100644 index 0000000..2bb115f --- /dev/null +++ b/bin/Data/Animations/NPCs/tarin stick.ani @@ -0,0 +1,6 @@ +1 +npcs.png +show;;-1;0;0;1;67;170;205;6;16;-7;-32;0;0;0;0;False;False +walk_0;;0;0;0;1;83;178;209;12;12;-16;-13;0;0;0;0;False;False +stick_up;;0;0;0;1;83;170;205;6;16;-8;-32;0;0;0;0;False;False +stick_down;;0;0;0;1;83;178;209;12;12;-19;-21;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/tarin.ani b/bin/Data/Animations/NPCs/tarin.ani new file mode 100644 index 0000000..3d30212 --- /dev/null +++ b/bin/Data/Animations/NPCs/tarin.ani @@ -0,0 +1,14 @@ +1 +npcs.png +stand_0;;-1;0;0;1;200;8;205;13;16;-7;-16;0;0;0;0;False;False +stand_3;;-1;0;0;1;200;39;205;14;16;-7;-16;0;0;0;0;False;False +stand_1;;-1;0;0;1;200;55;205;14;16;-7;-16;0;0;0;0;False;False +stand_2;;-1;0;0;1;200;8;205;13;16;-6;-16;0;0;0;0;False;True +walk_0;;-1;0;0;2;133;8;205;13;16;-7;-16;0;0;0;0;False;False;133;23;206;14;15;-7;-15;0;0;0;0;False;False +walk_1;;-1;0;0;2;133;55;205;14;16;-7;-16;0;0;0;0;False;False;133;55;205;14;16;-7;-16;0;0;0;0;False;True +walk_2;;-1;0;0;2;133;8;205;13;16;-6;-16;0;0;0;0;False;True;133;23;206;14;15;-7;-15;0;0;0;0;False;True +walk_3;;-1;0;0;2;133;39;205;14;16;-7;-16;0;0;0;0;False;False;133;39;205;14;16;-7;-16;0;0;0;0;False;True +show;;0;0;0;1;83;71;205;16;16;-8;-16;0;0;0;0;False;False +stick_down;;0;0;0;1;83;23;206;14;15;-7;-15;0;0;0;0;False;False +stick_up;;0;0;0;1;83;8;205;13;16;-7;-16;0;0;0;0;False;False +sleep;;0;0;0;1;83;192;205;15;16;-8;-16;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/walrus particle.ani b/bin/Data/Animations/NPCs/walrus particle.ani new file mode 100644 index 0000000..329dbe3 --- /dev/null +++ b/bin/Data/Animations/NPCs/walrus particle.ani @@ -0,0 +1,3 @@ +1 +npcs.png +idle;;0;0;0;2;533;286;58;4;4;-2;-2;0;0;0;0;False;False;533;285;64;6;6;-3;-3;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/walrus.ani b/bin/Data/Animations/NPCs/walrus.ani new file mode 100644 index 0000000..69d8bac --- /dev/null +++ b/bin/Data/Animations/NPCs/walrus.ani @@ -0,0 +1,12 @@ +1 +npcs.png +sleep;;0;0;0;1;83;149;52;32;28;-16;-27;0;0;0;0;False;False +blink;;0;0;0;2;83;183;52;32;28;-16;-27;0;0;0;0;False;False;83;149;52;32;28;-16;-27;0;0;0;0;False;False +wobble;;0;0;0;7;267;183;52;32;28;-16;-27;0;0;0;0;False;False;83;217;50;32;30;-16;-29;0;0;0;0;False;False;133;183;52;32;28;-16;-27;0;0;0;0;False;False;133;217;50;32;30;-16;-29;0;0;0;0;False;False;83;183;52;32;28;-16;-27;0;0;0;0;False;False;83;217;50;32;30;-16;-29;0;0;0;0;False;False;267;183;52;32;28;-16;-27;0;0;0;0;False;False +down;;0;0;0;1;83;183;52;32;28;-16;-27;0;0;0;0;False;False +jump;;0;0;0;2;400;217;50;32;30;-16;-29;0;0;0;0;False;False;83;251;48;32;32;-16;-25;0;0;0;0;False;False +fall;;0;0;0;1;83;149;52;32;28;-16;-1;0;0;0;0;True;False +up;;0;0;0;1;83;217;50;32;30;-16;-29;0;0;0;0;False;False +awakening;;0;0;0;10;1100;149;52;32;28;-16;-27;0;0;0;0;False;False;2000;183;52;32;28;-16;-27;0;0;0;0;False;False;200;149;52;32;28;-16;-27;0;0;0;0;False;False;1100;183;52;32;28;-16;-27;0;0;0;0;False;False;1000;217;50;32;30;-16;-29;0;0;0;0;False;False;133;183;52;32;28;-16;-27;0;0;0;0;False;False;133;217;50;32;30;-16;-29;0;0;0;0;False;False;133;183;52;32;28;-16;-27;0;0;0;0;False;False;133;217;50;32;30;-16;-29;0;0;0;0;False;False;83;183;52;32;28;-16;-27;0;0;0;0;False;False +swim_up;;0;0;0;1;83;160;96;23;16;-11;-16;0;0;0;0;False;False +swim_down;;0;0;0;1;83;185;92;24;20;-11;-20;0;0;0;0;False;False diff --git a/bin/Data/Animations/NPCs/witch.ani b/bin/Data/Animations/NPCs/witch.ani new file mode 100644 index 0000000..cfe5cf4 --- /dev/null +++ b/bin/Data/Animations/NPCs/witch.ani @@ -0,0 +1,4 @@ +1 +npcs.png +idle;;-1;0;0;4;250;27;264;16;30;0;0;0;0;0;0;False;False;250;9;265;16;29;0;1;0;0;0;0;False;True;250;27;264;16;30;0;0;0;0;0;0;False;False;250;9;265;16;29;0;1;0;0;0;0;False;False +mix;;10;0;0;4;67;27;264;16;30;0;0;0;0;0;0;False;False;67;9;265;16;29;0;1;0;0;0;0;False;True;67;27;264;16;30;0;0;0;0;0;0;False;False;67;9;265;16;29;0;1;0;0;0;0;False;False diff --git a/bin/Data/Animations/Nightmares/anger fish stone.ani b/bin/Data/Animations/Nightmares/anger fish stone.ani new file mode 100644 index 0000000..918cd56 --- /dev/null +++ b/bin/Data/Animations/Nightmares/anger fish stone.ani @@ -0,0 +1,3 @@ +1 +nightmares.png +run;;-1;0;0;2;267;16;97;16;14;0;0;0;0;0;0;False;False;267;16;97;16;14;0;0;0;0;0;0;False;True diff --git a/bin/Data/Animations/Nightmares/anger fish.ani b/bin/Data/Animations/Nightmares/anger fish.ani new file mode 100644 index 0000000..d72cfb6 --- /dev/null +++ b/bin/Data/Animations/Nightmares/anger fish.ani @@ -0,0 +1,3 @@ +1 +nightmares.png +idle;;-1;0;0;2;267;7;133;56;48;2;1;0;0;0;0;False;False;267;7;186;58;49;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Nightmares/evil eagle.ani b/bin/Data/Animations/Nightmares/evil eagle.ani new file mode 100644 index 0000000..a5ef8c3 --- /dev/null +++ b/bin/Data/Animations/Nightmares/evil eagle.ani @@ -0,0 +1,9 @@ +1 +nightmares.png +glide_-1;;0;0;0;1;83;240;221;56;25;-13;-19;0;0;0;0;False;False +glide_1;;0;0;0;1;83;240;221;56;25;-43;-19;0;0;0;0;False;True +flap;;-1;0;0;2;67;244;320;48;48;-13;-32;0;0;0;0;False;False;67;228;283;40;32;-13;-16;0;0;0;0;False;False +cflap_-1;;-1;0;0;4;67;244;320;48;48;-13;-32;0;0;0;0;False;False;67;228;283;40;32;-13;-16;0;0;0;0;False;False;67;272;283;40;32;-13;-16;0;0;0;0;False;False;67;228;283;40;32;-13;-16;0;0;0;0;False;False +cflap_1;;-1;0;0;4;67;244;320;48;48;-35;-32;0;0;0;0;False;True;67;228;283;40;32;-27;-16;0;0;0;0;False;True;67;272;283;40;32;-27;-16;0;0;0;0;False;True;67;228;283;40;32;-27;-16;0;0;0;0;False;True +cglide_-1;;0;0;0;1;83;240;248;56;30;-13;-24;0;0;0;0;False;False +cglide_1;;0;0;0;1;83;240;248;56;30;-43;-24;0;0;0;0;False;True diff --git a/bin/Data/Animations/Nightmares/facade hole.ani b/bin/Data/Animations/Nightmares/facade hole.ani new file mode 100644 index 0000000..e149739 --- /dev/null +++ b/bin/Data/Animations/Nightmares/facade hole.ani @@ -0,0 +1,3 @@ +1 +nightmares.png +idle;;0;0;0;7;667;306;102;4;4;-2;-2;0;0;0;0;False;False;133;296;100;8;8;-4;-4;0;0;0;0;False;False;133;282;98;12;12;-6;-6;0;0;0;0;False;False;800;264;96;16;16;-8;-8;0;0;0;0;False;False;133;282;98;12;12;-6;-6;0;0;0;0;False;False;133;296;100;8;8;-4;-4;0;0;0;0;False;False;133;306;102;4;4;-2;-2;0;0;0;0;False;False diff --git a/bin/Data/Animations/Nightmares/facade.ani b/bin/Data/Animations/Nightmares/facade.ani new file mode 100644 index 0000000..c8e9f4e --- /dev/null +++ b/bin/Data/Animations/Nightmares/facade.ani @@ -0,0 +1,12 @@ +1 +nightmares.png +eye_blink;;0;-23;2;2;133;265;16;46;12;0;0;0;0;0;0;False;False;133;265;32;46;13;0;0;0;0;0;0;False;False +eye;;0;-23;0;1;83;265;48;46;14;0;0;0;0;0;0;False;False +eye_half;;0;-23;2;1;133;265;32;46;13;0;0;0;0;0;0;False;False +eye_closed;;0;-23;2;1;267;265;16;46;12;0;0;0;0;0;0;False;False +mouth_open;;0;0;0;2;533;275;64;26;7;-13;0;0;0;0;0;False;False;83;272;75;32;13;-16;-5;0;0;0;0;False;False +mouth_closed;;0;0;0;1;533;275;64;26;7;-13;0;0;0;0;0;False;False +mouth_opened;;0;0;0;1;83;272;75;32;13;-16;-5;0;0;0;0;False;False +eye_blink_full;;0;-23;2;3;133;265;32;46;13;0;0;0;0;0;0;False;False;133;265;16;46;12;0;0;0;0;0;0;False;False;133;265;32;46;13;0;0;0;0;0;0;False;False +eye_respawn;;0;-23;2;2;267;265;16;46;12;0;0;0;0;0;0;False;False;533;265;32;46;13;0;0;0;0;0;0;False;False +mouth_respawn;;0;0;0;2;533;275;64;26;7;-13;0;0;0;0;0;False;False;267;272;75;32;13;-16;-5;0;0;0;0;False;False diff --git a/bin/Data/Animations/Nightmares/genie bottle.ani b/bin/Data/Animations/Nightmares/genie bottle.ani new file mode 100644 index 0000000..889fa1d --- /dev/null +++ b/bin/Data/Animations/Nightmares/genie bottle.ani @@ -0,0 +1,4 @@ +1 +nightmares.png +idle;;0;0;0;1;83;208;136;16;24;-8;-24;0;0;0;0;False;False +wobble;;-1;0;0;4;133;208;136;16;24;-8;-24;0;0;0;0;False;False;133;226;131;15;29;-8;-29;0;0;0;0;False;False;133;208;136;16;24;-8;-24;0;0;0;0;False;False;133;226;131;15;29;-7;-29;0;0;0;0;False;True diff --git a/bin/Data/Animations/Nightmares/genie smoke.ani b/bin/Data/Animations/Nightmares/genie smoke.ani new file mode 100644 index 0000000..c44fcd6 --- /dev/null +++ b/bin/Data/Animations/Nightmares/genie smoke.ani @@ -0,0 +1,5 @@ +1 +items.png +top;;0;0;0;7;267;43;155;10;10;-5;-5;0;0;0;0;False;False;400;224;160;16;16;-8;-8;0;0;0;0;False;False;133;242;154;28;28;-14;-14;0;0;0;0;False;False;133;272;152;32;32;-16;-16;0;0;0;0;False;False;133;242;154;28;28;-14;-14;0;0;0;0;False;False;133;272;152;32;32;-16;-16;0;0;0;0;False;False;133;184;169;32;31;-16;-16;0;0;0;0;False;False +bottom;;0;0;0;1;267;43;155;10;10;-5;-5;0;0;0;0;False;False +despawn;;0;0;0;7;133;184;169;32;31;-16;-16;0;0;0;0;False;False;133;272;152;32;32;-16;-16;0;0;0;0;False;False;133;242;154;28;28;-14;-14;0;0;0;0;False;False;133;272;152;32;32;-16;-16;0;0;0;0;False;False;133;242;154;28;28;-14;-14;0;0;0;0;False;False;400;224;160;16;16;-8;-8;0;0;0;0;False;False;267;43;155;10;10;-5;-5;0;0;0;0;False;False diff --git a/bin/Data/Animations/Nightmares/genie.ani b/bin/Data/Animations/Nightmares/genie.ani new file mode 100644 index 0000000..2d6c80b --- /dev/null +++ b/bin/Data/Animations/Nightmares/genie.ani @@ -0,0 +1,7 @@ +1 +nightmares.png +idle;;-1;-20;-44;2;267;204;164;40;32;0;0;0;0;0;0;False;False;267;204;164;40;32;0;0;0;0;0;0;False;True +tail;;-1;-4;-12;2;133;220;196;8;12;0;0;0;0;0;0;False;False;133;220;196;8;12;0;0;0;0;0;0;False;True +attack_0;idle;0;-20;-44;1;267;246;164;40;32;0;0;0;0;0;0;False;False +attack_1;idle;0;-20;-44;1;267;246;164;40;32;0;0;0;0;0;0;False;True +attack;;-1;-20;-44;2;267;246;164;40;32;0;0;0;0;0;0;False;False;267;246;164;40;32;0;0;0;0;0;0;False;True diff --git a/bin/Data/Animations/Nightmares/hardhit beetle shot.ani b/bin/Data/Animations/Nightmares/hardhit beetle shot.ani new file mode 100644 index 0000000..beffb2f --- /dev/null +++ b/bin/Data/Animations/Nightmares/hardhit beetle shot.ani @@ -0,0 +1,3 @@ +1 +nightmares.png +idle;;-1;0;0;2;133;9;291;14;14;-7;-7;0;0;0;0;False;False;133;25;290;16;16;-8;-8;0;0;0;0;False;False diff --git a/bin/Data/Animations/Nightmares/hardhit beetle.ani b/bin/Data/Animations/Nightmares/hardhit beetle.ani new file mode 100644 index 0000000..b3aeb79 --- /dev/null +++ b/bin/Data/Animations/Nightmares/hardhit beetle.ani @@ -0,0 +1,3 @@ +1 +nightmares.png +idle;;-1;-16;-39;2;467;9;249;32;39;0;0;0;0;0;0;False;False;467;9;249;32;39;0;0;0;0;0;0;False;True diff --git a/bin/Data/Animations/Nightmares/hot head.ani b/bin/Data/Animations/Nightmares/hot head.ani new file mode 100644 index 0000000..c7eea74 --- /dev/null +++ b/bin/Data/Animations/Nightmares/hot head.ani @@ -0,0 +1,11 @@ +1 +nightmares.png +flame;;-1;-16;-32;2;133;94;288;32;32;0;0;0;0;0;0;False;False;133;128;288;32;32;0;0;0;0;0;0;False;False +splash;;0;0;0;2;167;64;291;28;16;-14;-16;0;0;0;0;False;False;150;64;308;28;12;-14;-12;0;0;0;0;False;False +red;;0;0;0;1;83;96;322;28;16;-14;-16;0;0;0;0;False;False +green;;0;0;0;1;83;128;322;28;16;-14;-16;0;0;0;0;False;False +damaged;;-1;0;0;2;133;115;342;24;16;-12;-16;0;0;0;0;False;False;133;115;342;24;16;-12;-16;0;0;0;0;False;True +fireball;;-1;-5;-10;2;133;72;338;10;10;0;0;0;0;0;0;False;False;133;72;338;10;10;0;0;0;0;0;0;False;True +fireball_splash;;0;0;0;2;117;63;322;14;13;-7;-13;0;0;0;0;False;False;117;78;321;16;14;-8;-13;0;0;0;0;False;False +face_left;;0;0;0;1;83;96;322;14;16;-7;-16;0;0;0;0;False;False +face_right;;0;0;0;1;83;110;322;14;16;-7;-16;0;0;0;0;False;False diff --git a/bin/Data/Animations/Nightmares/nightmare bat.ani b/bin/Data/Animations/Nightmares/nightmare bat.ani new file mode 100644 index 0000000..81764a3 --- /dev/null +++ b/bin/Data/Animations/Nightmares/nightmare bat.ani @@ -0,0 +1,5 @@ +1 +nightmares.png +idle;;0;0;0;1;83;461;176;10;10;-5;-5;0;0;0;0;False;False +flame;;0;0;0;1;83;459;188;14;16;-7;-8;0;0;0;0;False;False +bat;;-1;0;0;2;133;458;206;16;12;-8;-6;0;0;0;0;False;False;133;461;220;10;14;-5;-6;0;0;0;0;False;False diff --git a/bin/Data/Animations/Nightmares/nightmare eye.ani b/bin/Data/Animations/Nightmares/nightmare eye.ani new file mode 100644 index 0000000..474e40c --- /dev/null +++ b/bin/Data/Animations/Nightmares/nightmare eye.ani @@ -0,0 +1,11 @@ +1 +nightmares.png +idle;;-1;0;0;2;267;90;18;44;32;-22;-32;0;0;0;0;False;False;267;88;52;48;30;-24;-30;0;0;0;0;False;False +split_0;;0;0;0;1;83;152;5;48;29;-24;-29;0;0;0;0;False;False +split_1;;0;0;0;1;83;148;36;56;29;-28;-29;0;0;0;0;False;False +split_2;;0;0;0;1;83;144;67;64;29;-32;-29;0;0;0;0;False;False +half_floor;;0;0;0;1;83;214;51;32;29;-16;-29;0;0;0;0;False;False +half_jump;;0;0;0;1;83;216;18;28;31;-14;-31;0;0;0;0;False;False +split_3;;0;0;0;1;83;144;98;64;29;-32;-29;0;0;0;0;False;False +left;;0;0;0;1;83;144;98;32;29;-16;-29;0;0;0;0;False;False +right;;0;0;0;1;83;176;98;32;29;-16;-29;0;0;0;0;False;False diff --git a/bin/Data/Animations/Nightmares/nightmare final.ani b/bin/Data/Animations/Nightmares/nightmare final.ani new file mode 100644 index 0000000..a3d2a37 --- /dev/null +++ b/bin/Data/Animations/Nightmares/nightmare final.ani @@ -0,0 +1,4 @@ +1 +nightmares.png +eye_open;;0;0;0;3;267;532;282;14;3;-7;0;0;0;0;0;False;False;267;517;279;14;8;-7;-3;0;0;0;0;False;False;267;502;276;14;12;-7;-6;0;0;0;0;False;False +eye_close;;0;0;0;2;267;517;279;14;8;-7;-3;0;0;0;0;False;False;267;532;282;14;3;-7;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Nightmares/nightmare fireball.ani b/bin/Data/Animations/Nightmares/nightmare fireball.ani new file mode 100644 index 0000000..65247f0 --- /dev/null +++ b/bin/Data/Animations/Nightmares/nightmare fireball.ani @@ -0,0 +1,6 @@ +1 +nightmares.png +idle_0;;-1;0;0;2;133;307;162;10;10;-5;-5;0;0;0;0;False;False;133;307;162;10;10;-5;-5;0;0;0;0;False;True +idle_1;;0;0;0;1;83;306;148;12;12;-6;-6;0;0;0;0;False;False +idle_2;;0;0;0;1;83;304;130;16;16;-8;-8;0;0;0;0;False;False +idle_3;;0;0;0;2;133;305;174;14;14;-7;-7;0;0;0;0;False;False;133;304;190;16;16;-8;-8;0;0;0;0;False;False diff --git a/bin/Data/Animations/Nightmares/nightmare ganon weapon.ani b/bin/Data/Animations/Nightmares/nightmare ganon weapon.ani new file mode 100644 index 0000000..8d0b110 --- /dev/null +++ b/bin/Data/Animations/Nightmares/nightmare ganon weapon.ani @@ -0,0 +1,12 @@ +1 +nightmares.png +ganon_-1;;0;0;0;1;83;583;122;44;44;-15;-33;0;0;0;0;False;True +ganon_1;;0;0;0;1;83;583;122;44;44;-29;-33;0;0;0;0;False;False +ganon_swing_-1;;-1;0;0;4;133;539;124;42;42;-10;-47;0;0;0;0;False;False;133;499;208;56;12;-19;-32;0;0;0;0;False;False;133;539;124;42;42;-10;-47;0;0;0;0;False;True;133;481;173;12;56;3;-54;0;0;0;0;False;False +ganon_swing_1;;-1;0;0;4;133;539;124;42;42;-32;-47;0;0;0;0;False;True;133;499;208;56;12;-37;-32;0;0;0;0;False;False;133;539;124;42;42;-32;-47;0;0;0;0;False;False;133;481;173;12;56;-15;-54;0;0;0;0;False;False +ganon_swing_up_-1;;-1;0;0;4;133;514;180;26;12;-16;-34;0;0;0;0;False;False;133;511;194;32;12;-19;-34;0;0;0;0;False;False;133;499;208;56;12;-31;-34;0;0;0;0;False;False;133;511;194;32;12;-19;-34;0;0;0;0;False;False +ganon_swing_up_1;;-1;0;0;4;133;514;180;26;12;-10;-34;0;0;0;0;False;False;133;511;194;32;12;-13;-34;0;0;0;0;False;False;133;499;208;56;12;-25;-34;0;0;0;0;False;False;133;511;194;32;12;-13;-34;0;0;0;0;False;False +throw_-1;;-1;0;0;4;133;539;124;42;42;-21;-21;31;1;10;10;False;True;133;499;208;56;12;-28;-6;46;0;9;12;False;False;133;539;124;42;42;-21;-21;31;1;10;10;False;False;133;481;173;12;56;-6;-28;0;1;12;9;False;False +throw_1;;-1;0;0;4;133;539;124;42;42;-21;-21;31;1;10;10;False;False;133;499;208;56;12;-28;-6;46;0;9;12;False;False;133;539;124;42;42;-21;-21;31;1;10;10;False;True;133;481;173;12;56;-6;-28;0;46;12;9;False;False +ganon_weapon_spawn_-1;;0;0;0;3;67;479;133;24;24;0;-36;0;0;0;0;False;True;67;505;129;32;32;-4;-40;0;0;0;0;False;True;67;539;124;42;42;-10;-46;0;0;0;0;False;True +ganon_weapon_spawn_1;;0;0;0;3;67;479;133;24;24;-24;-36;0;0;0;0;False;False;67;505;129;32;32;-28;-40;0;0;0;0;False;False;67;539;124;42;42;-32;-46;0;0;0;0;False;False diff --git a/bin/Data/Animations/Nightmares/nightmare particle.ani b/bin/Data/Animations/Nightmares/nightmare particle.ani new file mode 100644 index 0000000..48ac5d7 --- /dev/null +++ b/bin/Data/Animations/Nightmares/nightmare particle.ani @@ -0,0 +1,4 @@ +1 +nightmares.png +idle;;0;0;0;3;133;350;16;16;16;-8;-8;0;0;0;0;False;False;267;337;18;12;12;-6;-6;0;0;0;0;False;False;133;328;20;8;8;-4;-4;0;0;0;0;False;False +face_particle;;0;0;0;2;267;337;18;12;12;-6;-6;0;0;0;0;False;False;267;328;20;8;8;-4;-4;0;0;0;0;False;False diff --git a/bin/Data/Animations/Nightmares/nightmare tail.ani b/bin/Data/Animations/Nightmares/nightmare tail.ani new file mode 100644 index 0000000..96e4934 --- /dev/null +++ b/bin/Data/Animations/Nightmares/nightmare tail.ani @@ -0,0 +1,3 @@ +1 +nightmares.png +idle;;-1;0;0;4;67;64;65;16;16;0;0;0;0;0;0;False;False;67;64;24;16;16;0;0;0;0;0;0;False;False;67;65;46;14;14;1;1;0;0;0;0;False;False;67;65;4;14;14;1;1;0;0;0;0;False;False diff --git a/bin/Data/Animations/Nightmares/nightmare.ani b/bin/Data/Animations/Nightmares/nightmare.ani new file mode 100644 index 0000000..58ab25b --- /dev/null +++ b/bin/Data/Animations/Nightmares/nightmare.ani @@ -0,0 +1,53 @@ +1 +nightmares.png +spawn;;0;0;0;4;133;350;16;16;16;-8;-8;0;0;0;0;False;False;133;367;14;20;20;-10;-10;0;0;0;0;False;False;133;388;12;24;24;-12;-12;0;0;0;0;False;False;83;413;10;28;28;-14;-14;0;0;0;0;False;False +idle;;0;0;0;1;83;337;18;12;12;-6;-6;0;0;0;0;False;False +head;;0;0;0;1;83;416;56;16;16;-8;-8;0;0;0;0;False;False +wobble;;2;0;0;4;267;321;49;30;30;-15;-15;0;0;0;0;False;False;267;352;48;32;32;-16;-16;0;0;0;0;False;False;267;321;49;30;30;-15;-15;0;0;0;0;False;False;267;386;50;28;28;-14;-14;0;0;0;0;False;False +despawn;;0;0;0;6;133;413;10;28;28;-14;-14;0;0;0;0;False;False;133;388;12;24;24;-12;-12;0;0;0;0;False;False;133;367;14;20;20;-10;-10;0;0;0;0;False;False;133;350;16;16;16;-8;-8;0;0;0;0;False;False;133;337;18;12;12;-6;-6;0;0;0;0;False;False;133;328;20;8;8;-4;-4;0;0;0;0;False;False +slime_spawn;;0;0;0;3;133;328;20;8;8;-4;-4;0;0;0;0;False;False;83;337;18;12;12;-6;-6;0;0;0;0;False;False;133;350;16;16;16;-8;-8;0;0;0;0;False;False +slime_jump;;0;0;0;2;100;349;98;16;22;-8;-16;0;0;0;0;False;False;83;366;88;12;32;-6;-26;0;0;0;0;False;False +slime_land;;0;0;0;1;83;349;98;16;22;-8;-16;0;0;0;0;False;False +slime;;0;0;0;1;83;324;104;24;16;-12;-10;0;0;0;0;False;False +slime_despawn;;0;0;0;3;133;350;16;16;16;-8;-8;0;0;0;0;False;False;133;337;18;12;12;-6;-6;0;0;0;0;False;False;133;328;20;8;8;-4;-4;0;0;0;0;False;False +slime_damaged;;-1;0;0;4;33;349;98;16;22;-8;-16;0;0;0;0;False;False;33;366;88;12;32;-6;-26;0;0;0;0;False;False;33;349;98;16;22;-8;-16;0;0;0;0;False;False;33;324;104;24;16;-12;-10;0;0;0;0;False;False +man_spawn;;0;0;0;4;133;337;18;12;12;-6;-6;0;0;0;0;False;False;133;350;16;16;16;-8;-8;0;0;0;0;False;False;133;349;98;16;22;-8;-14;0;0;0;0;False;False;133;366;88;12;32;-6;-24;0;0;0;0;False;False +man_3;;-1;0;0;4;133;376;126;48;34;-24;-26;0;0;0;0;False;False;133;328;162;48;30;-24;-22;0;0;0;0;False;False;133;379;162;42;30;-21;-22;0;0;0;0;False;False;133;331;126;42;34;-21;-26;0;0;0;0;False;False +man_attack_3;;0;0;0;1;83;429;146;38;26;-19;-18;0;0;0;0;False;False +man_attack_1;;0;0;0;1;83;429;308;38;28;-19;-20;0;0;0;0;False;False +man_1;;-1;0;0;4;133;328;290;48;30;-24;-22;0;0;0;0;False;False;133;379;290;42;30;-21;-22;0;0;0;0;False;False;133;379;328;42;34;-21;-26;0;0;0;0;False;False;133;328;328;48;34;-24;-26;0;0;0;0;False;False +man_attack_0;;0;0;0;1;83;382;248;32;29;-19;-21;0;0;0;0;False;False +man_0;;-1;0;0;4;133;396;205;30;35;-17;-27;0;0;0;0;False;False;133;350;245;31;34;-18;-26;0;0;0;0;False;False;133;331;205;32;35;-19;-27;0;0;0;0;False;False;133;364;204;31;36;-18;-28;0;0;0;0;False;False +man_attack_2;;0;0;0;1;83;382;248;32;29;-13;-21;0;0;0;0;False;True +man_2;;-1;0;0;4;133;396;205;30;35;-13;-27;0;0;0;0;False;True;133;350;245;31;34;-13;-26;0;0;0;0;False;True;133;331;205;32;35;-13;-27;0;0;0;0;False;True;133;364;204;31;36;-13;-28;0;0;0;0;False;True +man_rotate;;-1;0;0;4;267;328;328;48;34;-24;-26;0;0;0;0;False;False;267;364;204;31;36;-8;-28;0;0;0;0;False;True;267;376;126;48;34;-24;-26;0;0;0;0;False;False;267;364;204;31;36;-23;-28;0;0;0;0;False;False +man_despawn;;0;0;0;5;133;366;88;12;32;-6;-24;0;0;0;0;False;False;133;349;98;16;22;-8;-14;0;0;0;0;False;False;133;350;16;16;16;-8;-8;0;0;0;0;False;False;133;337;18;12;12;-6;-6;0;0;0;0;False;False;133;328;20;8;8;-4;-4;0;0;0;0;False;False +moldorm_head_0;;0;0;0;1;83;516;36;24;28;-12;-12;0;0;0;0;False;False +moldorm_head_1;;0;0;0;1;83;480;36;28;28;-16;-12;0;0;0;0;False;False +moldorm_body;;0;0;0;1;83;464;16;16;16;-8;-8;0;0;0;0;False;False +moldorm_tail;;-1;0;0;2;83;481;16;16;16;-8;-8;0;0;0;0;False;False;133;498;17;14;14;-7;-7;0;0;0;0;False;False +moldorm_body_2;;0;0;0;1;83;449;17;14;14;-7;-7;0;0;0;0;False;False +moldorm_head_2;;0;0;0;1;83;448;36;28;24;-16;-12;0;0;0;0;False;False +moldorm_head_3;;0;0;0;1;83;480;36;28;28;-16;-16;0;0;0;0;True;False +moldorm_head_4;;0;0;0;1;83;516;36;24;28;-12;-16;0;0;0;0;True;False +moldorm_head_5;;0;0;0;1;83;480;36;28;28;-12;-16;0;0;0;0;True;True +moldorm_head_6;;0;0;0;1;83;448;36;28;24;-12;-12;0;0;0;0;False;True +moldorm_head_7;;0;0;0;1;83;480;36;28;28;-12;-12;0;0;0;0;False;True +ganon_spawn_-1;;0;0;0;5;133;337;18;12;12;-6;-6;0;0;0;0;False;False;133;350;16;16;16;-8;-8;0;0;0;0;False;False;133;349;98;16;22;-8;-14;0;0;0;0;False;False;133;424;83;24;29;-12;-21;0;0;0;0;False;False;83;453;80;32;32;-16;-24;0;0;0;0;False;False +ganon_-1;;0;0;0;1;83;453;80;32;32;-16;-24;0;0;0;0;False;False +ganon_1;;0;0;0;1;83;453;80;32;32;-16;-24;0;0;0;0;False;True +ganon_weapon_-1;;0;0;0;1;83;496;76;41;36;-25;-28;0;0;0;0;False;True +ganon_weapon_1;;0;0;0;1;83;496;76;41;36;-16;-28;0;0;0;0;False;False +ganon_weapon_spawn_-1;;0;0;0;1;83;496;76;41;36;-25;-28;0;0;0;0;False;True +ganon_weapon_spawn_1;;0;0;0;1;83;496;76;41;36;-16;-28;0;0;0;0;False;False +ganon_swing_-1;;-1;0;0;2;133;496;76;41;36;-25;-28;0;0;0;0;False;True;133;544;76;41;36;-25;-28;0;0;0;0;False;True +ganon_swing_1;;-1;0;0;2;133;496;76;41;36;-16;-28;0;0;0;0;False;False;133;544;76;41;36;-16;-28;0;0;0;0;False;False +ganon_swing_up_-1;;-1;0;0;1;83;592;72;32;40;-16;-32;0;0;0;0;False;False +ganon_swing_up_1;;-1;0;0;1;83;592;72;32;40;-16;-32;0;0;0;0;False;True +ganon_throw_-1;;0;0;0;1;83;560;35;41;29;-25;-21;0;0;0;0;False;True +ganon_throw_1;;0;0;0;1;83;560;35;41;29;-16;-21;0;0;0;0;False;False +ganon_spawn_1;;0;0;0;5;133;337;18;12;12;-6;-6;0;0;0;0;False;False;133;350;16;16;16;-8;-8;0;0;0;0;False;False;133;349;98;16;22;-8;-14;0;0;0;0;False;False;133;424;83;24;29;-12;-21;0;0;0;0;False;False;83;453;80;32;32;-16;-24;0;0;0;0;False;True +face_hidden;;0;0;0;1;83;350;16;16;16;-8;-8;0;0;0;0;False;False +final_spawn;;0;0;0;4;133;328;20;8;8;-4;-4;0;0;0;0;False;False;133;337;18;12;12;-6;-6;0;0;0;0;False;False;133;350;16;16;16;-8;-8;0;0;0;0;False;False;133;349;98;16;22;-8;-14;0;0;0;0;False;False +final;;-1;0;0;4;133;532;246;24;26;-12;-18;0;0;0;0;False;False;133;506;246;24;26;-12;-18;0;0;0;0;False;False;133;480;244;24;28;-12;-20;0;0;0;0;False;False;133;506;246;24;26;-12;-18;0;0;0;0;False;False +meldorm_spawn;;0;0;0;3;133;337;18;12;12;-6;-6;0;0;0;0;False;False;133;350;16;16;16;-8;-8;0;0;0;0;False;False;267;518;6;20;22;-10;-10;0;0;0;0;False;False diff --git a/bin/Data/Animations/Nightmares/slime eel.ani b/bin/Data/Animations/Nightmares/slime eel.ani new file mode 100644 index 0000000..c7fd764 --- /dev/null +++ b/bin/Data/Animations/Nightmares/slime eel.ani @@ -0,0 +1,8 @@ +1 +nightmares.png +attack;;0;0;0;5;633;160;240;16;10;-8;0;0;0;0;0;False;False;133;124;269;22;16;-11;0;0;0;0;0;False;False;533;96;269;26;13;-13;0;0;0;0;0;False;False;133;124;269;22;16;-11;0;0;0;0;0;False;False;133;160;240;16;10;-8;0;0;0;0;0;False;False +head_open;;0;0;0;1;83;96;258;26;24;-13;-11;0;0;0;0;False;False +head_0;;0;0;0;1;83;124;258;22;27;-11;-11;0;0;0;0;False;False +head_1;;0;0;0;1;83;148;258;25;25;-14;-11;0;0;0;0;False;False +head_2;;0;0;0;1;83;175;261;27;22;-16;-11;0;0;0;0;False;False +attack_spawn;;0;0;0;4;33;124;269;22;16;-11;0;0;0;0;0;False;False;533;96;269;26;13;-13;0;0;0;0;0;False;False;133;124;269;22;16;-11;0;0;0;0;0;False;False;133;160;240;16;10;-8;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/bomb.ani b/bin/Data/Animations/Objects/bomb.ani new file mode 100644 index 0000000..d095043 --- /dev/null +++ b/bin/Data/Animations/Objects/bomb.ani @@ -0,0 +1,5 @@ +1 +items.png +idle;;-1;0;0;1;200;8;171;8;13;-4;-13;0;0;0;0;False;False +explode;;0;-4;-13;4;167;88;168;16;16;-4;1;0;0;16;16;False;False;133;112;168;24;24;-8;-3;0;0;24;24;False;False;133;144;168;32;32;-12;-7;0;0;32;32;False;False;133;184;168;32;32;-12;-7;0;0;0;0;False;False +blink;;0;0;0;1;83;24;171;8;13;-4;-13;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/boomerang.ani b/bin/Data/Animations/Objects/boomerang.ani new file mode 100644 index 0000000..acfcd37 --- /dev/null +++ b/bin/Data/Animations/Objects/boomerang.ani @@ -0,0 +1,3 @@ +1 +items.png +run;;-1;0;0;4;67;136;125;8;12;-1;0;0;0;0;0;False;False;67;136;140;12;8;0;-1;0;0;0;0;False;False;67;136;125;8;12;5;0;0;0;0;0;False;True;67;136;140;12;8;0;5;0;0;0;0;True;False diff --git a/bin/Data/Animations/Objects/d7 tower bottom.ani b/bin/Data/Animations/Objects/d7 tower bottom.ani new file mode 100644 index 0000000..43d86da --- /dev/null +++ b/bin/Data/Animations/Objects/d7 tower bottom.ani @@ -0,0 +1,5 @@ +1 +objects animated.png +rotate;;0;0;32;13;400;16;400;80;48;0;0;0;0;0;0;False;False;400;112;400;80;48;0;0;0;0;0;0;False;False;400;16;400;80;48;0;0;0;0;0;0;False;False;400;112;400;80;48;0;0;0;0;0;0;False;False;400;16;400;80;48;0;0;0;0;0;0;False;False;400;112;400;80;48;0;0;0;0;0;0;False;False;400;16;400;80;48;0;0;0;0;0;0;False;False;400;208;400;80;48;0;0;0;0;0;0;False;False;400;304;400;80;48;0;0;0;0;0;0;False;False;400;400;400;80;48;0;0;0;0;0;0;False;False;400;16;464;80;48;0;0;0;0;0;0;False;False;400;112;464;80;48;0;0;0;0;0;0;False;False;400;208;464;80;48;0;0;0;0;0;0;False;False +idle;;0;0;32;1;400;16;400;80;48;0;0;0;0;0;0;False;False +opened;;0;0;32;1;83;208;464;80;48;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/d7 tower top 1.ani b/bin/Data/Animations/Objects/d7 tower top 1.ani new file mode 100644 index 0000000..7678964 --- /dev/null +++ b/bin/Data/Animations/Objects/d7 tower top 1.ani @@ -0,0 +1,4 @@ +1 +objects animated.png +rotate;;6;0;-96;2;400;496;320;80;96;0;0;0;0;0;0;False;False;400;496;424;80;96;0;0;0;0;0;0;False;False +idle;;0;0;-96;1;400;496;320;80;96;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/d7 tower top 2.ani b/bin/Data/Animations/Objects/d7 tower top 2.ani new file mode 100644 index 0000000..e470304 --- /dev/null +++ b/bin/Data/Animations/Objects/d7 tower top 2.ani @@ -0,0 +1,3 @@ +1 +objects animated.png +idle;;0;0;-64;1;400;512;256;48;64;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/d7 tower.ani b/bin/Data/Animations/Objects/d7 tower.ani new file mode 100644 index 0000000..bec2200 --- /dev/null +++ b/bin/Data/Animations/Objects/d7 tower.ani @@ -0,0 +1,4 @@ +1 +objects animated.png +rotate;;0;0;0;14;400;16;256;80;32;0;0;0;0;0;0;False;False;400;112;256;80;32;0;0;0;0;0;0;False;False;400;208;256;80;32;0;0;0;0;0;0;False;False;400;304;256;80;32;0;0;0;0;0;0;False;False;400;400;256;82;32;0;0;0;0;0;0;False;False;400;16;304;86;32;0;0;0;0;0;0;False;False;400;104;304;96;32;-8;0;0;0;0;0;False;False;400;202;304;86;32;-6;0;0;0;0;0;False;False;400;400;304;80;32;0;0;0;0;0;0;False;False;400;16;352;80;32;0;0;0;0;0;0;False;False;400;112;352;80;32;0;0;0;0;0;0;False;False;400;208;352;80;32;0;0;0;0;0;0;False;False;167;16;256;80;32;0;0;0;0;0;0;False;False;83;304;352;80;32;0;0;0;0;0;0;False;False +idle;;0;0;0;10;17;304;352;80;32;0;0;0;0;0;0;False;False;250;16;256;80;32;0;0;0;0;0;0;False;False;250;304;352;80;32;0;0;0;0;0;0;False;False;250;16;256;80;32;0;0;0;0;0;0;False;False;250;304;352;80;32;0;0;0;0;0;0;False;False;250;16;256;80;32;0;0;0;0;0;0;False;False;250;304;352;80;32;0;0;0;0;0;0;False;False;250;16;256;80;32;0;0;0;0;0;0;False;False;3000;304;352;80;32;0;0;0;0;0;0;False;False;133;16;256;80;32;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/dOneWay.ani b/bin/Data/Animations/Objects/dOneWay.ani new file mode 100644 index 0000000..bad4929 --- /dev/null +++ b/bin/Data/Animations/Objects/dOneWay.ani @@ -0,0 +1,6 @@ +1 +objects animated.png +idle;;0;0;0;1;200;128;64;16;16;0;0;0;0;0;0;False;False +rotate;;0;0;0;8;67;144;64;16;16;0;0;0;0;0;0;False;False;67;160;64;16;16;0;0;0;0;0;0;False;False;67;176;64;16;16;0;0;0;0;0;0;False;False;167;192;64;16;16;0;0;0;0;0;0;False;False;317;192;64;16;16;0;0;0;0;0;0;False;False;67;208;64;16;16;0;0;0;0;0;0;False;False;67;175;64;16;16;0;0;0;0;0;0;False;False;200;128;64;16;16;0;0;0;0;0;0;False;False +rotate2;;0;0;0;8;67;192;64;16;16;0;0;0;0;0;0;True;False;67;176;64;16;16;0;0;0;0;0;0;True;False;67;160;64;16;16;0;0;0;0;0;0;True;False;167;144;64;16;16;0;0;0;0;0;0;True;False;317;128;64;16;16;0;0;0;0;0;0;True;False;67;176;64;16;16;0;0;0;0;0;0;True;False;67;208;64;16;16;0;0;0;0;0;0;True;False;200;192;64;16;16;0;0;0;0;0;0;True;False +idle2;;0;0;0;1;200;192;64;16;16;0;0;0;0;0;0;True;False diff --git a/bin/Data/Animations/Objects/dTeleporter.ani b/bin/Data/Animations/Objects/dTeleporter.ani new file mode 100644 index 0000000..2d4e6b5 --- /dev/null +++ b/bin/Data/Animations/Objects/dTeleporter.ani @@ -0,0 +1,3 @@ +1 +objects animated.png +idle;;-1;-5;-5;2;100;65;113;10;10;0;0;0;0;0;0;False;False;100;65;113;10;10;0;0;0;0;0;0;False;True diff --git a/bin/Data/Animations/Objects/dungeon color switch.ani b/bin/Data/Animations/Objects/dungeon color switch.ani new file mode 100644 index 0000000..f6366eb --- /dev/null +++ b/bin/Data/Animations/Objects/dungeon color switch.ani @@ -0,0 +1,4 @@ +1 +objects.png +idle;;0;0;0;1;83;544;34;16;14;-8;-14;0;0;0;0;False;False +move;;0;0;0;3;83;562;33;16;15;-8;-15;0;0;0;0;False;False;83;580;32;16;16;-8;-16;0;0;0;0;False;False;83;562;33;16;15;-8;-15;0;0;0;0;False;True diff --git a/bin/Data/Animations/Objects/explosion.ani b/bin/Data/Animations/Objects/explosion.ani new file mode 100644 index 0000000..460cc27 --- /dev/null +++ b/bin/Data/Animations/Objects/explosion.ani @@ -0,0 +1,3 @@ +1 +items.png +idle;;0;0;0;3;133;112;168;24;24;-12;-12;0;0;0;0;False;False;133;144;168;32;32;-16;-16;0;0;32;32;False;False;133;184;169;32;31;-16;-15;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/holeTeleporter.ani b/bin/Data/Animations/Objects/holeTeleporter.ani new file mode 100644 index 0000000..9ef3494 --- /dev/null +++ b/bin/Data/Animations/Objects/holeTeleporter.ani @@ -0,0 +1,3 @@ +1 +objects animated.png +idle;;-1;0;0;4;67;329;32;14;14;-7;-7;0;0;0;0;False;False;67;345;32;14;14;-7;-7;0;0;0;0;False;False;67;325;47;18;18;-9;-9;0;0;0;0;False;False;67;345;47;18;18;-9;-9;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/ice block.ani b/bin/Data/Animations/Objects/ice block.ani new file mode 100644 index 0000000..3827802 --- /dev/null +++ b/bin/Data/Animations/Objects/ice block.ani @@ -0,0 +1,3 @@ +1 +enemies.png +idle;;-1;0;0;4;183;8;448;16;16;0;0;0;0;0;0;False;False;183;24;448;16;16;0;0;0;0;0;0;False;False;183;40;448;16;16;0;0;0;0;0;0;False;False;183;56;448;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/lamp_floor.ani b/bin/Data/Animations/Objects/lamp_floor.ani new file mode 100644 index 0000000..4302bcb --- /dev/null +++ b/bin/Data/Animations/Objects/lamp_floor.ani @@ -0,0 +1,4 @@ +1 +objects animated.png +idle;;-1;0;0;6;533;16;16;16;16;0;0;0;0;0;0;False;False;183;0;16;16;16;0;0;0;0;0;0;False;False;183;32;16;16;16;0;0;0;0;0;0;False;False;183;48;16;16;16;0;0;0;0;0;0;False;False;183;32;16;16;16;0;0;0;0;0;0;False;False;183;0;16;16;16;0;0;0;0;0;0;False;False +dead;;-1;0;0;1;200;64;16;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/lamp_torch.ani b/bin/Data/Animations/Objects/lamp_torch.ani new file mode 100644 index 0000000..66c5cbe --- /dev/null +++ b/bin/Data/Animations/Objects/lamp_torch.ani @@ -0,0 +1,3 @@ +1 +objects animated.png +IDLE;;-1;0;0;6;150;0;64;16;16;0;0;0;0;0;0;False;False;150;16;64;16;16;0;0;0;0;0;0;False;False;150;32;64;16;16;0;0;0;0;0;0;False;False;150;48;64;16;16;0;0;0;0;0;0;False;False;150;32;64;16;16;0;0;0;0;0;0;False;False;150;16;64;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/lamp_torch_blue.ani b/bin/Data/Animations/Objects/lamp_torch_blue.ani new file mode 100644 index 0000000..959b519 --- /dev/null +++ b/bin/Data/Animations/Objects/lamp_torch_blue.ani @@ -0,0 +1,3 @@ +1 +objects animated.png +idle;;-1;0;0;6;267;64;48;16;16;0;0;0;0;0;0;False;False;267;80;48;16;16;0;0;0;0;0;0;False;False;267;96;48;16;16;0;0;0;0;0;0;False;False;267;112;48;16;16;0;0;0;0;0;0;False;False;133;96;48;16;16;0;0;0;0;0;0;False;False;133;80;48;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/lamp_wall.ani b/bin/Data/Animations/Objects/lamp_wall.ani new file mode 100644 index 0000000..cb90b1d --- /dev/null +++ b/bin/Data/Animations/Objects/lamp_wall.ani @@ -0,0 +1,4 @@ +1 +objects animated.png +idle;;-1;0;0;6;167;0;81;16;15;0;0;0;0;0;0;False;False;167;16;81;16;15;0;0;0;0;0;0;False;False;167;32;81;16;15;0;0;0;0;0;0;False;False;500;48;81;16;15;0;0;0;0;0;0;False;False;167;32;81;16;15;0;0;0;0;0;0;False;False;167;16;81;16;15;0;0;0;0;0;0;False;False +dead;;-1;0;0;1;200;64;16;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/lamp_wall_1.ani b/bin/Data/Animations/Objects/lamp_wall_1.ani new file mode 100644 index 0000000..3039772 --- /dev/null +++ b/bin/Data/Animations/Objects/lamp_wall_1.ani @@ -0,0 +1,4 @@ +1 +objects animated.png +idle;;-1;0;0;6;167;0;96;16;16;0;0;0;0;0;0;False;False;167;16;96;16;16;0;0;0;0;0;0;False;False;167;32;96;16;16;0;0;0;0;0;0;False;False;500;48;96;16;16;0;0;0;0;0;0;False;False;167;32;96;16;16;0;0;0;0;0;0;False;False;167;16;96;16;16;0;0;0;0;0;0;False;False +dead;;-1;0;0;1;200;64;16;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/lamp_wall_2.ani b/bin/Data/Animations/Objects/lamp_wall_2.ani new file mode 100644 index 0000000..c52112c --- /dev/null +++ b/bin/Data/Animations/Objects/lamp_wall_2.ani @@ -0,0 +1,3 @@ +1 +objects animated.png +idle;;-1;0;0;6;167;0;112;16;16;0;0;0;0;0;0;False;False;167;16;112;16;16;0;0;0;0;0;0;False;False;167;32;112;16;16;0;0;0;0;0;0;False;False;500;48;112;16;16;0;0;0;0;0;0;False;False;167;32;112;16;16;0;0;0;0;0;0;False;False;167;16;112;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/lava.ani b/bin/Data/Animations/Objects/lava.ani new file mode 100644 index 0000000..2744b94 --- /dev/null +++ b/bin/Data/Animations/Objects/lava.ani @@ -0,0 +1,3 @@ +1 +objects.png +idle;;-1;0;0;6;533;194;235;16;16;0;0;0;0;0;0;False;False;183;194;267;16;16;0;0;0;0;0;0;False;False;167;194;251;16;16;0;0;0;0;0;0;False;False;183;202;267;16;16;0;0;0;0;0;0;False;False;183;194;251;16;16;0;0;0;0;0;0;False;False;167;194;267;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/lava_2d.ani b/bin/Data/Animations/Objects/lava_2d.ani new file mode 100644 index 0000000..657e061 --- /dev/null +++ b/bin/Data/Animations/Objects/lava_2d.ani @@ -0,0 +1,3 @@ +1 +objects animated.png +idle;;0;0;0;4;183;96;16;16;16;0;0;0;0;0;0;False;False;183;112;16;16;16;0;0;0;0;0;0;False;False;183;128;16;16;16;0;0;0;0;0;0;False;False;183;144;16;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/raft.ani b/bin/Data/Animations/Objects/raft.ani new file mode 100644 index 0000000..b0b61c3 --- /dev/null +++ b/bin/Data/Animations/Objects/raft.ani @@ -0,0 +1,4 @@ +1 +objects.png +idle;;0;0;0;1;83;259;202;16;15;0;0;0;0;0;0;False;False +water;;-1;0;0;2;267;259;202;16;15;0;0;0;0;0;0;False;False;267;259;218;16;15;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/shell_mansion_bar.ani b/bin/Data/Animations/Objects/shell_mansion_bar.ani new file mode 100644 index 0000000..d643d77 --- /dev/null +++ b/bin/Data/Animations/Objects/shell_mansion_bar.ani @@ -0,0 +1,3 @@ +1 +objects animated.png +idle;;-1;0;0;4;100;216;217;16;16;0;0;0;0;0;0;False;False;83;216;200;16;16;0;0;0;0;0;0;False;False;83;216;183;16;16;0;0;0;0;0;0;False;False;83;216;200;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/spear.ani b/bin/Data/Animations/Objects/spear.ani new file mode 100644 index 0000000..53f3e2a --- /dev/null +++ b/bin/Data/Animations/Objects/spear.ani @@ -0,0 +1,8 @@ +1 +enemies.png +0;;-1;0;0;1;200;256;104;16;8;-8;-4;0;0;0;0;False;False +1;;-1;0;0;1;200;272;96;8;16;-4;-8;0;0;0;0;False;False +2;;-1;0;0;1;200;256;104;16;8;-8;-4;0;0;0;0;False;True +3;;-1;0;0;1;200;272;96;8;16;-4;-8;0;0;0;0;True;False +rotate;;-1;0;0;4;100;256;104;16;8;-8;-4;0;0;0;0;False;False;100;272;96;8;16;-4;-8;0;0;0;0;False;False;100;256;104;16;8;-8;-4;0;0;0;0;False;True;100;272;96;8;16;-4;-8;0;0;0;0;True;False +rotatel;;-1;0;0;4;100;256;104;16;8;-8;-4;0;0;0;0;False;False;100;272;96;8;16;-4;-8;0;0;0;0;True;False;100;256;104;16;8;-8;-4;0;0;0;0;False;True;100;272;96;8;16;-4;-8;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/spikes.ani b/bin/Data/Animations/Objects/spikes.ani new file mode 100644 index 0000000..cf52d72 --- /dev/null +++ b/bin/Data/Animations/Objects/spikes.ani @@ -0,0 +1,3 @@ +1 +objects animated.png +idle;;-1;0;0;6;200;66;144;16;16;0;0;0;0;0;0;False;False;200;82;144;16;16;0;0;0;0;0;0;False;False;200;98;144;16;16;0;0;0;0;0;0;False;False;533;114;144;16;16;0;0;0;0;0;0;False;False;200;98;144;16;16;0;0;0;0;0;0;False;False;200;82;144;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/sword spawn.ani b/bin/Data/Animations/Objects/sword spawn.ani new file mode 100644 index 0000000..e94aa20 --- /dev/null +++ b/bin/Data/Animations/Objects/sword spawn.ani @@ -0,0 +1,3 @@ +1 +objects animated.png +idle;;0;0;0;6;3000;142;189;16;16;-8;-8;0;0;0;0;False;False;3000;160;179;26;26;-13;-13;0;0;0;0;False;False;267;188;177;24;28;-12;-14;0;0;0;0;False;False;267;142;208;24;30;-12;-15;0;0;0;0;False;False;267;168;208;22;32;-11;-16;0;0;0;0;False;False;200;192;208;16;32;-8;-16;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/sword.ani b/bin/Data/Animations/Objects/sword.ani new file mode 100644 index 0000000..cb7b6e5 --- /dev/null +++ b/bin/Data/Animations/Objects/sword.ani @@ -0,0 +1,22 @@ +1 +link0.png +attack_0;;0;0;0;3;50;192;293;6;15;0;-15;0;0;0;0;False;False;50;159;296;15;15;-13;-12;5;5;10;10;False;False;83;125;317;15;6;-19;9;1;1;14;4;False;False +attack_2;;0;0;0;3;50;192;293;6;15;8;-15;0;0;0;0;False;False;50;159;296;15;15;12;-12;5;5;10;10;False;True;83;125;317;15;6;18;9;1;1;14;4;False;True +attack_1;;0;0;0;3;50;125;317;15;6;14;4;0;0;0;0;False;True;50;159;296;15;15;11;-12;5;5;10;10;False;True;83;192;293;6;15;-1;-17;1;1;4;14;False;False +attack_3;;0;0;0;3;50;125;317;15;6;-14;8;0;0;0;0;False;False;50;159;296;15;15;-12;13;5;5;10;10;True;False;83;192;293;6;15;8;18;1;1;4;14;True;False +swing_0;;0;0;0;9;50;159;296;15;15;-12;15;3;3;10;10;True;False;50;192;293;6;15;9;18;1;1;4;12;True;False;33;159;296;15;15;15;13;3;3;10;10;True;True;50;125;317;15;6;16;9;1;1;12;4;False;True;50;159;296;15;15;11;-12;3;3;10;10;False;True;50;192;293;6;15;-1;-15;1;1;4;12;False;False;50;159;296;15;15;-13;-12;3;3;10;10;False;False;33;125;317;15;6;-16;9;1;1;12;4;False;False;17;125;317;15;6;-16;9;1;1;12;4;False;False +swing_1;;0;0;0;9;50;159;296;15;15;-13;-12;3;3;10;10;False;False;50;125;317;15;6;-16;9;1;1;12;4;False;False;50;159;296;15;15;-12;15;3;3;10;10;True;False;50;192;293;6;15;9;18;1;1;4;12;True;False;50;159;296;15;15;15;13;3;3;10;10;True;True;50;125;317;15;6;16;9;1;1;12;4;False;True;50;159;296;15;15;11;-12;3;3;10;10;False;True;33;192;293;6;15;-1;-15;1;1;4;12;False;False;17;192;293;6;15;-1;-15;1;1;4;12;False;False +swing_2;;0;0;0;9;50;159;296;15;15;11;-12;3;3;10;10;False;True;50;192;293;6;15;-1;-15;1;1;4;12;False;False;50;159;296;15;15;-13;-12;3;3;10;10;False;False;50;125;317;15;6;-16;9;1;1;12;4;False;False;50;159;296;15;15;-12;15;3;3;10;10;True;False;50;192;293;6;15;9;18;1;1;4;12;True;False;50;159;296;15;15;15;13;3;3;10;10;True;True;33;125;317;15;6;16;9;1;1;12;4;False;True;17;125;317;15;6;16;9;1;1;12;4;False;True +swing_3;;0;0;0;9;50;159;296;15;15;15;13;3;3;10;10;True;True;50;125;317;15;6;16;9;1;1;12;4;False;True;50;159;296;15;15;11;-12;3;3;10;10;False;True;50;192;293;6;15;-1;-15;1;1;4;12;False;False;50;159;296;15;15;-13;-12;3;3;10;10;False;False;50;125;317;15;6;-16;9;1;1;12;4;False;False;50;159;296;15;15;-12;15;3;3;10;10;True;False;33;192;293;6;15;9;18;1;1;4;12;True;False;17;192;293;6;15;9;18;1;1;4;12;True;False +stand_0;;0;0;0;1;83;125;317;15;6;-11;9;1;1;9;4;False;False +stand_1;;0;0;0;1;83;192;293;6;15;0;-10;1;1;4;9;False;False +stand_2;;0;0;0;1;83;125;317;15;6;10;9;1;1;9;4;False;True +stand_3;;0;0;0;1;83;192;293;6;15;9;13;1;1;4;9;True;False +poke_0;;0;-16;9;1;183;125;317;15;6;0;0;3;1;8;4;False;False +poke_1;;0;0;-15;1;183;192;293;6;15;0;0;1;4;4;7;False;False +poke_2;;0;16;9;1;183;125;317;15;6;0;0;3;1;8;4;False;True +poke_3;;0;9;18;1;183;192;293;6;15;0;0;1;3;4;8;True;False +rod_0;;0;0;0;2;50;32;161;6;15;0;-13;0;0;0;0;False;False;200;17;165;14;6;-14;9;0;0;0;0;False;False +rod_1;;0;0;0;2;50;17;165;14;6;13;4;0;0;0;0;False;True;200;32;161;6;15;0;-13;0;0;0;0;False;False +rod_2;;0;0;0;2;50;32;161;6;15;7;-12;0;0;0;0;False;True;200;17;165;14;6;14;9;0;0;0;0;False;True +rod_3;;0;0;0;2;50;17;165;14;6;-12;8;0;0;0;0;False;False;200;32;161;6;15;7;16;0;0;0;0;True;False diff --git a/bin/Data/Animations/Objects/torch_d4.ani b/bin/Data/Animations/Objects/torch_d4.ani new file mode 100644 index 0000000..383d493 --- /dev/null +++ b/bin/Data/Animations/Objects/torch_d4.ani @@ -0,0 +1,3 @@ +1 +objects animated.png +idle;;-1;0;0;6;167;368;113;16;15;0;0;0;0;0;0;False;False;167;384;113;16;15;0;0;0;0;0;0;False;False;167;400;113;16;15;0;0;0;0;0;0;False;False;500;416;113;16;15;0;0;0;0;0;0;False;False;167;400;113;16;15;0;0;0;0;0;0;False;False;167;384;113;16;15;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/torch_d4_d4.ani b/bin/Data/Animations/Objects/torch_d4_d4.ani new file mode 100644 index 0000000..8a44330 --- /dev/null +++ b/bin/Data/Animations/Objects/torch_d4_d4.ani @@ -0,0 +1,3 @@ +1 +objects animated.png +idle;;-1;0;0;4;350;368;128;16;16;0;0;0;0;0;0;False;False;350;384;128;16;16;0;0;0;0;0;0;False;False;350;400;128;16;16;0;0;0;0;0;0;False;False;350;416;128;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/torch_d6.ani b/bin/Data/Animations/Objects/torch_d6.ani new file mode 100644 index 0000000..ea70329 --- /dev/null +++ b/bin/Data/Animations/Objects/torch_d6.ani @@ -0,0 +1,3 @@ +1 +objects animated.png +idle;;-1;0;0;4;350;0;48;16;16;0;0;0;0;0;0;False;False;350;16;48;16;16;0;0;0;0;0;0;False;False;350;32;48;16;16;0;0;0;0;0;0;False;False;350;48;48;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/torch_d8.ani b/bin/Data/Animations/Objects/torch_d8.ani new file mode 100644 index 0000000..f891a06 --- /dev/null +++ b/bin/Data/Animations/Objects/torch_d8.ani @@ -0,0 +1,3 @@ +1 +objects animated.png +idle;;-1;0;0;6;167;0;128;16;16;0;0;0;0;0;0;False;False;167;16;128;16;16;0;0;0;0;0;0;False;False;167;32;128;16;16;0;0;0;0;0;0;False;False;500;48;128;16;16;0;0;0;0;0;0;False;False;167;32;128;16;16;0;0;0;0;0;0;False;False;167;16;128;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Objects/weatherBird.ani b/bin/Data/Animations/Objects/weatherBird.ani new file mode 100644 index 0000000..d21e663 --- /dev/null +++ b/bin/Data/Animations/Objects/weatherBird.ani @@ -0,0 +1,3 @@ +1 +objects animated.png +IDLE;;-1;0;0;4;150;32;208;16;32;0;0;0;0;0;0;False;False;150;48;208;16;32;0;0;0;0;0;0;False;False;150;64;208;16;32;0;0;0;0;0;0;False;False;150;80;208;16;32;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Particles/big_water_splash.ani b/bin/Data/Animations/Particles/big_water_splash.ani new file mode 100644 index 0000000..b51c178 --- /dev/null +++ b/bin/Data/Animations/Particles/big_water_splash.ani @@ -0,0 +1,6 @@ +1 +midboss.png +run_1;;0;0;0;2;100;332;123;38;14;-19;0;0;0;0;0;False;False;100;324;140;54;14;-27;7;0;0;0;0;False;False +run_3;;0;0;-14;2;100;332;123;38;14;-19;0;0;0;0;0;True;False;100;324;140;54;14;-27;-7;0;0;0;0;True;False +run_2;;0;-14;0;2;100;397;121;14;38;0;-19;0;0;0;0;False;False;100;380;113;14;54;-7;-27;0;0;0;0;False;False +run_0;;0;0;0;2;100;397;121;14;38;0;-19;0;0;0;0;False;True;100;380;113;14;54;7;-27;0;0;0;0;False;True diff --git a/bin/Data/Animations/Particles/buttonOrder.ani b/bin/Data/Animations/Particles/buttonOrder.ani new file mode 100644 index 0000000..edb7350 --- /dev/null +++ b/bin/Data/Animations/Particles/buttonOrder.ani @@ -0,0 +1,3 @@ +1 +items.png +idle;;-1;0;0;3;67;66;258;12;12;-6;-6;0;0;0;0;False;False;133;80;256;16;16;-8;-8;0;0;0;0;False;False;67;85;261;6;6;-8;-8;0;0;0;0;False;False diff --git a/bin/Data/Animations/Particles/despawn.ani b/bin/Data/Animations/Particles/despawn.ani new file mode 100644 index 0000000..9835c01 --- /dev/null +++ b/bin/Data/Animations/Particles/despawn.ani @@ -0,0 +1,3 @@ +1 +items.png +run;;0;-8;-8;2;133;66;258;12;12;2;2;0;0;0;0;False;False;133;80;256;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Particles/despawnParticle.ani b/bin/Data/Animations/Particles/despawnParticle.ani new file mode 100644 index 0000000..2dd3736 --- /dev/null +++ b/bin/Data/Animations/Particles/despawnParticle.ani @@ -0,0 +1,4 @@ +1 +items.png +idle;;0;0;0;2;117;66;258;12;12;-6;-6;0;0;0;0;False;False;133;80;256;16;16;-8;-8;0;0;0;0;False;False +orange;;0;0;0;2;67;114;226;12;12;-6;-6;0;0;0;0;False;False;133;128;224;16;16;-8;-8;0;0;0;0;False;False diff --git a/bin/Data/Animations/Particles/explosion.ani b/bin/Data/Animations/Particles/explosion.ani new file mode 100644 index 0000000..26fc1e3 --- /dev/null +++ b/bin/Data/Animations/Particles/explosion.ani @@ -0,0 +1,3 @@ +1 +items.png +RUN;;0;0;0;5;66;32;208;32;32;0;0;0;0;0;0;False;False;66;64;208;32;32;0;0;0;0;0;0;False;False;66;96;208;32;32;0;0;0;0;0;0;False;False;66;66;226;12;12;10;10;0;0;0;0;False;False;66;128;224;16;16;8;8;0;0;0;0;False;False diff --git a/bin/Data/Animations/Particles/explosion0.ani b/bin/Data/Animations/Particles/explosion0.ani new file mode 100644 index 0000000..77a5ad9 --- /dev/null +++ b/bin/Data/Animations/Particles/explosion0.ani @@ -0,0 +1,4 @@ +1 +items.png +run;;0;0;0;7;33;164;212;24;24;0;0;0;0;0;0;False;False;67;196;212;24;24;0;0;0;0;0;0;False;False;17;164;212;24;24;0;0;0;0;0;0;False;False;50;228;212;24;24;0;0;0;0;0;0;False;False;83;260;212;24;24;0;0;0;0;0;0;False;False;133;298;218;12;12;6;6;0;0;0;0;False;False;117;328;216;16;16;4;4;0;0;0;0;False;False +runc;;0;-12;-12;7;33;164;212;24;24;0;0;0;0;0;0;False;False;67;196;212;24;24;0;0;0;0;0;0;False;False;17;164;212;24;24;0;0;0;0;0;0;False;False;50;228;212;24;24;0;0;0;0;0;0;False;False;83;260;212;24;24;0;0;0;0;0;0;False;False;133;298;218;12;12;6;6;0;0;0;0;False;False;117;328;216;16;16;4;4;0;0;0;0;False;False diff --git a/bin/Data/Animations/Particles/explosionBomb.ani b/bin/Data/Animations/Particles/explosionBomb.ani new file mode 100644 index 0000000..a9d840d --- /dev/null +++ b/bin/Data/Animations/Particles/explosionBomb.ani @@ -0,0 +1,4 @@ +1 +items.png +run;;0;0;0;4;133;88;168;16;16;-8;-8;0;0;16;16;False;False;133;112;168;24;24;-12;-12;0;0;24;24;False;False;133;144;168;32;32;-16;-16;0;0;32;32;False;False;133;184;168;32;32;-16;-16;0;0;0;0;False;False +run2;;0;0;0;3;133;112;168;24;24;-12;-12;0;0;0;0;False;False;133;144;168;32;32;-16;-16;0;0;0;0;False;False;133;184;169;32;31;-16;-15;0;0;0;0;False;False diff --git a/bin/Data/Animations/Particles/explosionRaccoon.ani b/bin/Data/Animations/Particles/explosionRaccoon.ani new file mode 100644 index 0000000..43a6545 --- /dev/null +++ b/bin/Data/Animations/Particles/explosionRaccoon.ani @@ -0,0 +1,3 @@ +1 +items.png +run;;0;0;0;4;133;88;168;16;16;-8;-8;0;0;0;0;False;False;133;112;168;24;24;-12;-12;0;0;0;0;False;False;133;144;168;32;32;-16;-16;0;0;0;0;False;False;133;184;169;32;31;-16;-16;0;0;0;0;False;False diff --git a/bin/Data/Animations/Particles/fall.ani b/bin/Data/Animations/Particles/fall.ani new file mode 100644 index 0000000..3d5211b --- /dev/null +++ b/bin/Data/Animations/Particles/fall.ani @@ -0,0 +1,3 @@ +1 +enemies.png +IDLE;;0;0;0;3;200;81;1;10;10;0;0;0;0;0;0;False;False;200;92;1;6;6;2;2;0;0;0;0;False;False;200;99;1;4;4;3;3;0;0;0;0;False;False diff --git a/bin/Data/Animations/Particles/fishingSplash.ani b/bin/Data/Animations/Particles/fishingSplash.ani new file mode 100644 index 0000000..26a356d --- /dev/null +++ b/bin/Data/Animations/Particles/fishingSplash.ani @@ -0,0 +1,3 @@ +1 +objects animated.png +idle;;0;0;-15;2;117;295;77;16;17;-8;0;0;0;0;0;False;False;117;294;95;20;17;-10;-6;0;0;0;0;False;False diff --git a/bin/Data/Animations/Particles/flame.ani b/bin/Data/Animations/Particles/flame.ani new file mode 100644 index 0000000..8da7ead --- /dev/null +++ b/bin/Data/Animations/Particles/flame.ani @@ -0,0 +1,3 @@ +1 +enemies.png +idle;;6;-7;-8;2;133;113;16;14;16;0;0;0;0;0;0;False;False;133;129;16;14;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Particles/ice block despawn.ani b/bin/Data/Animations/Particles/ice block despawn.ani new file mode 100644 index 0000000..2559bc0 --- /dev/null +++ b/bin/Data/Animations/Particles/ice block despawn.ani @@ -0,0 +1,3 @@ +1 +items.png +run;;0;0;0;2;133;40;168;16;16;-8;-8;0;0;0;0;False;False;133;43;155;10;10;-5;-5;0;0;0;0;False;False diff --git a/bin/Data/Animations/Particles/pieceOfPowerExplosion.ani b/bin/Data/Animations/Particles/pieceOfPowerExplosion.ani new file mode 100644 index 0000000..250121e --- /dev/null +++ b/bin/Data/Animations/Particles/pieceOfPowerExplosion.ani @@ -0,0 +1,3 @@ +1 +items.png +run;;0;0;0;5;67;32;208;32;32;-16;-16;0;0;0;0;False;False;67;144;168;32;32;-16;-16;0;0;0;0;False;False;133;66;210;28;28;-14;-14;0;0;0;0;False;False;83;98;258;28;28;-14;-14;0;0;0;0;True;False;83;82;210;12;12;-6;-6;0;0;0;0;False;False diff --git a/bin/Data/Animations/Particles/pieceOfPowerTrail.ani b/bin/Data/Animations/Particles/pieceOfPowerTrail.ani new file mode 100644 index 0000000..cf066d9 --- /dev/null +++ b/bin/Data/Animations/Particles/pieceOfPowerTrail.ani @@ -0,0 +1,3 @@ +1 +items.png +run;;0;0;0;3;67;40;168;16;16;-8;-8;0;0;0;0;False;False;67;43;155;10;10;-5;-5;0;0;0;0;False;False;67;43;155;10;10;-5;-5;0;0;0;0;True;False diff --git a/bin/Data/Animations/Particles/run.ani b/bin/Data/Animations/Particles/run.ani new file mode 100644 index 0000000..b08635c --- /dev/null +++ b/bin/Data/Animations/Particles/run.ani @@ -0,0 +1,3 @@ +1 +enemies.png +spawn;;0;0;0;2;83;81;1;10;10;-5;-5;0;0;0;0;False;False;83;99;1;4;4;-2;-2;0;0;0;0;False;False diff --git a/bin/Data/Animations/Particles/shell_mansion_particle.ani b/bin/Data/Animations/Particles/shell_mansion_particle.ani new file mode 100644 index 0000000..9fb42be --- /dev/null +++ b/bin/Data/Animations/Particles/shell_mansion_particle.ani @@ -0,0 +1,3 @@ +1 +objects animated.png +idle;;0;0;0;3;267;83;115;10;10;-5;-5;0;0;0;0;False;False;133;98;114;12;12;-6;-6;0;0;0;0;False;False;133;112;112;16;16;-8;-8;0;0;0;0;False;False diff --git a/bin/Data/Animations/Particles/spawn.ani b/bin/Data/Animations/Particles/spawn.ani new file mode 100644 index 0000000..b581b3b --- /dev/null +++ b/bin/Data/Animations/Particles/spawn.ani @@ -0,0 +1,3 @@ +1 +items.png +run;;0;0;0;2;133;40;168;16;16;0;0;0;0;0;0;False;False;133;184;169;16;15;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Particles/splash.ani b/bin/Data/Animations/Particles/splash.ani new file mode 100644 index 0000000..075b0da --- /dev/null +++ b/bin/Data/Animations/Particles/splash.ani @@ -0,0 +1,3 @@ +1 +objects animated.png +idle;;0;0;-15;2;117;292;113;24;15;-12;0;0;0;0;0;False;False;117;290;129;28;15;-14;-1;0;0;0;0;False;False diff --git a/bin/Data/Animations/Particles/swordPoke.ani b/bin/Data/Animations/Particles/swordPoke.ani new file mode 100644 index 0000000..100c932 --- /dev/null +++ b/bin/Data/Animations/Particles/swordPoke.ani @@ -0,0 +1,3 @@ +1 +items.png +run;;0;-8;-8;2;67;114;226;12;12;2;2;0;0;0;0;False;False;67;128;224;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Particles/swordShotDespawn.ani b/bin/Data/Animations/Particles/swordShotDespawn.ani new file mode 100644 index 0000000..9835c01 --- /dev/null +++ b/bin/Data/Animations/Particles/swordShotDespawn.ani @@ -0,0 +1,3 @@ +1 +items.png +run;;0;-8;-8;2;133;66;258;12;12;2;2;0;0;0;0;False;False;133;80;256;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Sequences/beach_water.ani b/bin/Data/Animations/Sequences/beach_water.ani new file mode 100644 index 0000000..b306188 --- /dev/null +++ b/bin/Data/Animations/Sequences/beach_water.ani @@ -0,0 +1,4 @@ +1 +game sequences.png +top;;-1;0;0;5;133;336;232;16;16;0;0;0;0;0;0;False;False;267;352;232;16;16;0;0;0;0;0;0;False;False;267;368;232;16;16;0;0;0;0;0;0;False;False;267;384;232;16;16;0;0;0;0;0;0;False;False;133;336;232;16;16;0;0;0;0;0;0;False;False +bottom;;-1;0;0;4;267;336;256;16;16;0;0;0;0;0;0;False;False;267;352;256;16;16;0;0;0;0;0;0;False;False;267;368;256;16;16;0;0;0;0;0;0;False;False;267;384;256;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Sequences/bowWow link.ani b/bin/Data/Animations/Sequences/bowWow link.ani new file mode 100644 index 0000000..cfc793a --- /dev/null +++ b/bin/Data/Animations/Sequences/bowWow link.ani @@ -0,0 +1,6 @@ +1 +game sequences.png +stand;;0;0;0;1;83;230;73;27;23;-9;-23;0;0;0;0;False;False +piece;;0;0;0;1;83;226;105;31;23;-13;-23;0;0;0;0;False;False +walk;;-1;0;0;4;133;219;138;26;22;-14;-22;0;0;0;0;False;False;133;247;137;22;23;-11;-23;0;0;0;0;False;False;133;272;138;21;22;-9;-22;0;0;0;0;False;False;133;247;137;22;23;-11;-23;0;0;0;0;False;False +blocked;;0;0;0;1;133;219;138;26;22;-14;-22;0;0;0;0;False;False diff --git a/bin/Data/Animations/Sequences/bowWow.ani b/bin/Data/Animations/Sequences/bowWow.ani new file mode 100644 index 0000000..c3e86ae --- /dev/null +++ b/bin/Data/Animations/Sequences/bowWow.ani @@ -0,0 +1,8 @@ +1 +game sequences.png +idle_1;;0;0;0;1;83;279;56;24;23;-12;-23;0;0;0;0;False;False +idle_-1;;0;0;0;1;83;279;56;24;23;-12;-23;0;0;0;0;False;True +open_1;;-1;0;0;2;267;305;55;24;24;-12;-24;0;0;0;0;False;False;267;279;56;24;23;-12;-23;0;0;0;0;False;False +open_-1;;0;0;0;2;267;305;55;24;24;-12;-24;0;0;0;0;False;True;267;279;56;24;23;-12;-23;0;0;0;0;False;True +attack;;0;0;0;1;83;288;80;32;32;-16;-32;0;0;0;0;False;False +pre_attack;;2;0;0;2;133;324;106;24;24;-12;-24;0;0;0;0;False;False;133;324;80;24;24;-12;-24;0;0;0;0;False;False diff --git a/bin/Data/Animations/Sequences/castle frog boy.ani b/bin/Data/Animations/Sequences/castle frog boy.ani new file mode 100644 index 0000000..20a12d9 --- /dev/null +++ b/bin/Data/Animations/Sequences/castle frog boy.ani @@ -0,0 +1,6 @@ +1 +game sequences.png +walk;;-1;0;0;2;167;240;10;21;22;-11;-22;0;0;0;0;False;False;167;262;10;19;22;-9;-22;0;0;0;0;False;False +forward;;0;0;0;1;83;282;10;20;22;-11;-22;0;0;0;0;False;False +piece;;0;0;0;1;83;303;8;23;24;-15;-24;0;0;0;0;False;False +stand;;0;0;0;1;83;240;10;21;22;-11;-22;0;0;0;0;False;False diff --git a/bin/Data/Animations/Sequences/cliff sequence.ani b/bin/Data/Animations/Sequences/cliff sequence.ani new file mode 100644 index 0000000..5c2b518 --- /dev/null +++ b/bin/Data/Animations/Sequences/cliff sequence.ani @@ -0,0 +1,4 @@ +1 +game sequences.png +link;;-1;0;0;8;167;4;7;29;25;0;0;0;0;0;0;False;False;333;38;7;31;25;-3;0;0;0;0;0;False;False;167;4;7;29;25;0;0;0;0;0;0;False;False;333;38;7;31;25;-3;0;0;0;0;0;False;False;333;4;7;29;25;0;0;0;0;0;0;False;False;500;38;7;31;25;-3;0;0;0;0;0;False;False;167;4;7;29;25;0;0;0;0;0;0;False;False;167;38;7;31;25;-3;0;0;0;0;0;False;False +marin;;-1;0;0;8;167;11;40;21;24;0;0;0;0;0;0;False;False;333;39;41;22;24;-1;0;0;0;0;0;False;False;167;11;40;21;24;0;0;0;0;0;0;False;False;333;39;41;22;24;-1;0;0;0;0;0;False;False;333;11;40;21;24;0;0;0;0;0;0;False;False;500;39;41;22;24;-1;0;0;0;0;0;False;False;167;11;40;21;24;0;0;0;0;0;0;False;False;167;39;41;22;24;-1;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Sequences/final fountain.ani b/bin/Data/Animations/Sequences/final fountain.ani new file mode 100644 index 0000000..c5ee2e6 --- /dev/null +++ b/bin/Data/Animations/Sequences/final fountain.ani @@ -0,0 +1,4 @@ +1 +end sequence.png +top;;-1;-64;-48;3;50;16;16;128;48;0;0;0;0;0;0;False;False;50;16;96;128;48;0;0;0;0;0;0;False;False;50;16;176;128;48;0;0;0;0;0;0;False;False +bottom;;-1;-32;0;3;50;48;64;64;16;0;0;0;0;0;0;False;False;50;48;144;64;16;0;0;0;0;0;0;False;False;50;48;224;64;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Sequences/final star.ani b/bin/Data/Animations/Sequences/final star.ani new file mode 100644 index 0000000..a3e6609 --- /dev/null +++ b/bin/Data/Animations/Sequences/final star.ani @@ -0,0 +1,3 @@ +1 +end sequence.png +idle;;-1;0;0;4;267;294;31;3;3;-1;-1;0;0;0;0;False;False;533;293;35;5;5;-2;-2;0;0;0;0;False;False;800;292;41;7;7;-3;-3;0;0;0;0;False;False;533;293;35;5;5;-2;-2;0;0;0;0;False;False diff --git a/bin/Data/Animations/Sequences/link awake.ani b/bin/Data/Animations/Sequences/link awake.ani new file mode 100644 index 0000000..4df1ac8 --- /dev/null +++ b/bin/Data/Animations/Sequences/link awake.ani @@ -0,0 +1,9 @@ +1 +end sequence.png +shadow;;-1;0;0;4;133;448;768;128;8;0;0;0;0;0;0;False;False;133;448;784;128;8;0;0;0;0;0;0;False;False;133;448;800;128;8;0;0;0;0;0;0;False;False;133;448;816;128;8;0;0;0;0;0;0;False;False +sleep;;0;0;0;1;83;16;769;128;47;0;-47;0;0;0;0;False;False +awake;;0;0;0;12;467;16;833;128;47;0;-47;0;0;0;0;False;False;400;16;769;128;47;0;-47;0;0;0;0;False;False;500;16;833;128;47;0;-47;0;0;0;0;False;False;367;16;897;128;47;0;-47;0;0;0;0;False;False;367;16;833;128;47;0;-47;0;0;0;0;False;False;83;16;897;128;47;0;-47;0;0;0;0;False;False;500;160;769;128;47;0;-47;0;0;0;0;False;False;1000;160;833;128;47;0;-47;0;0;0;0;False;False;200;160;897;128;47;0;-47;0;0;0;0;False;False;200;304;769;128;47;0;-47;0;0;0;0;False;False;200;304;832;128;48;0;-48;0;0;0;0;False;False;200;304;890;128;54;0;-54;0;0;0;0;False;False +smile;;0;0;-80;3;200;16;448;72;80;0;0;0;0;0;0;False;False;200;96;448;72;80;0;0;0;0;0;0;False;False;200;176;448;72;80;0;0;0;0;0;0;False;False +pre_smile;;0;0;0;1;83;16;448;72;80;0;-80;0;0;0;0;False;False +sit;;0;0;0;1;83;480;854;40;62;0;0;0;0;0;0;False;False +look_up;;0;0;0;2;200;528;854;40;62;0;0;0;0;0;0;False;False;200;576;852;40;64;0;-2;0;0;0;0;False;False diff --git a/bin/Data/Animations/Sequences/link castle.ani b/bin/Data/Animations/Sequences/link castle.ani new file mode 100644 index 0000000..d9f6309 --- /dev/null +++ b/bin/Data/Animations/Sequences/link castle.ani @@ -0,0 +1,6 @@ +1 +game sequences.png +walk;;-1;0;0;2;167;167;41;19;23;-11;-23;0;0;0;0;False;False;167;139;42;21;22;-12;-22;0;0;0;0;False;False +stand;;0;0;0;1;83;167;41;19;23;-11;-23;0;0;0;0;False;False +forward;;0;0;0;1;83;217;41;19;23;-8;-23;0;0;0;0;False;False +piece;;0;0;0;1;83;189;41;23;23;-13;-23;0;0;0;0;False;False diff --git a/bin/Data/Animations/Sequences/link final.ani b/bin/Data/Animations/Sequences/link final.ani new file mode 100644 index 0000000..fe638d8 --- /dev/null +++ b/bin/Data/Animations/Sequences/link final.ani @@ -0,0 +1,4 @@ +1 +end sequence.png +idle;;-1;0;0;2;267;304;180;35;21;0;0;0;0;0;0;False;False;267;304;202;34;22;0;0;0;0;0;0;False;False +sitting;;0;0;0;1;83;304;128;32;27;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Sequences/link grave.ani b/bin/Data/Animations/Sequences/link grave.ani new file mode 100644 index 0000000..bd6831a --- /dev/null +++ b/bin/Data/Animations/Sequences/link grave.ani @@ -0,0 +1,7 @@ +1 +game sequences.png +look;;0;0;0;1;83;166;5;19;27;-9;-27;0;0;0;0;False;False +right;;0;0;0;1;83;140;5;23;27;-8;-27;0;0;0;0;False;False +walk;;-1;0;0;4;167;108;38;24;26;-8;-26;0;0;0;0;False;False;167;140;5;23;27;-7;-26;0;0;0;0;False;False;167;107;6;24;26;-8;-26;0;0;0;0;False;False;167;140;5;23;27;-7;-26;0;0;0;0;False;False +forward;;0;0;0;1;83;188;5;19;27;-8;-27;0;0;0;0;False;False +lean;;0;0;0;1;83;209;5;22;27;-12;-27;0;0;0;0;False;False diff --git a/bin/Data/Animations/Sequences/seagull big final.ani b/bin/Data/Animations/Sequences/seagull big final.ani new file mode 100644 index 0000000..fbb2eeb --- /dev/null +++ b/bin/Data/Animations/Sequences/seagull big final.ani @@ -0,0 +1,3 @@ +1 +end sequence.png +idle;;-1;0;0;6;100;344;142;16;7;-8;-7;0;0;0;0;False;False;100;344;130;16;11;-8;-5;0;0;0;0;False;False;133;344;181;16;11;-8;-5;0;0;0;0;False;False;133;344;172;16;8;-8;-7;0;0;0;0;False;False;100;344;161;16;10;-8;-9;0;0;0;0;False;False;100;344;150;16;10;-8;-9;0;0;0;0;False;False diff --git a/bin/Data/Animations/Sequences/seagull final.ani b/bin/Data/Animations/Sequences/seagull final.ani new file mode 100644 index 0000000..71fc876 --- /dev/null +++ b/bin/Data/Animations/Sequences/seagull final.ani @@ -0,0 +1,4 @@ +1 +end sequence.png +fly_1;;-1;0;0;5;267;308;235;8;9;-5;-5;0;0;0;0;False;False;133;317;235;8;10;-5;-5;0;0;0;0;False;False;133;326;232;8;15;-5;-8;0;0;0;0;False;False;133;335;233;8;13;-5;-7;0;0;0;0;False;False;133;344;234;8;11;-5;-6;0;0;0;0;False;False +fly_-1;;-1;0;0;5;267;308;235;8;9;-3;-5;0;0;0;0;False;True;133;317;235;8;9;-3;-5;0;0;0;0;False;True;133;326;232;8;15;-3;-8;0;0;0;0;False;True;133;335;233;8;13;-3;-7;0;0;0;0;False;True;133;344;234;8;11;-3;-6;0;0;0;0;False;True diff --git a/bin/Data/Animations/Sequences/seagull small.ani b/bin/Data/Animations/Sequences/seagull small.ani new file mode 100644 index 0000000..72298e6 --- /dev/null +++ b/bin/Data/Animations/Sequences/seagull small.ani @@ -0,0 +1,4 @@ +1 +game sequences.png +idle;;-1;0;0;4;133;339;299;10;5;-5;-5;0;0;0;0;False;False;133;339;305;10;4;-5;-4;0;0;0;0;False;False;133;340;286;8;6;-4;-4;0;0;0;0;False;False;133;340;293;8;5;-4;-5;0;0;0;0;False;False +glide;;0;0;0;1;83;339;299;10;5;-5;-5;0;0;0;0;False;False diff --git a/bin/Data/Animations/Sequences/seagull.ani b/bin/Data/Animations/Sequences/seagull.ani new file mode 100644 index 0000000..7b36cbd --- /dev/null +++ b/bin/Data/Animations/Sequences/seagull.ani @@ -0,0 +1,4 @@ +1 +game sequences.png +idle;;-1;0;0;6;100;352;306;16;7;-8;-7;0;0;0;0;False;False;100;352;293;16;11;-8;-4;0;0;0;0;False;False;100;352;280;16;11;-8;-4;0;0;0;0;False;False;100;376;305;16;8;-8;-6;0;0;0;0;False;False;100;376;293;16;10;-8;-7;0;0;0;0;False;False;100;376;281;16;10;-8;-7;0;0;0;0;False;False +glide;;0;0;0;1;83;352;306;16;7;-8;-7;0;0;0;0;False;False diff --git a/bin/Data/Animations/Sequences/tower dust.ani b/bin/Data/Animations/Sequences/tower dust.ani new file mode 100644 index 0000000..84b7dab --- /dev/null +++ b/bin/Data/Animations/Sequences/tower dust.ani @@ -0,0 +1,3 @@ +1 +game sequences.png +idle;;-1;0;0;3;133;176;197;48;8;0;0;0;0;0;0;False;False;133;177;207;46;8;1;0;0;0;0;0;False;False;133;176;217;48;7;1;1;0;0;0;0;False;False diff --git a/bin/Data/Animations/Sequences/wale.ani b/bin/Data/Animations/Sequences/wale.ani new file mode 100644 index 0000000..db6e5d8 --- /dev/null +++ b/bin/Data/Animations/Sequences/wale.ani @@ -0,0 +1,3 @@ +1 +end sequence.png +idle;;-1;0;0;4;533;368;138;40;22;0;0;0;0;0;0;False;False;533;368;162;40;18;0;0;0;0;0;0;False;False;533;368;182;40;19;0;0;0;0;0;0;False;False;533;368;203;40;24;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Sequences/water.ani b/bin/Data/Animations/Sequences/water.ani new file mode 100644 index 0000000..622bf04 --- /dev/null +++ b/bin/Data/Animations/Sequences/water.ani @@ -0,0 +1,3 @@ +1 +end sequence.png +idle;;-1;0;0;2;267;160;128;16;16;0;0;0;0;0;0;False;False;267;176;128;16;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Sequences/weather bird link.ani b/bin/Data/Animations/Sequences/weather bird link.ani new file mode 100644 index 0000000..3f5731c --- /dev/null +++ b/bin/Data/Animations/Sequences/weather bird link.ani @@ -0,0 +1,4 @@ +1 +game sequences.png +walk;;-1;0;0;4;167;305;138;21;22;-12;-22;0;0;0;0;False;False;167;349;137;19;23;-10;-23;0;0;0;0;False;False;167;327;138;21;22;-12;-22;0;0;0;0;False;False;167;349;137;19;23;-10;-23;0;0;0;0;False;False +stand;;0;0;0;1;83;217;41;19;23;-9;-23;0;0;0;0;False;False diff --git a/bin/Data/Animations/Sequences/weather bird marin.ani b/bin/Data/Animations/Sequences/weather bird marin.ani new file mode 100644 index 0000000..ff039f0 --- /dev/null +++ b/bin/Data/Animations/Sequences/weather bird marin.ani @@ -0,0 +1,4 @@ +1 +game sequences.png +walk;;-1;0;0;4;167;237;171;19;21;-12;-21;0;0;0;0;False;False;167;257;170;18;22;-11;-22;0;0;0;0;False;False;167;276;171;19;21;-12;-21;0;0;0;0;False;False;167;257;170;18;22;-11;-22;0;0;0;0;False;False +stand;;0;0;0;1;83;296;170;19;22;-9;-22;0;0;0;0;False;False diff --git a/bin/Data/Animations/Sequences/weather bird objects.ani b/bin/Data/Animations/Sequences/weather bird objects.ani new file mode 100644 index 0000000..dd51482 --- /dev/null +++ b/bin/Data/Animations/Sequences/weather bird objects.ani @@ -0,0 +1,7 @@ +1 +game sequences.png +top;;-1;0;0;3;300;344;665;160;8;0;0;0;0;0;0;False;False;300;344;674;160;8;0;0;0;0;0;0;False;False;300;344;683;160;8;0;0;0;0;0;0;False;False +bottom;;-1;0;0;3;400;344;692;32;8;0;0;0;0;0;0;False;False;400;344;701;32;8;0;0;0;0;0;0;False;False;400;344;710;32;8;0;0;0;0;0;0;False;False +rotator;;-1;0;0;2;167;378;693;5;24;0;0;0;0;0;0;False;False;167;385;693;5;24;0;0;0;0;0;0;False;False +flower_red;;-1;0;0;3;300;393;697;14;7;0;0;0;0;0;0;False;False;300;393;697;14;7;1;0;0;0;0;0;False;False;300;393;697;14;7;2;0;0;0;0;0;False;False +flower_white;;-1;0;0;3;300;393;705;14;7;0;0;0;0;0;0;False;False;300;393;705;14;7;1;0;0;0;0;0;False;False;300;393;705;14;7;2;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/Sequences/weather bird ulrich.ani b/bin/Data/Animations/Sequences/weather bird ulrich.ani new file mode 100644 index 0000000..341b6ca --- /dev/null +++ b/bin/Data/Animations/Sequences/weather bird ulrich.ani @@ -0,0 +1,5 @@ +1 +game sequences.png +walk;;-1;0;0;4;167;239;201;18;23;-9;-23;0;0;0;0;False;False;167;258;200;17;24;-9;-24;0;0;0;0;False;False;167;276;201;20;23;-9;-23;0;0;0;0;False;False;167;258;200;17;24;-9;-24;0;0;0;0;False;False +stand;;0;0;0;1;83;297;199;22;25;-11;-25;0;0;0;0;False;False +stopped;;0;0;0;1;83;258;200;17;24;-9;-24;0;0;0;0;False;False diff --git a/bin/Data/Animations/dialog_arrow.ani b/bin/Data/Animations/dialog_arrow.ani new file mode 100644 index 0000000..0223a3a --- /dev/null +++ b/bin/Data/Animations/dialog_arrow.ani @@ -0,0 +1,3 @@ +1 +minimap.png +idle;;-1;0;0;2;267;161;32;0;0;-8;-6;0;0;0;0;False;False;267;161;32;8;6;-8;-6;0;0;0;0;False;False diff --git a/bin/Data/Animations/dungeonPlayer.ani b/bin/Data/Animations/dungeonPlayer.ani new file mode 100644 index 0000000..17be63d --- /dev/null +++ b/bin/Data/Animations/dungeonPlayer.ani @@ -0,0 +1,3 @@ +1 +minimap.png +IDLE;;-1;0;0;2;200;2;180;6;6;0;0;0;0;0;0;False;False;200;10;180;6;6;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/link fishing.ani b/bin/Data/Animations/link fishing.ani new file mode 100644 index 0000000..56b3ac0 --- /dev/null +++ b/bin/Data/Animations/link fishing.ani @@ -0,0 +1,9 @@ +1 +link0.png +idle;;0;0;0;1;83;313;133;25;16;0;0;0;0;0;0;False;False +throw;;0;-6;0;6;50;273;273;31;15;0;0;-10;12;3;3;False;False;67;309;272;27;16;4;-1;-9;-6;3;3;False;False;67;342;256;15;32;17;-17;8;-6;3;3;False;False;333;362;264;16;24;17;-9;18;-4;3;3;False;False;50;384;256;15;32;17;-17;8;-6;3;3;False;False;583;309;272;27;16;4;-1;-9;-6;3;3;False;False +pull_up;idle;0;0;0;1;250;422;222;26;18;-2;-2;0;0;0;0;False;False +pull_right;idle;0;0;0;1;250;314;232;29;16;-5;0;0;0;0;0;False;False +hooked;;0;0;0;1;83;422;222;26;18;-3;-2;0;0;0;0;False;False +hooked_pull;hooked;0;0;0;2;333;345;126;18;24;8;-8;0;0;0;0;False;False;167;422;222;26;18;-3;-2;0;0;0;0;False;False +pullout;;0;0;0;1;1000;370;121;15;29;11;-13;0;0;0;0;False;False diff --git a/bin/Data/Animations/link0.ani b/bin/Data/Animations/link0.ani new file mode 100644 index 0000000..f74e861 --- /dev/null +++ b/bin/Data/Animations/link0.ani @@ -0,0 +1,123 @@ +1 +link0.png +stand_0;;0;0;0;1;1000;0;0;14;16;0;0;0;0;0;0;False;False +stand_3;;0;0;0;1;1000;31;0;13;16;0;0;0;0;0;0;False;False +stand_1;;0;1;0;1;1000;61;0;12;16;0;0;0;0;0;0;False;False +stand_2;;0;0;0;1;1000;0;0;14;16;0;0;0;0;0;0;False;True +stands_0;;0;0;0;1;1000;0;0;14;16;0;0;0;0;0;0;False;False +stands_3;;0;-1;0;1;1000;126;45;14;16;0;0;0;0;0;0;False;False +stands_1;;0;1;0;1;1000;162;45;14;16;0;0;0;0;0;0;False;False +stands_2;;0;0;0;1;1000;92;45;15;16;-1;0;0;0;0;0;False;True +standms_0;;0;0;0;1;1000;0;0;14;16;0;0;0;0;0;0;False;False +standms_3;;0;-1;0;1;1000;126;45;14;16;0;0;0;0;0;0;False;False +standms_1;;0;1;0;1;1000;162;45;14;16;0;0;0;0;0;0;False;False +standms_2;;0;1;0;1;1000;57;45;14;16;-1;0;0;0;0;0;False;True +standbs_2;;0;1;1;1;1000;49;246;14;15;0;0;0;3;3;12;False;True +standbs_0;;0;-1;1;1;1000;49;246;14;15;0;0;0;3;3;12;False;False +standbs_3;;0;0;1;1;1000;87;246;13;15;0;0;3;13;8;3;False;False +standbs_1;;0;1;0;1;1000;122;245;14;16;0;0;2;5;8;3;False;False +standbms_2;;0;1;1;1;1000;49;246;14;15;0;0;0;3;3;12;False;True +standbms_0;;0;-1;1;1;1000;49;246;14;15;0;0;0;3;3;12;False;False +standbms_3;;0;-1;1;1;1000;21;46;14;15;0;0;3;13;8;3;False;False +standbms_1;;0;1;0;1;1000;122;245;14;16;0;0;2;5;8;3;False;False +standc_0;;-1;0;0;1;200;125;0;14;16;0;0;0;0;0;0;False;False +standc_2;;-1;0;0;1;200;125;0;14;16;0;0;0;0;0;0;False;True +standc_3;;-1;1;0;1;200;157;0;12;16;0;0;0;0;0;0;False;False +standc_1;;-1;1;0;1;200;185;0;12;16;0;0;0;0;0;0;False;False +walk_0;;-1;0;0;2;150;16;0;13;16;1;0;0;0;0;0;False;False;150;0;0;14;16;0;0;0;0;0;0;False;False +walk_3;;-1;0;0;2;150;31;0;13;16;1;0;0;0;0;0;False;True;150;31;0;13;16;0;0;0;0;0;0;False;False +walk_1;;-1;1;0;2;150;61;0;12;16;0;0;0;0;0;0;False;True;150;61;0;12;16;0;0;0;0;0;0;False;False +walk_2;;-1;0;0;2;150;16;0;13;16;0;0;0;0;0;0;False;True;150;0;0;14;16;0;0;0;0;0;0;False;True +walkc_0;;-1;0;0;2;150;141;0;13;16;1;0;0;0;0;0;False;False;150;125;0;14;16;0;0;0;0;0;0;False;False +walkc_3;;-1;1;0;2;150;157;0;12;16;0;0;0;0;0;0;False;True;150;157;0;12;16;0;0;0;0;0;0;False;False +walkc_1;;-1;1;0;2;150;185;0;12;16;0;0;0;0;0;0;False;True;150;185;0;12;16;0;0;0;0;0;0;False;False +walkc_2;;-1;0;0;2;150;141;0;13;16;0;0;0;0;0;0;False;True;150;125;0;14;16;0;0;0;0;0;0;False;True +walks_0;;-1;0;0;2;150;16;1;13;15;1;1;0;0;0;0;False;False;150;0;0;14;16;0;0;0;0;0;0;False;False +walks_3;;-1;-1;0;2;150;143;45;15;16;0;0;0;0;0;0;False;False;150;126;45;14;16;0;0;0;0;0;0;False;False +walks_1;;-1;1;0;2;150;180;45;14;16;0;0;0;0;0;0;False;False;150;162;45;14;16;0;0;0;0;0;0;False;False +walks_2;;-1;-1;0;2;150;110;46;13;15;1;1;0;0;0;0;False;True;150;92;45;15;16;0;0;0;0;0;0;False;True +walkms_0;;-1;0;0;2;150;16;1;13;15;1;1;0;0;0;0;False;False;150;0;0;14;16;0;0;0;0;0;0;False;False +walkms_3;;-1;-1;0;2;150;143;45;15;16;0;0;0;0;0;0;False;False;150;126;45;14;16;0;0;0;0;0;0;False;False +walkms_1;;-1;1;0;2;150;180;45;14;16;0;0;0;0;0;0;False;False;150;162;45;14;16;0;0;0;0;0;0;False;False +walkms_2;;-1;-1;0;2;150;75;46;13;15;1;1;0;0;0;0;False;True;150;57;45;14;16;1;0;0;0;0;0;False;True +walkbs_2;;-1;1;1;2;150;68;247;15;14;-1;1;0;2;3;12;False;True;150;49;246;14;15;0;0;0;3;3;12;False;True +walkbs_0;;-1;-1;1;2;150;68;247;15;14;0;1;0;2;3;12;False;False;150;49;246;14;15;0;0;0;3;3;12;False;False +walkbs_3;;-1;0;1;2;150;103;246;14;15;0;0;3;13;8;3;False;False;150;87;246;13;15;0;0;3;13;8;3;False;False +walkbs_1;;-1;1;0;2;150;142;246;14;15;0;1;2;4;8;3;False;False;150;122;245;14;16;0;0;2;5;8;3;False;False +walkbms_2;;-1;1;1;2;150;68;247;15;14;-1;1;0;2;3;12;False;True;150;49;246;14;15;0;0;0;3;3;12;False;True +walkbms_0;;-1;-1;1;2;150;68;247;15;14;0;1;0;2;3;12;False;False;150;49;246;14;15;0;0;0;3;3;12;False;False +walkbms_3;;-1;0;1;2;150;39;46;15;15;-1;0;3;13;8;3;False;False;150;21;46;14;15;-1;0;3;13;8;3;False;False +walkbms_1;;-1;1;0;2;150;142;246;14;15;0;1;2;4;8;3;False;False;150;122;245;14;16;0;0;2;5;8;3;False;False +push_0;;-1;-1;0;2;150;15;21;15;16;0;0;0;0;0;0;False;False;150;32;21;15;16;0;0;0;0;0;0;False;False +push_3;;-1;0;0;2;150;51;21;14;16;0;0;0;0;0;0;False;False;150;67;21;12;16;1;0;0;0;0;0;False;False +push_1;;-1;-1;0;2;150;82;21;16;16;0;0;0;0;0;0;False;False;150;99;21;15;16;0;0;0;0;0;0;False;False +push_2;;-1;0;0;2;150;32;21;15;16;0;0;0;0;0;0;False;True;150;15;21;15;16;0;0;0;0;0;0;False;True +attack_0;;0;0;0;3;50;17;96;15;16;-1;0;0;0;0;0;False;True;50;34;97;15;15;-1;1;0;0;0;0;False;True;133;34;97;15;15;-4;1;0;0;0;0;False;True +attack_2;;0;0;0;3;50;17;96;15;16;-1;0;0;0;0;0;False;False;50;34;97;15;15;0;1;0;0;0;0;False;False;133;34;97;15;15;3;1;0;0;0;0;False;False +attack_1;;0;0;0;3;50;94;97;14;15;0;1;0;0;0;0;False;False;50;110;96;13;16;0;0;0;0;0;0;False;False;133;110;96;13;16;0;-3;0;0;0;0;False;False +attack_3;;0;0;0;3;50;57;96;13;16;0;0;0;0;0;0;False;False;50;72;96;14;16;0;0;0;0;0;0;False;False;133;72;96;14;16;0;3;0;0;0;0;False;False +swing_0;;0;0;1;4;100;72;96;14;16;0;1;0;0;0;0;False;False;100;34;97;15;15;1;1;0;0;0;0;False;False;100;110;96;13;16;0;-1;0;0;0;0;False;False;100;34;97;15;15;-1;0;0;0;0;0;False;True +swing_1;;0;0;1;4;100;34;97;15;15;-1;0;0;0;0;0;False;True;100;72;96;14;16;0;1;0;0;0;0;False;False;100;34;97;15;15;1;0;0;0;0;0;False;False;100;110;96;13;16;0;-1;0;0;0;0;False;False +swing_2;;0;0;1;4;100;110;96;13;16;0;-1;0;0;0;0;False;False;100;34;97;15;15;-1;0;0;0;0;0;False;True;100;72;96;14;16;0;1;0;0;0;0;False;False;100;34;97;15;15;1;0;0;0;0;0;False;False +swing_3;;0;0;1;4;100;34;97;15;15;1;0;0;0;0;0;False;False;100;110;96;13;16;0;-1;0;0;0;0;False;False;100;34;97;15;15;-1;0;0;0;0;0;False;True;100;72;96;14;16;0;1;0;0;0;0;False;False +poke_0;;0;-1;1;1;183;34;97;15;15;0;0;0;0;0;0;False;True +poke_1;;0;1;0;1;183;110;96;13;16;0;0;0;0;0;0;False;False +poke_2;;0;1;1;1;183;34;97;15;15;0;0;0;0;0;0;False;False +poke_3;;0;0;2;1;183;72;96;14;16;0;0;0;0;0;0;False;False +rod_0;;0;0;0;2;50;17;96;15;16;1;0;0;0;0;0;False;True;200;34;97;15;15;-1;1;0;0;0;0;False;True +rod_1;;0;0;0;2;50;94;97;14;15;1;1;0;0;0;0;False;False;200;110;96;13;16;1;0;0;0;0;0;False;False +rod_2;;0;0;0;2;50;17;96;15;16;-2;0;0;0;0;0;False;False;200;34;97;15;15;0;1;0;0;0;0;False;False +rod_3;;0;0;0;2;50;57;96;13;16;-1;0;0;0;0;0;False;False;200;72;96;14;16;-1;1;0;0;0;0;False;False +powder_2;;0;0;1;1;200;34;97;15;15;0;0;0;0;0;0;False;False +powder_1;;0;1;0;1;200;110;96;13;16;0;0;0;0;0;0;False;False +powder_0;;0;-1;1;1;200;34;97;15;15;0;0;0;0;0;0;False;True +powder_3;;0;-1;0;1;200;72;96;14;16;0;0;0;0;0;0;False;False +jump_2;;0;0;0;5;50;16;0;13;16;0;0;0;0;0;0;False;True;100;337;97;16;14;0;0;0;0;0;0;False;False;100;358;98;14;16;0;0;0;0;0;0;False;False;100;378;100;16;14;0;0;0;0;0;0;False;False;100;16;0;13;16;0;0;0;0;0;0;False;True +jump_3;;0;1;0;5;50;31;0;13;16;-1;0;0;0;0;0;False;False;100;284;97;12;15;0;0;0;0;0;0;False;False;100;301;97;12;15;0;0;0;0;0;0;False;False;100;317;96;12;16;0;0;0;0;0;0;False;False;100;31;0;13;16;-1;0;0;0;0;0;False;False +jump_1;;0;1;0;5;50;61;0;12;16;0;0;0;0;0;0;False;False;83;284;97;12;15;0;0;0;0;0;0;True;False;100;301;97;12;15;0;0;0;0;0;0;True;False;100;317;96;12;16;0;-1;0;0;0;0;True;False;100;61;0;12;16;0;0;0;0;0;0;False;False +jump_0;;0;1;0;5;50;16;0;13;16;0;0;0;0;0;0;False;False;100;337;97;16;14;0;0;0;0;0;0;False;True;100;358;98;14;16;0;0;0;0;0;0;False;True;100;378;100;16;14;0;0;0;0;0;0;False;True;100;16;0;13;16;0;0;0;0;0;0;False;False +fall_0;;-1;1;0;1;200;16;0;13;16;0;0;0;0;0;0;False;False +fall_2;;-1;0;0;1;200;16;0;13;16;0;0;0;0;0;0;False;True +show1;;-1;-1;0;1;200;443;135;16;16;0;0;0;0;0;0;False;False +fall;;0;0;4;6;200;284;161;15;15;0;0;0;0;0;0;False;False;150;284;180;13;13;1;2;0;0;0;0;False;False;117;285;198;11;11;2;3;0;0;0;0;False;False;100;286;212;8;8;3;4;0;0;0;0;False;False;200;287;224;4;4;5;6;0;0;0;0;False;False;83;0;0;0;0;0;0;0;0;0;0;False;False +intro;;0;-1;0;14;500;368;173;16;29;0;0;0;0;0;0;False;True;500;368;173;16;29;0;0;0;0;0;0;False;False;500;368;173;16;29;0;0;0;0;0;0;False;True;500;368;173;16;29;0;0;0;0;0;0;False;False;500;368;173;16;29;0;0;0;0;0;0;False;True;500;368;173;16;29;0;0;0;0;0;0;False;False;500;368;173;16;29;0;0;0;0;0;0;False;True;500;368;173;16;29;0;0;0;0;0;0;False;False;500;385;173;16;29;0;0;0;0;0;0;False;False;500;402;173;16;29;0;0;0;0;0;0;False;False;100;419;173;16;29;0;0;0;0;0;0;False;False;200;402;173;16;29;0;0;0;0;0;0;False;False;100;419;173;16;29;0;0;0;0;0;0;False;False;200;402;173;16;29;0;0;0;0;0;0;False;False +dying;;0;0;0;13;133;0;0;14;16;0;0;0;0;0;0;False;False;133;61;0;12;16;1;0;0;0;0;0;False;False;133;0;0;14;16;0;0;0;0;0;0;False;True;133;31;0;13;16;0;0;0;0;0;0;False;False;133;0;0;14;16;0;0;0;0;0;0;False;False;133;61;0;12;16;1;0;0;0;0;0;False;False;133;0;0;14;16;0;0;0;0;0;0;False;True;133;31;0;13;16;0;0;0;0;0;0;False;False;133;0;0;14;16;0;0;0;0;0;0;False;False;133;61;0;12;16;1;0;0;0;0;0;False;False;133;0;0;14;16;0;0;0;0;0;0;False;True;133;31;0;13;16;0;0;0;0;0;0;False;False;500;395;137;14;14;0;2;0;0;0;0;False;False +intro_sit;;-1;-1;0;3;1000;402;173;16;29;0;0;0;0;0;0;False;False;100;402;173;16;29;0;0;0;0;0;0;False;False;200;419;173;16;29;0;0;0;0;0;0;False;False +show2;;0;-1;0;1;83;443;153;16;16;0;0;0;0;0;0;False;False +dig_0;;0;-1;0;2;250;186;73;14;16;0;0;0;0;0;0;False;True;83;202;73;15;16;1;0;0;0;0;0;False;True +dig_1;;0;-1;0;2;250;153;75;14;15;0;0;0;0;0;0;False;False;83;169;74;15;15;1;1;0;0;0;0;False;False +dig_2;;0;1;0;2;250;186;73;14;16;0;0;0;0;0;0;False;False;83;202;73;15;16;-2;0;0;0;0;0;False;False +dig_3;;0;0;1;2;250;118;73;14;15;0;0;0;0;0;0;False;False;83;134;73;16;16;-1;-1;0;0;0;0;False;False +dive;;0;-1;4;2;267;419;2;16;15;0;0;0;0;0;0;False;False;267;438;2;16;15;0;0;0;0;0;0;False;False +pull_0;;0;0;0;1;83;214;23;16;16;0;0;0;0;0;0;False;False +pull_1;;0;0;0;1;83;194;21;16;16;-1;0;0;0;0;0;False;False +pull_2;;0;0;0;1;83;214;23;16;16;-1;0;0;0;0;0;False;True +pull_3;;0;0;0;1;83;173;21;16;16;-1;0;0;0;0;0;False;False +throw_2;;0;0;1;1;200;34;97;15;15;0;0;0;0;0;0;False;False +throw_1;;0;1;0;1;200;110;96;13;16;0;0;0;0;0;0;False;False +throw_0;;0;-1;1;1;200;34;97;15;15;0;0;0;0;0;0;False;True +throw_3;;0;-1;0;1;200;72;96;14;16;0;0;0;0;0;0;False;False +grab_0;;0;0;0;1;83;235;23;13;16;-1;0;0;0;0;0;False;False +grab_1;;0;0;0;1;83;82;21;16;16;-1;0;0;0;0;0;False;False +grab_2;;0;0;0;1;83;235;23;13;16;2;0;0;0;0;0;False;True +grab_3;;0;0;0;1;83;51;22;14;15;0;1;0;0;0;0;False;False +stunned;;0;0;0;1;83;395;137;14;14;0;2;0;0;0;0;False;False +swim_0;;0;0;0;2;267;384;5;14;11;0;5;0;0;0;0;False;True;267;401;4;14;12;0;4;0;0;0;0;False;True +swim_1;;0;0;0;2;267;314;4;14;12;0;4;0;0;0;0;False;False;267;332;3;12;13;1;3;0;0;0;0;False;False +swim_2;;0;0;0;2;267;384;5;14;11;0;5;0;0;0;0;False;False;267;401;4;14;12;0;4;0;0;0;0;False;False +swim_3;;0;0;0;2;267;349;4;14;12;0;4;0;0;0;0;False;False;267;366;5;14;11;0;5;0;0;0;0;False;False +swim_2d_2;;-1;0;1;2;133;271;2;16;14;0;0;0;0;0;0;False;False;133;292;2;16;15;0;0;0;0;0;0;False;False +swim_2d_0;;-1;0;1;2;133;271;2;16;14;0;0;0;0;0;0;False;True;133;292;2;16;15;0;0;0;0;0;0;False;True +bed;;0;-1;0;2;300;385;175;16;15;0;0;0;0;0;0;False;False;233;368;175;16;15;0;0;0;0;0;0;False;False +ocarina;;0;-1;0;4;917;423;29;16;16;0;0;0;0;0;0;False;False;917;423;29;16;16;0;0;0;0;0;0;False;True;917;423;29;16;16;0;0;0;0;0;0;False;False;583;423;29;16;16;0;0;0;0;0;0;False;True +ocarina_duo;;-1;-1;0;2;1067;423;29;16;16;0;0;0;0;0;0;False;False;1067;423;29;16;16;0;0;0;0;0;0;False;True +ocean_sit;;0;0;0;1;83;428;135;12;16;0;0;0;0;0;0;False;False +final_stand;;0;0;0;1;83;401;96;14;16;0;0;0;0;0;0;False;False +final_stand_down;;0;0;0;1;83;417;96;14;16;0;0;0;0;0;0;False;False +fountain;;-1;0;0;8;133;327;177;16;16;-1;0;0;0;0;0;False;False;133;310;177;16;15;-1;0;0;0;0;0;False;False;133;310;160;16;16;-1;0;0;0;0;0;False;False;133;327;160;16;16;-1;0;0;0;0;0;False;False;133;310;160;16;16;-1;0;0;0;0;0;False;True;133;310;177;16;15;-1;0;0;0;0;0;False;True;133;327;177;16;16;-1;0;0;0;0;0;False;True;133;311;193;16;16;-1;0;0;0;0;0;False;False +pushed_over;;0;0;0;1;83;395;137;14;14;0;2;0;0;0;0;False;False +intro_jump;;0;0;0;1;83;16;1;13;15;0;1;0;0;0;0;False;True +flying_0;;-1;0;0;1;200;141;1;13;15;1;1;0;0;0;0;False;False +flying_2;;-1;0;0;1;200;141;1;13;15;0;1;0;0;0;0;False;True +flying_3;;-1;1;0;1;200;157;0;12;16;0;0;0;0;0;0;False;False +flying_1;;-1;1;0;1;200;185;0;12;16;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/mapPlayer.ani b/bin/Data/Animations/mapPlayer.ani new file mode 100644 index 0000000..337385d --- /dev/null +++ b/bin/Data/Animations/mapPlayer.ani @@ -0,0 +1,3 @@ +1 +minimap.png +IDLE;;-1;0;0;2;200;169;113;5;5;0;0;0;0;0;0;False;False;200;177;113;5;5;0;0;0;0;0;0;False;False diff --git a/bin/Data/Animations/mapSelector.ani b/bin/Data/Animations/mapSelector.ani new file mode 100644 index 0000000..7dd2709 --- /dev/null +++ b/bin/Data/Animations/mapSelector.ani @@ -0,0 +1,3 @@ +1 +minimap.png +IDLE;;-1;-4;-4;2;200;199;114;15;15;0;0;0;0;0;0;False;False;200;190;105;33;33;-9;-9;0;0;0;0;False;False diff --git a/bin/Data/Animations/menu_link.ani b/bin/Data/Animations/menu_link.ani new file mode 100644 index 0000000..399b9a4 --- /dev/null +++ b/bin/Data/Animations/menu_link.ani @@ -0,0 +1,3 @@ +1 +link0.png +idle;;-1;0;0;2;150;31;0;13;16;0;0;0;0;0;0;False;False;150;31;0;13;16;1;0;0;0;0;0;False;True diff --git a/bin/Data/Dungeon/dColor_0.txt b/bin/Data/Dungeon/dColor_0.txt new file mode 100644 index 0000000..fbe464d --- /dev/null +++ b/bin/Data/Dungeon/dColor_0.txt @@ -0,0 +1,20 @@ +10 +20 +6 +6 +7,9,4,4,5,8, +15,8,7,6,7,16, +4,15,10,8,20,4, +4,7,12,10,19,4, +4,14,14,9,16,4, +0,1,0,0,0,0 + +3.dc_nightmare_killed,0,0,0,1.dc_nightmarekey,0 +0,0,1.dc_map,0,0,0 +0,0,0,0,0,0 +0,0,0,0,1.dc_beak,0 +0,0,0,1.dc_smallkey_0,0,0 +0,0,0,0,0,0 + +1 +dc_wall,2,3,11 \ No newline at end of file diff --git a/bin/Data/Dungeon/eight_0.txt b/bin/Data/Dungeon/eight_0.txt new file mode 100644 index 0000000..39a5861 --- /dev/null +++ b/bin/Data/Dungeon/eight_0.txt @@ -0,0 +1,23 @@ +2 +8 +8 +9 +4,4,4,13,13,4,4,4, +13,4,4,20,20,4,4,13, +15,12,11,15,16,12,8,14, +4,7,17,11,11,12,16,4, +4,20,15,17,17,11,16,4, +13,18,8,18,17,17,8,13, +18,16,15,17,17,10,10,19, +14,4,4,20,14,4,4,14, +0,0,0,1,0,0,0,0 + +0,0,0,0,0,0,0,0, +1.d8_nkey,0,0,3.d8_nightmare,1.d8_potion,0,0,1.d8_magic_rod, +0,0,1.d8_ruby50_1,0,0,1.d8_smallkey_3,0,0, +0,1.d8_smallkey_4,0,0,0,0,0,0, +0,1.d8_smallkey_5,0,0,0,0,0,0, +0,1.d8_ruby20,0,1.d8_dmap,0,0,0,0, +0,0,d8_ruby50_0,0,0,1.d8_chest_zol,0,0, +1.d8_compass,0,0,0,0,0,0,1.d8_stoneBeak, +0,0,0,0,0,0,0,0, \ No newline at end of file diff --git a/bin/Data/Dungeon/five_0.txt b/bin/Data/Dungeon/five_0.txt new file mode 100644 index 0000000..6593779 --- /dev/null +++ b/bin/Data/Dungeon/five_0.txt @@ -0,0 +1,23 @@ +6 +8 +7 +9 +5,6,9,5,8,4,4, +4,4,20,4,18,8,4, +5,12,10,6,20,18,6, +4,4,4,4,15,19,6, +4,4,5,13,7,16,4, +4,5,12,8,20,4,4, +4,4,5,5,19,4,4, +4,4,4,5,10,12,8, +0,0,0,0,0,0,1 + +0,0,0,1.d5_dmap,0,0,0, +0,0,3.d5_nightmare,0,0,1.d5_ruby50_1,0, +0,0,0,0,0,1.d5_ruby50_0,1.d5_key_2, +0,0,0,0,0,0,0, +0,0,0,0,0,1.d5_ms_chest,0, +0,1.d5_key_3,0,0,0,0,0, +0,0,0,0,0,0,0, +0,0,0,1.d5_compass,0,1.d5_200_rupees,0, +0,0,0,0,0,0,0, \ No newline at end of file diff --git a/bin/Data/Dungeon/four_0.txt b/bin/Data/Dungeon/four_0.txt new file mode 100644 index 0000000..06dc0a2 --- /dev/null +++ b/bin/Data/Dungeon/four_0.txt @@ -0,0 +1,21 @@ +10 +12 +6 +8 +4,4,7,8,4,4, +9,4,20,20,4,13, +20,7,10,17,8,20, +15,19,7,17,17,16, +4,18,17,19,20,4, +4,15,17,17,16,4, +4,4,20,14,4,4, +2,2,1,2,2,2 + +0,0,1.d4_flippers,0,0,0, +0,0,0,0,0,1.d4_key_3, +3.d4_nightmare_killed,0,1.d4_key_4,0,1.d4_map,0, +0,1.d4_chest_zol,1.d4_r50_2,0,0,1.d4_key_2, +0,0,0,0,1.d4_r50_1,0, +0,1.d4_nkey,0,0,1.d4_beak,0, +0,0,0,1.d4_key_1,0,0, +0,0,0,0,0,0, \ No newline at end of file diff --git a/bin/Data/Dungeon/one_0.txt b/bin/Data/Dungeon/one_0.txt new file mode 100644 index 0000000..b92da7e --- /dev/null +++ b/bin/Data/Dungeon/one_0.txt @@ -0,0 +1,22 @@ +6 +16 +7 +7 +4,4,4,4,4,4,9, +4,5,7,6,4,4,20, +13,4,18,11,8,13,20, +20,5,18,10,10,10,16, +14,4,15,11,16,4,4, +4,5,12,19,4,4,4, +2,2,2,1,2,2,2, + +0,0,0,0,0,0,0, +0,0,0,0,0,0,3.d1_n1_killed, +1.d1_feather,0,0,1.d1_nightmarekey,0,1.d1_beak,0, +0,0,1.d1_r20,1.d1k3,0,0,0, +0,0,0,1.d1k2,1.d1_map,0,0, +0,0,0,0,0,0,0, +0,0,0,0,0,0,0, + +1 +d1_wall,2,3,17 \ No newline at end of file diff --git a/bin/Data/Dungeon/seven_0.txt b/bin/Data/Dungeon/seven_0.txt new file mode 100644 index 0000000..981020e --- /dev/null +++ b/bin/Data/Dungeon/seven_0.txt @@ -0,0 +1,15 @@ +0 +40 +4 +5 +7,11,12,8, +18,17,11,19, +18,10,17,19, +15,11,10,16, +0,1,0,0 + +1.shell_26,0,0,1.d7_smallkey_2, +0,0,0,0, +1.d7_beak,0,0,0, +0,0,0,0, +0,0,0,0, \ No newline at end of file diff --git a/bin/Data/Dungeon/seven_1.txt b/bin/Data/Dungeon/seven_1.txt new file mode 100644 index 0000000..bda7b20 --- /dev/null +++ b/bin/Data/Dungeon/seven_1.txt @@ -0,0 +1,13 @@ +0 +4 +4 +4 +4,13,13,4, +5,17,17,8, +18,19,20,19, +15,10,10,16 + +0,0,1.d7_map,0, +0,0,0,0, +0,0,0,1.d7_mirrorShield, +0,1.d7_chestBomb,0,0, \ No newline at end of file diff --git a/bin/Data/Dungeon/seven_2.txt b/bin/Data/Dungeon/seven_2.txt new file mode 100644 index 0000000..c67e06a --- /dev/null +++ b/bin/Data/Dungeon/seven_2.txt @@ -0,0 +1,16 @@ +36 +40 +4 +4 +4,7,6,4, +7,19,13,13, +15,19,7,16, +4,15,16,4 + +0,0,1.d7_potion,0, +0,0,0,1.d7_nkey, +0,0,0,0, +0,0,0,0, + +1 +d7_nightmare,2,2,18 \ No newline at end of file diff --git a/bin/Data/Dungeon/seven_2_alt.txt b/bin/Data/Dungeon/seven_2_alt.txt new file mode 100644 index 0000000..b7afca6 --- /dev/null +++ b/bin/Data/Dungeon/seven_2_alt.txt @@ -0,0 +1,13 @@ +36 +40 +4 +4 +4,7,6,4, +7,19,13,13, +15,19,7,16, +4,15,16,4 + +0,0,1.d7_potion,0, +0,0,0,1.d7_nkey, +0,0,3.d7_nightmare,0, +0,0,0,0, \ No newline at end of file diff --git a/bin/Data/Dungeon/seven_3.txt b/bin/Data/Dungeon/seven_3.txt new file mode 100644 index 0000000..809e5ca --- /dev/null +++ b/bin/Data/Dungeon/seven_3.txt @@ -0,0 +1,13 @@ +36 +4 +4 +4 +4,4,4,4 +4,19,13,4 +4,11,17,4 +4,4,4,4 + +0,0,0,0, +0,0,0,0, +0,0,3.d7_nightmare,0, +0,0,0,0 \ No newline at end of file diff --git a/bin/Data/Dungeon/seven_3_alt.txt b/bin/Data/Dungeon/seven_3_alt.txt new file mode 100644 index 0000000..311e69b --- /dev/null +++ b/bin/Data/Dungeon/seven_3_alt.txt @@ -0,0 +1,13 @@ +36 +4 +4 +4 +4,4,4,4 +4,4,4,4 +4,4,4,4 +4,4,4,4 + +0,0,0,0, +0,0,0,0, +0,0,0,0, +0,0,0,0 \ No newline at end of file diff --git a/bin/Data/Dungeon/six_0.txt b/bin/Data/Dungeon/six_0.txt new file mode 100644 index 0000000..b8cc1a6 --- /dev/null +++ b/bin/Data/Dungeon/six_0.txt @@ -0,0 +1,25 @@ +2 +12 +8 +8 +13,4,4,4,4,4,4,13, +7,8,4,13,9,4,13,20, +7,17,12,19,20,14,20,20, +15,19,4,20,20,4,18,16, +4,14,6,15,16,13,20,4, +4,13,20,4,4,20,19,4, +4,14,5,11,12,16,14,4, +0,0,0,1,0,0,0,0 + +1.d6_ruby100_1,0,0,0,0,0,0,1.d6_ruby200, +0,1.d6_compass,0,0,0,0,1.d6_nightmarekey,0, +0,1.d6_stoneBeak,0,0,3.d6_facade,0,1.d6_smallkey_0,0, +0,0,0,0,0,0,0,0, +0,0,1.d6_ruby100_0,0,0,0,0,0, +0,1.d6_stonelifter_2,1.d6_ruby50,0,0,0,0,1.d6_potion, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, + +2 +d6_wall_1,1,3,17 +d6_wall_0,5,4,20 \ No newline at end of file diff --git a/bin/Data/Dungeon/three_0.txt b/bin/Data/Dungeon/three_0.txt new file mode 100644 index 0000000..379df27 --- /dev/null +++ b/bin/Data/Dungeon/three_0.txt @@ -0,0 +1,17 @@ +6 +32 +2 +6 +13,4 +20,4 +18,6 +20,4 +7,6 +1,2 + +1.d3_stonebeak,0, +1.d3_r200,0, +1.d3_chest_zol,1.d3_map, +0,0, +0,1.d3k1, +0,0 \ No newline at end of file diff --git a/bin/Data/Dungeon/three_1.txt b/bin/Data/Dungeon/three_1.txt new file mode 100644 index 0000000..cde66cf --- /dev/null +++ b/bin/Data/Dungeon/three_1.txt @@ -0,0 +1,11 @@ +2 +4 +3 +3 +4,13,4 +5,17,6 +4,14,4 + +0,0,0, +0,0,0, +0,0,0, \ No newline at end of file diff --git a/bin/Data/Dungeon/three_2.txt b/bin/Data/Dungeon/three_2.txt new file mode 100644 index 0000000..8221ef1 --- /dev/null +++ b/bin/Data/Dungeon/three_2.txt @@ -0,0 +1,17 @@ +34 +8 +4 +4 +7,12,12,8 +20,7,11,16 +15,10,19,16 +4,4,14,4 + +0,0,0,0, +1.d3_r50,0,1.d3_boots,1.d3_nkey, +0,0,0,0, +0,0,0,0, + +2 +d3_wall_1,3,1,19 +d3_wall_2,2,2,17 \ No newline at end of file diff --git a/bin/Data/Dungeon/three_3.txt b/bin/Data/Dungeon/three_3.txt new file mode 100644 index 0000000..d3cf1a2 --- /dev/null +++ b/bin/Data/Dungeon/three_3.txt @@ -0,0 +1,11 @@ +42 +44 +2 +3 +13,4 +20,4 +15,6 + +0,0, +3.d3_nightmare,0, +0,0, \ No newline at end of file diff --git a/bin/Data/Dungeon/two_0.txt b/bin/Data/Dungeon/two_0.txt new file mode 100644 index 0000000..371803c --- /dev/null +++ b/bin/Data/Dungeon/two_0.txt @@ -0,0 +1,21 @@ +10 +12 +6 +8 +5,11,12,12,11,6, +4,20,4,4,14,4, +5,16,4,4,9,8, +14,4,4,4,4,14, +13,4,4,4,4,13, +15,8,11,11,11,16, +4,20,14,15,16,4, +2,1,2,2,2,2 + +1.d2_stonelifter,1.d2_ruby20,1.d2_smallkey_4,0,0,0 +0,0,0,0,1.d2_nkey,0 +0,0,0,0,0,3.d2_genie_killed +0,0,0,0,0,0 +1.d2_stoneBeak,0,0,0,0,0 +0,0,0,0,0,0 +0,1.d2_ruby50,0,1.d2_smallkey_2,1.d2_smallkey_3,0 +0,0,0,0,0,0 \ No newline at end of file diff --git a/bin/Data/Editor/editorIcons4x.atlas b/bin/Data/Editor/editorIcons4x.atlas new file mode 100644 index 0000000..b4c5aa5 --- /dev/null +++ b/bin/Data/Editor/editorIcons4x.atlas @@ -0,0 +1,39 @@ +1 +4 +editor 2d mode:176,0,16,16,0,0 +editor bed:87,2,8,11,0,0 +editor color shift:144,0,16,16,0,0 +editor compass sound:16,16,16,16,0,0 +editor dialog box:112,2,9,11,0,0 +editor door:32,16,16,16,0,0 +editor dungeon:128,0,16,16,0,0 +editor dungeon blacker:192,0,16,16,0,0 +editor egg teleport:32,0,16,16,0,0 +editor enemy trigger:160,0,16,16,0,0 +editor floor:16,0,16,16,0,0 +editor grave trigger:160,16,16,16,0,0 +editor hit trigger:208,0,16,16,0,0 +editor intro:104,3,7,9,0,0 +editor item disabler:96,0,16,16,0,0 +editor jump:48,0,16,16,0,0 +editor key condition setter:144,16,16,16,0,0 +editor key setter:128,16,16,16,0,0 +editor kill trigger:160,16,16,16,0,0 +editor ladder:80,16,16,16,0,0 +editor ladder top:96,16,16,16,0,0 +editor light:112,16,16,16,0,0 +editor music:0,16,16,16,0,0 +editor object hider:208,16,16,16,0,0 +editor object respawner:224,0,16,16,0,0 +editor object spawner:64,0,16,16,0,0 +editor overworld:0,0,16,16,0,0 +editor position dialog:64,0,16,16,0,0 +editor room darkener:176,16,16,16,0,0 +editor script on touch:80,0,16,16,0,0 +editor shadow disabler:112,0,16,16,0,0 +editor shadow setter:80,5,7,7,0,0 +editor shore sound:16,16,16,16,0,0 +editor slow:64,16,16,16,0,0 +editor teleporter:32,0,16,16,0,0 +editor upper level:192,16,16,16,0,0 +editor water:48,16,16,16,0,0 diff --git a/bin/Data/Editor/editorIcons4x.png b/bin/Data/Editor/editorIcons4x.png new file mode 100644 index 0000000..9e62f68 Binary files /dev/null and b/bin/Data/Editor/editorIcons4x.png differ diff --git a/bin/Data/Intro/cloud.png b/bin/Data/Intro/cloud.png new file mode 100644 index 0000000..0185b44 Binary files /dev/null and b/bin/Data/Intro/cloud.png differ diff --git a/bin/Data/Intro/intro.atlas b/bin/Data/Intro/intro.atlas new file mode 100644 index 0000000..8deea03 --- /dev/null +++ b/bin/Data/Intro/intro.atlas @@ -0,0 +1,8 @@ +1 +1 +intro_logo_0:1,1,126,56,0,0 +intro_logo_1:128,1,126,56,0,0 +intro_nintendo:1,58,112,8,0,0 +intro_background:255,1,160,207,0,0 +intro_mountain:416,1,320,207,0,0 +intro_boat:128,63,32,23,0,0 diff --git a/bin/Data/Intro/intro.png b/bin/Data/Intro/intro.png new file mode 100644 index 0000000..848ebe4 Binary files /dev/null and b/bin/Data/Intro/intro.png differ diff --git a/bin/Data/Intro/ocean.png b/bin/Data/Intro/ocean.png new file mode 100644 index 0000000..bf952a1 Binary files /dev/null and b/bin/Data/Intro/ocean.png differ diff --git a/bin/Data/Intro/rain.png b/bin/Data/Intro/rain.png new file mode 100644 index 0000000..5bfa3ae Binary files /dev/null and b/bin/Data/Intro/rain.png differ diff --git a/bin/Data/Intro/waves.png b/bin/Data/Intro/waves.png new file mode 100644 index 0000000..ccda4f4 Binary files /dev/null and b/bin/Data/Intro/waves.png differ diff --git a/bin/Data/Languages/dialog_eng.lng b/bin/Data/Languages/dialog_eng.lng new file mode 100644 index 0000000..f4ffbc4 --- /dev/null +++ b/bin/Data/Languages/dialog_eng.lng @@ -0,0 +1,1158 @@ +// items +smallkey You got a Small Key!\nYou can open a locked door. +compass You've got the Compass!\nNow, you can see where the chests and Nightmares are hidden!\fThis Compass has a new feature-- a tone will tell you if a key is hidden in a room when you enter! +dmap At last, you got a Map!\nPress the SELECT Button to look at it! +stonebeak You found a stone beak!\nLet's find the owl statue that belongs to it. + +sword1 You found your Sword! It must be yours because it has your name engraved on it! +feather You've got the Roc's Feather! It feels like your body is a lot lighter! +pegasusBoots You've got the Pegasus Boots! If you hold down the Button, you can dash! +flippers You've got the Flippers! If you press the B Button while you swim, you can dive underwater! +bracelet0 You found the Power Bracelet! At last, you can pick up pots and stones! +bracelet1 You've got a more Powerful Bracelet! Now you can almost lift a whale! +ocarina You've got the Ocarina! You should learn to play many songs! +powder You got some Magic Powder! Try to sprinkle it on many things! +mirrorShield You've got the Mirror Shield! You can now turn back the beams you couldn't block before! +hookshot You've got the Hook Shot! Its chain stretches long when you use it! +magicRod You've got the Magic Rod! Now you can burn things! Burn it! Burn, baby burn! +shovel You've got a Shovel! Now you can feel the joy of digging! +magicPowder You've got some Magic Powder! Try sprinkling it on a variety of things! +bomb You've got a bomb!\nWay to go! +sword2 You've got a new Sword! You should put your name on it right away! +boomerang You got the Boomerang in exchange for the item you had. + +shield It's a Shield!\nThere is space for your name! +shield_intro You got your shield back! Press the button and repel enemies with it! +shield_back You got your shield back! You can use it to flip enemies! + +yoshiPickup You got a Yoshi Doll! Recently, he seems to be showing up in many games! + +// playing the ocarina without having learned a song +ocarina_bad Well, it's an Ocarina, but you don't know how to play it... +ocarina_bad_marin Not very good... Eh? What? Did I say something? No, you're hearing things... + +// trading alt + 0161 +trade0 You traded your ¡ for ¢! Maybe you can trade the ribbon for something else! +trade1 You exchanged ¢ for £! It's full of juicy beef! +trade2 You gave him £ and got bananas ¤ in return! Good deal! +trade4 You found a stick a monkey left behind...\nYou take it! +trade5 ¥ became the honeycomb ¦! You're not sure how it happened, but take it! +trade6 You exchanged ¦ for §! It's not as sweet, but it is delicious! +trade7 You traded the § for the ¨! +trade8 You traded ¨ for a goat's letter ©! ...Great!? +trade9 You got a Broom as your reward from Mr. Write! But that photo was not of... +trade10 You exchanged ª for the fishing hook «! What will the fishing hook become? +trade11 The « became a necklace ¬! L-l-lucky! +trade12 You returned the necklace ¬ and got a scale ­ of the mermaid's tail. How will you use this? +trade13 You've got the Magnifying Lens! This will reveal many things you couldn't see before! + +// keyholes +keyhole_0 Hunh? A keyhole here?\nIt says, 'Tale Keyhole' +keyhole_1 Hunh? A keyhole here?\nIt says, 'Slime Keyhole' +keyhole_2 Hunh? A keyhole here?\nIt says, 'Angler Keyhole' +keyhole_3 Hunh? A keyhole here?\nIt says, 'Face Keyhole' +keyhole_4 Hunh? A keyhole here?\nIt says, 'Bird Keyhole' + +// collectables +toadstool You pick the toadstool... As you hold it over your head, a mellow aroma flows into your nostrils. +toadstool_hole It's the toadstool you picked in the woods. What is it for? You hold it over your head and a mellow aroma wafts into your nostrils. + +seashell You found a Secret Seashell! If you collect a lot of these, something good is bound to happen! + +heart You've got a Heart! Thump! One of your Heart Containers is filled! + +ruby20 You got 20 Rupees! JOY! +ruby50 You got 50 Rupees!\nVery Nice! +ruby100 You got 100 Rupees!\nYou're Happy! +ruby200 You got 200 Rupees!\nYou're Ecstatic! + +// trendy game +ruby30 It's 30 Rupees! You can play the game three more times with this! + +heartMeter You've got a Piece of Heart! Press SELECT on the Subscreen to see. +heartMeterFilled You collected four Pieces of Heart. Now, you have a complete Heart Container! + +guardianAcorn You've got a Guardian Acorn!\nIt will reduce the damage you take by half! +pieceOfPower You got a Piece of Power!\nYou can feel the energy flowing through you! + +potion You found the secret medicine! You should apply this and see what happens! + +dkey1 You've got the Tail Key! Now you can open the Tail Cave gate! +dkey2 You've got the Slime Key! Now you can open the gate in Ukuku Prairie! +dkey3 You've got the Angler Key! +dkey4 You've got the Face Key! +dkey5 You've got the Bird Key! + +nightmarekey You've got the Nightmare's Key! Now you can open the door to the Nightmare's Lair! + +instrument0 You've got the Full Moon Cello! +instrument1 You've got the Conch Horn! +instrument2 You've got the Sea Lily's Bell! +instrument3 You've got the Surf Harp! +instrument4 You've got the Wind Marimba! +instrument5 You've got the Coral Triangle! +instrument6 You've got the Organ of Evening Calm! +instrument7 You've got the Thunder Drum! + +instrument0Collected {...SWAMP...}{A path opens...}{in the blooms...} +instrument1Collected {...PRAIRIE...}{...PRAIRIE...} The Prairie is waiting... +instrument2Collected {...WATERFALL...}{It is hidden in the}{waterfall...} +instrument3Collected {...BAY...}{Your road goes into the}{bay...} +instrument4Collected {...SHRINE...}{An island secret in the}{shrine...} +instrument5Collected {...MOUNTAIN...}{Something calls...}{from the mountains...} +instrument6Collected {...OCARINA...}{The music of the Ocarina}{leads...} +instrument7Collected {...EGG....}{The Egg on the mountain}{calls!} + +goldLeaf You've found a Gold Leaf! Press SELECT to see how many you've collected! +goldLeafLast At last! You've got the final Golden Leaf! Now go and see Richard about that key... + +// ° ± ² ³ +// <- alt + 0176 +// -> 0177 +// v 0178 +signpost0 error +signpost1 ± Tail Cave\n² Toronbo Shores +signpost2 Mysterious Forest\n(It's a little bit\n mysterious) +signpost3 East ± Ukuku\n Prairie\fFarther East\n Animal Village +signpost4 Beware of Sea Urchins!\nDon't touch them with your bare hands! +signpost5 Beware of floors with cracks! A heavy person should not stand on them! + +signpost6 Kanalet Castle 10 Min. ± ³ +signpost7 Kanalet Castle 5 Min. ± +signpost8 Kanalet Castle 50 Paces ³ + +signpost9 ± Animal Village\n² Martha's Bay +signpost10 Seashell Mansion + +signpost11 You're close to Tal Tal Heights. The Camera Shop is nearby. +signpost12 ± Tamaranch Mt.\n° Goponga Swamp +signpost13 ± Crazy Tracy\n² Manbo's Pond +signpost14 ± Cemetery\n² Ukuku Prairie +signpost15 ± Gopongo Swamp\n² Mysterious Forest + +signpost16 DANGER!\nKeep out!\n(Except BowWow) +signpost17 Richard's Villa +signpost19 Telephone Booth\n² Signpost Maze + +signpost20 Mt. Tamaranch +signpost21 Do you want to challenge the river rapids on a raft? Proceed to the office at once, please! + +signpost22 Entrance to\nYarna Desert ± +signpost23 ± Welcome to the\nAnimal Village! + +signpost_Down ² GO THIS WAY +signpost_Up ³ GO THIS WAY +signpost_Right ± GO THIS WAY +signpost_Left ° GO THIS WAY +signpost_TryAgain TRY AGAIN FROM THE START +signpost_Great GREAT! YOU DID IT! YOUR REWARD IS ± THIS WAY! +signpost_Gone GONE ON TOUR\nMAMU + +talking_tree Well that was a surprise! Hey! I'll tell you a secret! Use your sword to poke at dungeon walls... If you hear a hollow clank, you can break the wall with a Bomb! + +mamu0 Ribbit! Ribbit! Hey, man, I'm Mamu, on vocals! Brother, you look like you don't know squat about music! Ribbit! +mamu1 Ribbit! Ribbit! I'm Mamu, on vocals! But I don't need to tell you that, do I? Everybody knows me! Want to hang out and listen to us jam? For 300 Rupees, we'll let you listen to a previously unreleased cut! What do you do? +mamu2 Well, that's a shame, but we don't play for free! +mamu3 Thank you... Thank you very much... Croak! +ocarina_frog_song You've learned The Frog's Song of Soul! It's a very moving tune... It can even liven up unliving things! +ocarina_frog_song_end If you play this song, you'll make everything around you feel more alive! + +manbo0 I am Manbo, child of the Sun Fish! Have you got an Ocarina? +manbo1 Very well...\nGlub Blub Bloop! +manbo2 Ahaha! Then I can teach you my song! Bloop! +manbo3 Aha... You don't have an Ocarina, so... Glub glub! +manbo4 I am Manbo, child of the Sun Fish! When you play my Mambo, you can warp to Manbo Pond! Try this tune in the dungeons, too! Cha-cha-cha! + +ocarina_manbo_song You've learned Manbo's Mambo! When you get out of the water, play it! + +choice_Pay Pay +choice_Leave Leave + +signHead1 THE WIND FISH IN NAME ONLY, FOR IT IS NEITHER. +signHead2 MUSIC, THE FISH STIRS IN THE EGG YOU ARE THERE... +signHead3 SEA BEARS FOAM, SLEEP BEARS DREAMS. BOTH END IN THE SAME WAY CRASSSH! +signHead4 SECRETS ARE LIKE WATER WHEN IT COMES TO BRIDGES +signHead5 THE WIND FISH SLUMBERS LONG... THE HERO'S LIFE GONE... +signHead6 AROUND HERE, SECRETS ARE NIGH +signHead7 You are near the Eagle's Tower. Beware of the bird! +signHead8 NOW YOU NEED LOOK FAR FOR A SECRET... +signHead9 IN SOIL SLEEPS SECRETS, BENEATH YOUR SOLES... + +castle_button Hunh? It sounds like the castle gate opened! You can easily leave the castle now! + +door_nightmarekey Eh? It's locked! You can open the door with the Nightmare Key. + +dungeon_keyhole_block Hunh? This rock has a key hole! You should come back with a key! +rock_cracks_message This rock has many cracks... There must be some way to shatter it... +crystal_hard Oh? What a weird object! There must be some way to tackle this obstacle. + +stone Wow! This looks pretty heavy! You won't be able to lift it with just your bare hands... + +// nightmares +nightmare1 {BUZZZZZ! BUZZZZ!}{OUTZZZIDER!} +nightmareFinal0 This island is going to disappear... Our world is going to disappear... Our world... Our... world... +nightmareFinal1 ...[NAME], you have beaten all the Nightmares! Climb the stairs before you! + +// maria +maria_0_0 What a relief! I thought you'd never wake up! You were tossing and turning...\fWhat? Zelda? No, my name's Marin! You must still be feeling a little woozy.\nYou are on Koholint Island! +maria_0_1 Follow the lane south to reach the beach where I found you. Since you washed ashore, lots of nasty monsters have been in the area, so be careful, okay? + +// marin standing outside +maria_1_0 Hi! Tarin went to the forest to look for toadstools, but I'd rather sing. Listen to this, it's called the 'Ballad of the Wind Fish.' +maria_1_1 I just love to sing-- what can I say? What do you like to do, [NAME]? + +// after talking to the owl +maria_1_2 [NAME], Tarin's taking a nap at home. I don't know how he can sleep on such a nice day! It makes me want to sing a song... Yes, the song is 'Ballad of the Wind Fish!' + +// singing in the right village +maria_1_3 Hey! That's a nice Ocarina you have there! Will you accompany me as I sing? +maria_1_4 So, how do you like it? It's really touching, isn't it? Does it stick in your mind? +maria_1_5 Please! I want you to learn it! This song is my favorite! + +maria_1_6 Please remember this song! You should play it every once in a while to keep it fresh in your mind! +maria_1_7 Please, don't ever forget this song...or me... + +maria_1_8 They say the 'Ballad of the Wind Fish' is a song of awakening. I wonder, if the Wind Fish wakes up, will he make my wish come true? +maria_1_9 Oh, [NAME]. I often come to this village to sing, too! It seems that just about everyone loves my 'Ballad of the Wind Fish!' [NAME], what is your favorite song? + +marin_letter At the beach... Marin ¶ + +// maria at the beach +marin_2_0 Oh, [NAME], I'm glad you found this place. Will you stay and talk to me for a while? +// Yes! No... +marin_2_1 Okay, I'll just watch the waves for a while... +marin_2_2 I wonder where these coconut trees come from? ...Tarin says there is nothing beyond the sea, but I believe there must be something over there... When I discovered you, [NAME], my heart skipped a beat! I thought, this person has come to give us a message... +marin_2_3 ... ... ... ... ... ... ... ... If I was a sea gull, I would fly as far as I could! I would fly to far away places and sing for many people! ...If I wish to the Wind Fish, I wonder if my dream will come true... ... ... +marin_2_4 Hey! Are you listening? [NAME], are you listening to me? +marin_2_5 Humph! Your head is always in the clouds! Will you please listen to me next time?! +marin_2_6 I want to know everything about you...Err...Uhh, Ha ha ha ha! +marin_2_7 Hunh? The walrus wants me to go to him? It doesn't matter, I will go with you to him... + +maria_collected You got Marin! Is this your big chance? + +// going into a dungeon +marin_dungeon Eh? You want me to go in there? No, I think I'll wait out here... Take care of yourself, [NAME]! +marin_dungeon_leave [NAME]! You're back! Are you hurt? +marin_dungeon_leave_time ...You're late! I thought you'd never come back! +marin_dungeon_hearts ...EEEK! You're hurt! Arrrgh! Don't be so reckless! +marin_dungeon_hearts_alt ...You idiot! I told you this would happen... Eh?! What? I didn't say anything, really! + +marin_cucco_0 Ha ha ha! Do it! Do it! Do it moooore! ... ... Hunh? No, it's nothing... I didn't mean it. +marin_cucco_1 No! No! Poor hen!\nStop that! + +marin_pot_0 Yes!! Yes!! Break them! Break them all! ... ... ... ... What? What's wrong? +marin_pot_1 Ahhh! Ahhh, you are a bad boy, [NAME]! + +marin_digging Great! Dig it! Dig it! Dig to the center of the earth!! + +maria_game_0 Wow! [NAME], can I try this?! What do you say? +// Okay No Way +maria_game_1 C'mon! I want to do it! Can I? It looks so fun! +// Yes Okay +maria_game_2 You're good! You're a pro, aren't you? ... ... ... ... Well, beat it! Pros aren't allowed in here! + + +// walrus sequence +maria_3_0 Yes, it's that lazy walrus! Shall we give him a little surprise? +// Yes No... +marin_3_1 You're right, it would be mean to wake him up now! Let's let him sleep some more! +maria_3_2 Aha ha ha! Wow! He certainly woke with a start! +maria_3_3 Hunh? Oh, he's calling me... It's the same as always... Ha ha! +maria_3_4 [NAME], I'm going to the Animal Village! Please drop by, okay? + +// marin falling into the fountain not falling on link +marin_fountain Whew! What a surprise! + +// marin in the mountains +marin_4_0 Somebody, HELP! +marin_4_1 Hey! [NAME]! Some monsters put me up here! What should I do?! I'm afraid of heights!! +marin_4_2 Yow! That was a surprise! [NAME], thank you! +marin_4_3 ... ... ... ... ... ... ... ... Say... [NAME] ... +marin_4_4 Uhh... I don't know how to say this... but... +marin_4_5 MAAAAAAARINNNN!! +marin_4_6 Hunh?! Tarin??! ... ... ... ... Uh... Nevermind, I... I gotta go! + +marin_5_0 Thank you for everything! [NAME], you are the kindest boy I know. One day I made a wish to the Wind Fish... What was the wish? It was... No, it's secret! +marin_5_1 [NAME], some day you will leave this island... I just know it in my heart... ...Don't ever forget me... If you do, I'll never forgive you! + +walrus_0 {ZZZ ZZZ ZZZ ZZZ}{... ¶ ... ¶ ...} +walrus_1 {Arfh! Arfh! Arf!}{¶ ¶! ¶ ¶!}{..... ·??} + +animals_absorbed {... ... ... ...}It seems to be totally absorbed in Marin's song! + +ocarina_maria_song You've learned the 'Ballad of the Wind Fish!' This song will always remain in your heart! + +// tarin house +tarin_chest Hey! What are ya doin' in my chest?! Where'd you learn ta do such a thing?! + +// tarin +npc02_leave Whoa, boy! Where ya off to in such a hurry? Sit a spell, I got somethin' to tell ya! +tarin_0 Well, [NAME], ya finally snapped out of it... Name's Tarin... Hope yer feelin' better... What? How did I know your name? You think it's weird, eh? Well, I saw it on back of this shield! +tarin_1 Oh, yeah... Some other stuff like this washed up on the beach... If'n you go look watch out for monsters! Ever since you showed up, [NAME], I've seen 'em all over the place! + +// after the raccoon transformation +tarin_raccoon_2 The last thing I kin remember was bitin' into a big juicy toad-stool... Then, I had the darndest dream... I was a raccoon! Yeah, sounds strange, but it sure was fun! +tarin_raccoon_3 I'm all tucker'd out... I think I better set a spell before I head home... + +tarin_2 I'm tired... I'm goin' ta sleep now... Zzzzzz... +tarin_3 Hrrrm...Snore... Hunh?... If'n ya don' know...call old man Ulrira! Zonk...Snore... + +// tarin with the bananas +tarin_4 I was hungry somethin' fierce so I went and got bananas at the beach... [NAME], if you want some, you should go and get some! + +// tarin trading sequence +tarin_stick Oh?! [NAME], I see ya have a nice stick... Can I borrow it for a second? +tarin_stick_no Hmmm, [NAME], you are mean! + +// after the trading sequence sleeping in the bed +tarin_5 Unnnngh! Owwwww! ... ... ... ... I've sure lost my taste for honey! + + +// lady with the broom +npc_broom_0 YAHOO! I'm fine, and you?! +npc_broom_1 YAHOO! I worked too hard and now my broom is worn to the handle! +npc_broom_2 YAHOO! YAHOO! A new broom?! For me? It is, isn't it?! +npc_broom_3 Okay! In return you can have this fishing hook I found when I swept by the river bank! +npc_broom_4 YAHOO! A new broom! Superb! +npc_broom_5 Then YOU sweep the island! +npc_broom_bowwow She's had an awful tragedy in the house across the way! It's just awful, and all I can do is sweep! + +npc04 Er...Uh...Hmm...How to say... Please call... Outside... ... +npc04_game It seems that old man Ulrira is a shy guy, in person... + +// kid with hints +//npc05_0 Hey, man! When you want to save just push all the Buttons at once! Uhh... Don't ask me what that means, I'm just a kid! +npc05_1 Well, it seems that after you save, you will start at the last door you went through... I'm not really sure why that is 'cause I'm just a kid! +npc05_2 I heard that you can press SELECT to look at the island map... But, I don't understand what they mean by that... +npc05_3 When you're running out of Hearts, you'd better enter a house or cave... Why? I have no idea, I'm just a kid! + +npc_ball_left Where are you from, brother? ...Outside the island? What is 'outside?' I've never thought about it... +npc_ball_right The giant egg on top of Tamaranch Mountain? They say the Wind Fish is sleeping inside of it... Why? I don't know either... + +// kid near the weather bird or next to the shop +npc_boy_island Dude! You're asking me when we started to live on this island? What do you mean by 'when?' Whoa! The concept just makes my head hurt! +npc_boy_marin Hey, dude! What do you think of Marin? Uhh... I don't know, I'm just a kid! +npc_boy_shrine Hey hey, bro! About the Dream Shrine there... They say there's something good inside... ... I better not say anything else as I'm just a kid! +npc_boy_marin_beach Marin? She likes to go stare at the ocean all by herself... Why? Hey, I'm just a kid, don't ask me! +// kids while marin is with link +npc_boy_marin_following Hey... Where're you two going together? Hunh? Uh, I didn't mean anything... I'm just a kid! +npc_boy_marin_gone Hunh?! Marin's not with you? What happened to her? + +// when the player has the broom and the grandma is in the other village +npc_boy_grandmother Grandma's not here. She's in the Animal Village. That's what Grandpa Ulrira said on the phone! + +// kids playing ball game after the village gets attacked +npc_kid_attacked Hey buddy! It's serious! Yeah, really serious!! Yeah, it is! The Moblins came to the village! Yeah, that's right! A whole gang of Moblins! Then... It's for real! They all went to the house... Yeah, that house, and then they did something at Bow Wow's house!! It was a really bad scene, with the M-m-moblins! So, I mean, ahh! ... ... ... ... ... ... ... ... It might be faster to find out for yourself what happened! + +// chef in the right village +npc_chef_0 My ultimate plan is to open a branch in Mabe Village! +npc_chef_1 Rik'm rak'm! I ran out of ingredients! If I had honey, I could make this fit for a king! +npc_chef_2 Hi ho! Hey you! Is that possibly a ¦ you have? I just ran out! Will you swap it for a pineapple? +npc_chef_3 That's a crying shame, but I realize those are a rare delicacy! +npc_chef_4 Hi ho! Yeah, I know, that tub of goo is asleep right in the way to Yarna Desert! Once he's asleep he won't budge for a loooooonng time. But hey! Take Little Marin and wake him up with her song! That slob would wake up with a jump if he heard her sing, for sure! Heh heh heh! +npc_chef_marin HI HO! Little Marin! Welcome! ... ... ... ... Oh, shucks! You are here too... Sorry... + +// yoshi doll +npc07_0 Because they all look alike, even I am sometimes confused... +npc07_1 By the way, my baby wants a Yoshi Doll. I saw one at the Trendy Game, but I couldn't get it. +npc07_2 Oh! Will you give that doll to my baby?! +npc07_3 Tsk tsk... What a shame... +npc07_4 Oh thank you! You are indeed a generous person! Ah! I will give you this in return! +npc07_5 My husband is lost in the woods! Please go find him! + +npc_house_chest [NAME] checked the chest.\nWow! This is a nice chest! +npc_house_chest_marin [NAME], do you always look in other people's drawers? + +npc_letter_boy_0 Well... I pretty much stick to myself, me and my letters... My name's Write! The only thing I don't like about my hobby is that I never receive a response... +npc_letter_boy_1 What's this?! A letter for me?! I'm so happy! ...And look! The letter came with a photograph! +npc_letter_boy_2 Mmm... She's so beautiful... I must give you something for your trouble... Hmm... Well, it looks like all I have is this broom... how'll that be? +npc_letter_boy_3 Please! I really must insist you have this ª! +npc_letter_boy_4 Oh boy! Letter writing is such a great hobby! +npc_letter_boy_5 Hello! I'm writing back to Christine now! + + +npc_letter_girl_0 You don't know the proper etiquette when dealing with a lady, do you? You should have brought flowers or something, then I might be more inclined to talk with you... Oh yes, in my case, hibiscus are best... +npc_letter_girl_1 Oh, you brought me a hibiscus! How sweet! Well, since you are such a gentleman I have a request to make of you. Will you listen? +npc_letter_girl_2 I would like you to take this letter to a Mr. Write who lives on the border of the Mysterious Forest, please! +npc_letter_girl_3 ...Is that so? And I thought you were a gentleman... +npc_letter_girl_4 You know, sometimes I can't help eating a delicious piece of paper, even if it's a letter to my darling Mr. Write... How embarrassing! + +// fisher under the bridge +npc_bridge_0 It's no use, little buddy! A fish took my hook... I keep casting my line into the water, but I haven't got a bite... I thought this would happen... +npc_bridge_1 Oh! What is that you have in your hand? It's not a fishing hook, is it? You had better let me have it. I'll give you my next catch if you let me have it... +npc_bridge_2 You should be more kind to me! I thought we were buddies! +npc_bridge_3 Keep your eyes open and watch a pro at work. +npc_bridge_4 My, that's a BIIIIG one! +npc_bridge_5 I can't wait to see what I'll catch next! + + +tracy_give Give +tracy_dont Don't + +npc_tracy_0 Hi there, big guy! I'm Crazy Tracy! I've got a little secret for sale that'll pump you up! +npc_tracy_1 Will you give me 28 Rupees for my secret? +npc_tracy_2 How about it? 42 Rupees for my little secret... +npc_tracy_3 ...You're so cute!\nI'll give you a 7 Rupee discount! +npc_tracy_4 All right, come here and I'll rub it on you! ...There... I've applied my own secret medicine! It will take effect when you lose all heart! Drop by again, big guy! +npc_tracy_5 Beat it, then! Come back when you have some cash! +npc_tracy_6 ... ... ... ... But I won't sell it to you! +npc_tracy_7 Well! I'm only offering you a secret that will make you strong! You're such a chicken!! +npc_tracy_8 Here's some bonus treatment! Behold! Your Hearts are full! + + +// npc lost boy +npc_lost_boy_0 Yep, Papahl got lost, just like he said! Now, I am so famished I can't move! Can you give me some vittles? +npc_lost_boy_1 You're one cold hombre... +npc_lost_boy_2 This § is so delicious! I'm going to eat the § right now! Bon Appetit! +npc_lost_boy_3 AH! This isn't meant to be a reward... Here, take this ¨! It's a hibiscus! +npc_lost_boy_4 Delicious! Yum! I'm filled with energy, now! + + +// mermaid +npc_mermaid_0 When I was swimming in the bay, the waves took a very important necklace from around my neck! If you find it, I will let you take a scale from my tail! +npc_mermaid_1 I have already looked around here! +npc_mermaid_2 Ahh! That's it! That's my necklace! Give it! Give it back! I will give you a scale as I said! +npc_mermaid_3 Promise! You'll only take one! +npc_mermaid_4 You are heartless and cruel! +npc_mermaid_5 An artist once asked me to pose for him, and he wanted a scale, too... Can the legend of the Magnifying Lens be true...? + +// mermaid statue +mermaid_statue_0 THE MOURNING MERMAID By SCHULE? ...A scale is missing... +mermaid_statue_1 You put the missing scale in the mermaid statue! + + +// rabbit +rabbit_0_0 Hey! Did ya know Animal Village and Mabe Village are sister cities? Yes, even though they aren't large enough to be called cities... Anyway, I heard from a very good source that they have a Dream Shrine in Mabe, and that it has something good inside... Is that true? +rabbit_0_1 I dreamed that I turned into a carrot last night... What an odd dream... + +rabbit_1_0 I can't go to Mabe Village because of all the monsters. I hope Marin is all right. +rabbit_1_1 Eh? How can an animal talk? How? Hey, I'm just a rabbit, so I don't know! + +rabbit_2_0 Yarna Desert? There's a way to get there to the south, but you might not be able to get through if that lazy walrus is in the way! +rabbit_2_1 Have you heard of the Flying Rooster? They say it lived in Mabe Village a long time ago... I wonder if it's true... + +rabbit_3_0 Ahhh... Sigh... On such a nice day, we need a song from Marin! +rabbit_3_1 Aaaah, Little Marin... I want her to come back again...Her song is the best... + +rabbit_marin Ahhh! It's her!\nLittle Marin!! + + +// dialog choices +choice_Yes Yes +choice_YES YES +choice_Yes! Yes! +choice_Okay Okay +choice_Yeah Yeah +choice_Fine Fine + +choice_No No +choice_NO NO +choice_No... No... +choice_No! No! +choice_N-No N-No +choice_No_Way No Way +choice_No_way No way +choice_Not_Now Not Now +choice_Nope Nope +choice_Give Give +choice_Keep Keep +choice_Dont Don't +choice_Can Can +choice_Cant Can't + +choice_Fish Fish +choice_Cast Cast +choice_Look Look + + +npc08_0 Yep! Those're my boys! I'm Papahl, please to meetcha! I'll be lost in the hills later, so keep a look out for me, hear? +npc08_1 I've got to say, thanks again! + +// bowWow girl +npc09_0 Ho ho ho! My BowWow is so proud of his fine fur coat! +npc09_1 AIEEEEEEEE! It's terrrrible! My BowWow was dognapped by... Mo-mo-MOBLINS!! OHHH! AHHHH! Please! Somebody help my poor BowWow!! +npc09_2 Oh thank you! I'm so happy you brought my baby back! Now, would you be a dear and take him for a walk? It would really help me out a lot! You will?! Thanks! +npc09_3 Ho ho ho! I really appreciate what you did for my poor, precious BowWow! You are such a nice boy! How can I ever repay you? I know...\fSMOOOOOOOCH!\nYou got a reward from Madam Meow-Meow... ... ...\nL-l-lucky! + + +// bowWow +bowWow2 YIP YIP!\nYIP YIP! + +bowWow3_0 Make-up! Jewels! Dresses! I want it all! sigh... And some new accessories would be nice... +bowWow3_1 Oh! That Ribbon! I need it! Will you trade for my dog food? + +bowWow3_2 Eh?! I can't believe it! You are the worst!! +bowWow3_3 Lucky! Thanks!\nWell, here's your £! + +bowWow_dig WOOF! Dig! RUFF! + +npc_trendy_open TRENDY GAME!\nOne Play 10 Rs. +npc_trendy_no_cash Sorry kid! You don't have the Rupees! Come back when you have the cash! +npc_trendy_start The A and B Buttons move the crane... The rest is just timing! Go over to the buttons to play! Good Luck! +npc_trendy_again Challenge Again? +npc_trendy_closed We're closing up for today! Come again, anytime! +npc_trendy_good_luck Good Luck! + +npc_trendy_play Play +npc_trendy_no_play No + +// 0176: < +npc_fisherman_0 How about some fishing, little buddy? +npc_fisherman_choice I'll only charge you 10 Rupees... +npc_fisherman_1 You have to have more passion! Live a little! +npc_fisherman_2 You're short of Rupees? Don't worry about it. You just come back when you have more money, little buddy. +npc_fisherman_3 Okay, here's how you do it. Use ° and ± on the ´ to aim a cast. Once you hook a fish, press the Button rapidly to reel him in! +npc_fisherman_4 Why not try one more time, little buddy? +npc_fisherman_5 Wow! That one got away!\nWant to try again? +npc_fisherman_6 Wow! Nice Fish! It's a lunker!! I'll give you a 20 Rupee prize! +npc_fisherman_6_1 Try again? +npc_fisherman_7 It's a runt! I'll only give you a 5 Rupees prize for that. +npc_fisherman_7_1 You should try again! + +npc_fisherman_8 Oh! It's a big one! And it has a Piece of Heart, too! You get a 20 Rupee prize on top of that! +npc_fisherman_8_full Oh! It's a big one! And it has a Piece of Heart, too! You have completed another Heart Container! On top of that, you get a 20 Rupee prize! Want to try again? + +npc_fisherman_8_1 Try again? +npc_fisherman_9 This pond's all fished out. +npc_fisherman_9_1 Why not try your luck in the sea? +npc_fisherman_10 Did I say that? Forget it, okay? Run along now... + + +// npc raft +npc_raft_0 Want to go on a raft ride for a hundred Rupees? +npc_raft_1 Okay, the raft is ready for you outside! Enjoy! +// same string as for the fisherman +npc_raft_2 You're short of Rupees? Don't worry about it. You just come back when you have more money, little buddy. + +// frog boy +npc_frog_boy_0 Salutations! You wouldn't know by the look of me, but I used to live in the castle! My servants went berserk and I was forced to flee to my villa... So, you want the key to Ukuku Prairie, do you? I may be able to help you... Let's make... a deal, shall we? I want you to retrieve the Golden Leaf I left behind in the castle when I fled... + +npc_frog_body_impressed I am impressed. There are five leaves in all. Remember to buy a shovel on your way back. +npc_frog_body_coward Well, I never! I thought you looked cowardly, but... Please, leave me... just get out here! + +npc_frog_body_please Ah! Bonjour! [NAME], for the love of justice, and my own sake, you must find all the leaves! + +npc_frog_body_bien Ahh! Tres Bien! I see you have recovered all of the leaves! Now, move this box and you will find your reward! +npc_frog_body_debt I am forever in your debt for getting my leaves back! + +npc_frog_body_bowwow Ahem! Really, I must insist that you not bring that awful beast in here! Leave that creature outside and then we can talk! Good Bye! + +npc_zora If you keep me a secret, I'll tell you something useful. Go to Toronbo Shores, use the magnifying glass and you will find someone like me. + +alligator_0 Welcome to Sale's House O' Bananas! I'm Sale, this is my house! Actually, my hobby is collecting rare and unusual canned food. My brother is an artist, so I guess strange hobbies run in the family! +alligator_1 What's that you have?! It's canned food! For heaven's sake, man, give that £ to ME!! PLEASE! +alligator_2 He's hysterical! What do you do? +alligator_3 I don't suppose it would do any good to beg? Well, if you change your mind, tell me. +alligator_4 Oh thank you! I'll take that! +alligator_5 MUNCH MUNCH!! ... ... ... ... That was great! I know it's not a fair trade, but here's some bananas! YUM... +alligator_6 Thank you again! That was yummy! +alligator_7 Hey friend! Have you ever ridden the rapids on a raft? You can, near Tal Tal Heights! You ought to try it! + +witch_0 Double double, toil and trouble a toadstool mix makes powder for tricks! +witch_1 Ahhh... It has the Sleepy Toadstool, it does! We'll mix it up something in a jiffy, we will! +witch_2 It's all ready, it is! Take care, as there's not much there! Why not try a bit in my hut? +witch_3 Good job! Use it on your enemies and see what happens. If you run out, go to the forest, pick some mushrooms, and I will make you more. + +cukeman_0 Hey Mon! +cukeman_1 You know me, I like short names the best... +cukeman_2 It can display millions of polygons! +cukeman_3 I definitely need it, as soon as possible! + +fairy_0 Let's heal your wounds and get rid of all that stress... Close your eyes and relax... + + +// general dialog not used in the actual game +itemShop_dialog [itemShopItem]\n[itemShopPrice] Rupees! +itemShop_bow Bow & Arrow Set Only 980 Rupees! +itemShop_arrow 10 Arrows 10 Rupees +itemShop_shovel Deluxe Shovel 200 Rupees! Seems expensive! +itemShop_hearts Three Hearts 10 Rupees! +itemShop_shield Shield 20 Rupees! +itemShop_bomb Ten Bombs 10 Rupees + +itemShop_buy Buy +itemShop_dont Don't +itemShop_no_way No Way +itemShop_no_way! No Way! + +// shopkeeper +shopkeeper_0 Hey! Welcome! See anything you like?! Just bring it here! +shopkeeper_1 Thanks a lot! And come again! +shopkeeper_2 Sorry kid! You don't have the Rupees! Come back when you have the cash! +shopkeeper_3 Aye Caramba! Kid, you have a lot to learn, trying to buy something you have no use for! +shopkeeper_4 Hey! You! Stop! You gotta pay! Put it back! +shopkeeper_5 Guess what? You got it for free. Are you proud of yourself? + +itemShop_revenge I wasn't kidding when I said pay! Now, you'll pay the ultimate price!! + +weatherBird Here Sleeps The Flying Rooster + +rooster_0 Wow! The Rooster has recovered! He seems very friendly! + +// ghost that follows link +ghost_0 {...the house...}{...take me...}{...the house...}{...at the bay...} +// trying to enter a dungon +ghost_1 {...N-N-No!...}{...N-not there!} +ghost_2 {...Here!...}{...enter...}{...my house...} +ghost_3 {...Nostalgia...}{...unchanged...}{...boo hoo...} +ghost_4 {...Enough...}{...cemetery...}{...take me...}{...my grave...} +ghost_5 {...my grave...}{...take me...}{...my grave...} +ghost_6 {...Thank you...}{...a jar...}{...in my home...}{...look inside..}{...bye...bye...} + +ghost_grave_powder Cough Cough... Don't sprinkle that on me... ...I'll have to curse you! Cough Cough... + + +// == owl == +owl_1_0 Hoot! Hoot!\nSo you are the lad who owns the sword...\fNow I understand why the monsters are starting to act so violently...\fA courageous lad has come to wake the Wind Fish...\fIt is said that you cannot leave the island unless you wake the Wind Fish...\fYou should now go north, to the Mysterious Forest.\nI will wait for you there! Hoot! +owl_1_1 Hoot! Ho, brave lad, on your quest to wake the dreamer! Welcome to the Mysterious Wood! Much of mystery you will find on this uncharted Koholint island! I'm afraid you may find it a trifle difficult to leave the island while the Wind Fish naps. ...By the by, have you ever visited the Tail Cave, which is south of the village? Go there with the key you find in this forest... The Wind Fish is watching... Hoot! +owl_1_2 Hoot! Take the key and go to the Tail Cave. Retrieve the Instrument that is hidden there! Go now! The Wind Fish is waiting! Hooot! + +owl_2_0 Hoooot! That is an 'Instrument of the Sirens!' I have to admit, at first I did not believe you were real... That Instrument, along with the seven others in the set, has the power to wake the Wind Fish! You must collect them all! I was instructed to give you directions... Your next goal is north, in Goponga Swamp!! Hoot, indeed! +owl_2_1 Hoot! That is a fearsome looking animal you have there! Do not forget, the next Instrument is in Goponga Swamp! + +// post dungeon 3 +owl_3_0 Hoot! How many Instruments have you gotten so far? When you play the Instruments in front of the Egg, the Wind Fish will wake and you will leave this island. Now, you must hasten to the Yarna Desert! The dark, monstrous inhabitants of the sand will show you the way! Hoot Hoot! +owl_3_1 Hoot! The shape of the key shows a fish, swimming up a cascade of water! Go now to the mountain waterfall! A leap from the top and you will reach your goal! + +// at the grave of the ghost +owl_5_0 Hoot! It has been some time since our paths crossed, lad. You must dive into the waters of Martha's Bay to enter the Catfish's Maw... The closer you get to the Wind Fish, the more restless he sleeps. Carry onward! Hoot! + +// owl sitting infront of the egg on the stairs +owl_stairs Hoooot! The Wind Fish sleeps long and dreamily in the Egg above... When you play the eight Siren Instruments in front of the Egg he will awaken. This, my friend, is the only way for you to leave the island! Hoo! + +// pre dungeon 6 +owl_6_0 Hoot! There are two shrines, one to the north, the other to the south. First, head south, where ancient ruins speak of the Wind Fish... You will learn much there... +owl_6_1 Hoot! I see you have read the relief... While it does say the island is but a dream of the Wind Fish, no one is really sure... Just as you cannot know if a chest holds treasure until you open it, so you cannot tell if this is a dream until you awaken... The only one who knows for sure is the Wind Fish... Trust your feelings... Someday you will know for sure... + +// after dungeon 6 +owl_7_0 Hoot! The many monsters of this island fear that the Wind Fish is about to awaken! The monsters' power is real! They may conquer the island and destroy their foes! That day may come soon! Now, go to the mountain tower! Fly like a bird! Hoot! Hoot! +// after dungeon 6 on the mountain entry +owl_7_1 Hoot hoot! Your path is not easy, but you are almost there. Go east. The Wind Fish is getting restless. + +// after saving marin +owl_8_0 Hoot! That girl sang her song in front of the Egg! Her 'Ballad of the Wind Fish' is a song of awakening! Did she actually intend to wake the Wind Fish?! The next Sirens' Instrument is in the west. Play your melodies so the unliving stones might hear! Show your courage! The Wind Fish waits for you! Hoot! + +// after opening the egg +owl_9_0 The time has come... The Wind Fish awaits... Enter the Egg... Hoot! Hoot! + +owl_final Hoot! Young lad, I mean... [NAME], the hero! You have defeated the Nightmares! You have proven your wisdom, courage and power! ... ... ... ... As part of the Wind Fish's spirit, I am the guardian of his dream world... But one day, the Nightmares entered the dream and began wreaking havoc. Then you, [NAME], came to rescue the island... I have always trusted in your courage to turn back the Nightmares. Thank you, [NAME]... My work is done... The Wind Fish will wake soon. Good bye...Hoot! + + + +// raccoon in the forest +raccoon_0 As a raccoon, my nose is verrry sensitive, ta stuff like dust and powder... +raccoon_1 Heh heh heh ho! You're goin' ta be lost, thanks to me! Heh heh! + +dog GRRRR... + +desert_bone_0 Ahhh... Yess... That dust was so refreshing... For that, I'll tell you a hint! Use a Bomb in a place where the sand swallows you... There is a treat on the other side of the wall... Bye! + +// chicken dude in the mountains +chicken_dude_0 Chickens these days don't have the fighting spirit they used to! In the old days, they could fly, flap flap! But now, see? Cluck cluck! +chicken_dude_1 Wow! Amazing! That rooster is actually flying! It's just like I said, eh? Have you tried to hold him over your head? Cluck Cluck! +chicken_dude_2 Wooo! Finally! This flying rooster is the greatest! + +// hidden npc that trades the boomerang +npc_hidden_0 I found a good item washed up on the beach... I'll trade it to you for what you have in your B Button... +npc_hidden_1 Okay, let's do it! When you don't want the Boomerang anymore, come back! +npc_hidden_2 Oh, yeah, uh... okay, whatever. +npc_hidden_3 Give me back the Boomerang, I beg you! I'll return the item you gave to me! +npc_hidden_4 The item came back to you. You returned the Boomerang. +npc_hidden_5 Ah... Don't give me that item... How about something else? + + +// bat in cave +npcBat_Intro Hey, Kid! You woke me up from a fine nap!! ...Thanks a lot!\nBut now, I'll get my revenge!\nAre you ready?! +npcBat_End Heh Heh Heh! You deserve it! Now look at all that junk you have to carry!\nHah! Take care! See you again! + +npcBat_Powder I'll let you carry more Magic Powder! He He! Are you ready?! +npcBat_Bombs Okay, I'll let you carry more Bombs! He He He! Are you ready?! +npcBat_Arrows Fine, I'll let you have more arrows! Heh Heh! Are you ready?! + +bat_yes + +book Read this book? +book_read Do you want to read this book? +book_realy_read Do you really want to read it? + +book_yes YES +book_no NO +book_look Look +book_dont Don't + +bookcase This is not a chest... What? You knew that? Okay. + +book1_0 'Selecting The Item That's Right For You' +book1_1 'You can select your favorite item for the A and B Buttons on the Sub-Screen. Using different items, you can fight without a sword! Try many different things to find what's right for you!' + +book2_0 'Auto Map And Memo Guide Book' +book2_1 'You can see an island map by pressing the SELECT Button. The dark parts of the map are the places you have not yet visited. Move the cursor and press the A Button to get more information about an area, or to replay the message you got there...' + +book3_0 'Secrets Of The Whirling Blade' +book3_1 'The Whirling Blade technique has been handed down from generation by the family of the hero. To use it, hold down the Sword Button and build up your power. When you have enough, you can released the Button! Can you master this?' + +book4_0 'How To Handle Your Shield Like A Pro!' +book4_1 'If you hold the Button down, you can defend yourself from enemy attacks, and you can flip some enemies, to... Besides the standard shield there is also a mirrored variety which can defend against beams!' + +book5_0 'Fun With Bombs' +book5_1 'After you put a Bomb down, you can pick it up by pressing the Button again. You can then throw it by pushing the Button one more time. Did you know that?' + +book6_0 'The Properties Of Warp Holes' +book6_1 'There are some Warp Holes on Koholint Island. You can warp to and fro using these holes. If you jump into the Warp Hole at which you arrived, you will go back to the next one in the sequence. You can only warp to a hole you have seen with your own eyes...' + +book7_0 'Atlas Of Koholint Island' +book7_1 You can move the cursor and look up the name of a place... Do you want to look at this map? + +book8_0 'Dark Secrets And Mysteries Of Koholint' +book8_1 Gasp! Wha-what's this! ... ... You can't read the tiny print without the aid of a magnifying glass... +book8_2 Round and round, the passageways of the Egg...\n{° ° ³ ± ± ³ ° ³}{??}...Hmmmmmm, this book reeks of secrets... +book8_3 Round and round, the passageways of the Egg...\n{± ³ ³ ± ³ ³ ± ³}{??}...Hmmmmmm, this book reeks of secrets... +book8_4 Round and round, the passageways of the Egg...\n{° ³ ± ³ ° ³ ± ³}{??}...Hmmmmmm, this book reeks of secrets... +book8_5 Round and round, the passageways of the Egg...\n{± ± ± ± ³ ³ ³ ³}{??}...Hmmmmmm, this book reeks of secrets... + + +// ° ± ² ³ +// <- alt + 0176 +// -> 0177 +// v 0178 + +// ° ± ² ³ +book9_1 New world of color under the 5 gravestones.\f{3³ 4± 5³}{2° 1² }\fTry with all your might. Open a new path! Whoever is worthy receives the power of color. I wonder what the world of color is? + +// phone in the house of ulrira +ulrira_telephone 'BRRING! BRRING! BRRING! CLICK! Yeees! It's the Bucket Mouse! Thanks for calling! ...Well... CLICK!' ??? ... You must have dialed a wrong number... + +// ulrira dialog +ulrira_0 'BRRING! BRRING! Hello! It's me, Ulrira! Ask me anything about the island! If you get lost, give me a call! Bye! CLICK!' +ulrira_1 'BRRING! BRRING! Ulrira speaking! You know, there is a library in the village that might have some good information for you! Talk to you later! CLICK!' + +ulrira_2_0 'BRRING! BRRING! Hello, this is Ulrira! ...Well, most Moblins live in the Mysterious Forest, but some live in the caves of Tal Tal Heights... I hope that is what you wanted to know! CLICK!' +ulrira_2_1 'BRRING! BRRING! Yes, this is Ulrira. The Indigestible Flowers of Goponga Swamp... Those flowers are BowWow's favorite. Why don't you take him for a walk there? CLICK!' + +ulrira_3_0 'BRRING! BRRING! Ulrira at your service! Oh? You should take BowWow home now, Madam MeowMeow would appreciate it! Bye! CLICK!' +ulrira_3_1 'BRRING! BRRING! Hi, it's Ulrira! ...Have you met everyone on the island? There's a man named Richard who lives in Pothole Field, southeast of the village. Why not pay him a visit? That's all I can tell you for now! Bye! CLICK!' +ulrira_3_2 'BRRING! BRRING! Old man Ulrira here! ...Do you like bananas? Try talking to people in the village again! Bye! CLICK!' + +ulrira_leaf_0 'BRRING! BRRING! Ya, it's Ulrira! You haven't found the 5 Golden Leaves? Keep an eye on the ones you have. Someone might try and take 'em! Bye! CLICK!' +ulrira_leaf_1 'BRRING! BRRING! Ya, it's Ulrira! You haven't found the 5 Golden Leaves? Try bombing suspicious places. Hope that helps. Bye! CLICK!' +ulrira_leaf_2 'BRRING! BRRING! Ya, it's Ulrira! You haven't found the 5 Golden Leaves? Go scare that crow by the castle and see if that helps! Bye! CLICK!' +ulrira_shovel 'BRRING! BRRING! Ulrira here! ... Shovel... Did you purchase a shovel? You may find something if you dig here and there! Bye! CLICK!' + +ulrira_3_3 'BRRING! BRRING! Ya, it's Ulrira! The cave in the Ukuku Prairie is the key! Yes, I mean the key cave, no pun intended. Bye! CLICK!' + +ulrira_4_0 'BRRING! BRRING! Hi, this is Ulrira! In the Yarna Desert, which is located in the southeast of the island, you will find something called the Angler Key. Hmmm... How much more obvious do I have to be? Bye! CLICK!' +ulrira_4_1 'BRRING! BRRING! This is Ulrira! Oh, I heard from grandma that there is something hidden behind the falls in the Tal Tal Mountains. Does that help? Bye! CLICK!' + +ulrira_5_0 'BRRING! BRRING! Hi, it's Ulrira! The Catfish's mouth is wide open? It sounds like a great place to dive! Bye! CLICK!' + +ulrira_6_0 'BRRING! BRRING! Ulrira here! ... Have you been to the Face Shrine? It is north of Animal Village. That is a very interesting ruin... CLICK!' + +ulrira_7_0 'BRRING! BRRING! Hi, it's Ulrira! Have you heard of the Flying Rooster of Mabe Village? In the good old days, it used to give us rides if we held it above our heads... Now it is lying under the Weathercock... Is that useful for you? I hope so! Bye! CLICK!' +ulrira_7_1 'BRRING! BRRING! Hi, it's Ulrira! You are doing great! Your efforts will end soon... By the way, have you visited the Hen House on the mountain? There is a cave nearby with something important in it. Bye! CLICK!' +ulrira_7_2 'BRRING! BRRING! Ulrira here... Yes, when I was just a lad, I recall seeing a high tower in the mountains! You should go there! Is that helpful for you? Bye! CLICK!' + +ulrira_8_0 'BRRING! BRRING! Hi, it's Ulrira! The head of the turtle is in your way? Put life into it and it will move! It's true! True! Bye! CLICK!' +ulrira_8_1 'BRRING! BRRING! Ulrira here! ... Go for it! You're almost there! I'm pulling for you! Bye! CLICK!' + +ulrira_9_0 'BRRING! BRRING! Hello, this is Ulrira speaking! [NAME], it's time for you to face the Egg on Mt. Tamaranch! Be careful, [NAME]! Bye! CLICK!' +ulrira_9_1 'BRRING! BRRING! This is Ulrira! You're lost in the Egg? Hmmmm. No sir, I can't help you on that one. How about the library? And hey, don't stop calling me because I didn't know one little answer! CLICK!' + +ulrira_wife 'BRRING! BRRING! Ya, it's Ulrira! My wife went to the Animal Village and left me all alone. Can you tell her to come home as soon as she is done cleaning? Bye! CLICK!' +ulrira_ghost 'BRRING! BRRING! This is Ulrira! Now you're being haunted by a ghost?! Well, how about taking him where he wants to go? Bye! CLICK!' +ulrira_mamu 'BRRING! BRRING! Yeah, this is Ulrira! You are starting to like music, eh? Well, a frog named Mamu, who lives in the Signpost Maze, might know some new songs, but he charges a lot to play them! Bye! CLICK!' + +// TODO: not sure when this is shown in the game +ulrira_seashells 'BRRING! BRRING! Ulrira speaking! Are your enemies too strong for you? In that case, you better collect all the Seashells... Just believe in yourself and do your best! CLICK!' + + +// dungeon intro +dungeon_1 Level 1--\n Tail Cave +dungeon_2 Level 2--\n Bottle Grotto +dungeon_3 Level 3--\n Key Cavern +dungeon_4 Level 4--\n Angler's Tunnel +dungeon_5 Level 5--\n Catfish's Maw +dungeon_6 Level 6--\n Face Shrine +dungeon_7 Level 7--\n Eagle's Tower +dungeon_8 Level 8--\n Turtle Rock + +beak_nop This owl statue is trying to say something, but you can't understand it because it has no beak. + +beak_d1_1 Turn aside the spined ones with a shield... +beak_d1_2 If there is a door that you can't open, move a stone block. + + +// shrine +shrine_dark ?? There is a picture carved on the wall, but you can't see it because it's too dark in here... +shrine_message TO THE FINDER... THE ISLE OF KOHOLINT, IS BUT AN ILLUSION... HUMAN, MONSTER, SEA, SKY... A SCENE ON THE LID OF A SLEEPER'S EYE... AWAKE THE DREAMER, AND KOHOLINT WILL VANISH MUCH LIKE A BUBBLE ON A NEEDLE... CAST-AWAY, YOU SHOULD KNOW THE TRUTH! ... ... ... ... What? Illusion? + + +// dungeon two +beak_d2_1 Part of the floor is raised. Tap the blue crystal. +beak_d2_2 Make every block design the same. A new path will open. +beak_d2_3 First, defeat the imprisoned Pols Voice, Last, Stalfos... + +// genie +d2_boss_0 HO HO HO! I'm your bad guy this time!! HO HO HO! +d2_boss_1 NYAH NYAH! You can't hurt me as long as I have my bottle! +d2_boss_2 . . . .! I can't move!\nBut I am still all right. Your little sword won't break this bottle! +d2_boss_3 Waaaah! You- you broke my bottle! Why, you... You make me hopping mad!!! + +// dungeon three +beak_d3_1 Far away...\nDo not fear, dash and fly! +beak_d3_2 To defeat the black monster with the hard shell, feed him something explosive. +beak_d3_3 Poke suspicious parts of the wall with your sword and listen to the sounds it makes. + +d3_boss {NEENER NEENER!}{You can't find me!}{NYAH NYAH!} + +bow_wow_cave_entry Ennh? Who's this suspicious looking runt?!\nOkay boys, let's get ridda him! +bow_wow_cave_boss You must be an assassin sent by Madam MeowMeow to rescue the mutt! You came here to get me, but it is I who will get you!! +bow_wow_cave_bw You've saved BowWow! What a fearsome beast! + +castle_monkey_hunger Chi-kiita! Chi-kiita! Kiki the monkey! Hungry! Kiki the monkey! +castle_monkey_bowwow Kiiiki! What?! All right, mutt! Let's battle!! + +castle_monkey_banana {¤! ¤!}{Oooh! Oooh!}{Give to Kiki!?} +castle_monkey_banana_yes {¤! ¤!}{Oooh! Ooh! Kiki!}{Monkeys! Come!}{Repay him! Kiki!} +castle_monkey_done {Monkey business!}{Done! Bye bye!}{Oooh! Kiki!} + +// dungeon four +beak_d4_1 The glint of the tile will be your guide... + +d4_nightmare {BLOOOP! BLOOOP! }{GLUB! GLUB! }{OGGGH! FOOOOD!}{BLOOOOP! GLUB! } + +// dungeon five +beak_d5_1 If you can't destroy a skeleton with your sword, try using a bomb. +beak_d5_2 Dive under where torchlight beams do cross... + +master_stalfos_0 Arrgh! I can't beat you! I'm outta here! +master_stalfos_1 Gulp! You found me!\nYou're a real pesky kid, you know that?! +master_stalfos_2 You again?! You keep going and going... I can't outlast you!\nAll right, let's do it! +master_stalfos_3 'I've got what was inside this box. Come and get it, if you can!' Master µ + +slime_eel_0 Ssso...you are the outsssider, come to wake the Wind Fisssh... KEEE-HEE-HEEEH!\nI shall eat you! +slime_eel_1 TSSSK, TSSSK! You don't ssseem to know what kind of island thisss iss... KEEE-HEEE-HEEE! What a fool... KEE-HEE-HEH!! + +// dungeon six +beak_d6_1 Enter the space where the eyes have walls... +beak_d6_2 Hop on top of the crystals to move forward. +beak_d6_3 To open a treasure chest, use the pots around it. + +facade_opening Hey dummy! Need a hint? My weak point is... !! Whoops! There I go, talking too much again... +facade_death Okay, listen up! If the Wind Fish wakes up, everything on this island will be gone forever! And I do mean... EVERYTHING! + +// dungeon seven +grim_creeper_enter Hey runt! You think you can take me?! All right boys, get this punk out of my face! +grim_creeper_1 Ha! That's all you've got?! Get ready for THIS! +grim_creeper_2 You dirty rat! You k-k-k...beat my brothers! You'll pay!! I'll never forget you! +grim_creeper_3 BAH! I'm not going to hold back! I'm going to make you wish you were never born!! +grim_creeper_4 My energy... gone...I...lost! But you will be lost too, if the Wind Fish wakes! Same as me...you ...are...in... his...dream... + +beak_d7_1 Jump off the floor above to reach the chest on the table. +beak_d7_2 The riddle is solved when the pillars fall! +beak_d7_3 If you can't go over the poles, try throwing things you have in your hands. + +// dungeon eight +beak_d8_1 To defeat the monsters who hold the key, attack them from a higher place. +beak_d8_2 If the statue looks strange, shoot it with the bow. +beak_d8_3 Fill all the holes with the rock that rolls, this (´) is the key! + +ice_block_message Brrrr... This is a block of solid ice! It's very cold! + +hot_head_0 CRACKLE-FWOOOSH! You're finished! I will never let you play the Instruments of the Sirens!! +hot_head_1 C-C-CRACKLE! Why did you come here? If it weren't for you, nothing would have to change! You cannot wake the Wind Fish! Remember, you... too...are in... ...the dream... + +// color dungeon +grave_locked If you have no courage, then you have no strength. Gravestones won't move for cowards. + +beak_dc_1 Here is your clue. Make all the red blue. + +stone_hinox What a greedy fool! You want more power?! A buffoon like you might as well give up and go home! + +giant_buzz_blob_enter BOO! I am no weakling! Your pitiful sword is no match for me! +giant_buzz_blob_sword You fool! Your sword won't work! Try something else! + +// is this only shown on the normal gameboy? +// I am sorry, but this is the Color Dungeon. Only those with the power of color may enter. If you can tell who wears red and who wears blue, you may enter. Farewell. +npc_color_0 Our colors are never the same! If I am red, he is blue! If he is red, I am blue! What color is my cloth? +npc_color_1 No, no. Take a closer look and try again. +npc_color_2 Don't tell anyone. +npc_color_3 The fairy queen is waiting for you. +npc_color_4 Do you have the powder?\nIf not, you must go back. + +choice_Red Red +choice_Blue Blue + +hardhit_beetle_0 Blue is safe. Yellow is caution. Red is danger. +hardhit_beetle_1 Blue. Start over. Yellow is caution. Red is danger. +hardhit_beetle_2 Yellow is caution. Red is danger, Take your time. + +choice_RED RED +choice_BLUE BLUE + +color_fairy_0 Welcome, [NAME]. I admire you for coming this far. I will give you the power of color. If you want offense, choose red. If you want defense choose blue. Which power do you want? +color_fairy_1 Red for offense, blue for defense. Which do you choose? +color_fairy_2 Are you sure? +color_fairy_3 Relax and close your eyes. +color_fairy_4 I will now take you out. + +cloak_blue You've got the Blue Clothes! Your damage will be reduced by half! +cloak_red You've got the Red Clothes! Your body is full of energy! + +// desert +desertLanmola Annoyance! You are only getting in the way! + +// shell mansion +shell_mansion_0 I am the spirit of the mansion. I have been waiting for someone to overcome the darkness. Find all the secret shells and go through the gate to receive the ultimate sword! +shell_mansion_1 Hmmm. No response. You must not have enough shells. +shell_mansion_2 My job here is finished. + +npc_hippo_0 Go away! +npc_hippo_1 Quit it! +npc_hippo_2 Leave me alone! I'm trying to sit still so Schule can paint my portrait! + +npc_painter_0 Ya, I am Schule Donavitch! Zee mermaid statue by zee bay iz my masterpiece! ... To tell you zee truth, zis werk iz not complete! Zee art, it'z... difficult for you to grasp, iz it not? +npc_painter_1 Iz zat zee Mermaid scale? I can't use it now. I have to werk on zis drawing. You should go finish zee mermaid statue for me. +npc_painter_2 Ach! Vat are you looking at vith zat magnifying lens? Stop it at vonce! + +// photo house +photo_book 'The Travels of [NAME]' Do you want to look at your album? +photo_book_text Which picture would you like to see? Use + to select, then press the A Button! + +// entering with a follower +photo_mouse_follower See me later, when you're alone! + +photo_left_11 11 shots left! What kind of picture should I take? +photo_left_10 10 shots left! What kind of picture should I take? +photo_left_9 9 shots left! What kind of picture should I take? +photo_left_8 8 shots left! What kind of picture should I take? +photo_left_7 7 shots left! What kind of picture should I take? +photo_left_6 6 shots left! What kind of picture should I take? +photo_left_5 5 shots left! What kind of picture should I take? +photo_left_4 4 shots left! What kind of picture should I take? +photo_left_3 3 shots left! What kind of picture should I take? +photo_left_2 2 shots left! What kind of picture should I take? +photo_left_1 1 shots left! What kind of picture should I take? +photo_left_0 Oh no! You're out of film! Don't forget to look at your album! + + +// photo sequence photo house +photo_01_0 I just LOVE to take pictures. Will you let me take your picture? +photo_01_1 Go to the back of the room and stand in front of the screen. +photo_01_2 I'll call this 'Here Stands A Brave Man.' Say cheese! +photo_01_3 What's your name, young man? [NAME]? Well here's your album, [NAME]. Give it a look before you leave! +photo_01_4 Let's see if we can fill that album! +photo_01_5 Let's take a picture! +photo_01_6 No picture?!\nAre you pullin' my leg? +photo_01_7 What a bummer! +photo_01_8 Beautiful! I'll call this 'Game Over.' +photo_01_9 Hey! I haven't taken your picture yet! Go back and stand in front of the screen! + +// photo sequence ulrira house +photo_02_0 Hi! It's me, the photographer! You seem curious about Grandpa Ulrira. +photo_02_1 I'll call this '[NAME] Discovers Ulrira's Secret!' + +// photo sequences BowWow +photo_03_0 Hey, that looks great! I'll call it '[NAME] Plays With BowWow!' Now get closer to BowWow! +photo_03_1 Grrrr! +photo_03_2 [NAME], get closer! +photo_03_3 Grrrr! Grrrr!! +photo_03_4 Grrrr! Grrrr!! GRRRR! +photo_03_5 Much closer! OK, I'm ready. Smile! + +// photo sequences castle +photo_05_0 Hi, [NAME]. You know I love to take pictures. Wouldn't this old castle make a great photo? +photo_05_1 Nothing yet?! I grow tired of waiting. I want those Golden Leaves delivered soon! Courage like this deserves a photo, don't you think? +photo_05_2 Go ahead and take a picture of me. Any angle you like! +photo_05_3 I'm not afraid. I just decided to wait at home. + +// photo sequences grave +photo_06_0 Ah how I love pictures. Hey, [NAME]! What are you doing here? +photo_06_1 You want to know about that ghost? I'll bet he's happy thanks to you. Are you ready for a picture? +photo_06_2 I'll call this 'I Was Very Afraid.' Smile! + +// photo sequences marin cliff +marin_cliff_0 This is my first walk with you, [NAME]. +marin_cliff_1 . . . . . +marin_cliff_2 This cliff will be our secret place. +marin_cliff_3 Aren't you going to say anything? +marin_cliff_4 Oh how I love pictures! Why don't you take a picture when no one is around?\nYou can call it . . . +marin_cliff_5 I'll go develop this. Come see it later, OK? + +// photo sequences fountain +photo_08_0 Hi! I'm the photographer! What a great photo moment! I'll call this 'Heads Up!' +photo_08_1 Ohh! I'm sorry! Are you okay?! [NAME]? + +// photo sequences weather bird +photo_09_0 Hey, Marin and [NAME]! Are you taking pictures? You should take pictures of everyone, including me. +photo_09_1 I use this to take pictures. Are you ready? Say 'mushroom!' +photo_09_2 OK, I'm done. I'll go home now. + +// photo sequences fisher +photo_10_0 I have a feelin' that I'll catch a big fish again. +photo_10_1 WHOA! That's a big one! Hey, photo guy! Can you take a picture of this? +photo_10_2 Hey! Be more careful next time! + +// photo sequences zora +photo_11_0 Hey, you can see me?! You must have a magnifying glass. I'm not a trouble maker. I just want to live in peace. +photo_11_1 Hi there! It's me, the photographer! You say Zora is in the house? I HAVE to take a picture of that. I'll call it 'I Found Zora.' + +// photo sequences mountain +photo_12_0 Hey, this represents your adventures perfectly! +photo_12_1 I'll call this one 'Close Call.' Hmm. +photo_12_2 I'm too close. +photo_12_3 I should back up. +photo_12_4 Aaaaaah! + +// map +map_tal_tal Tal Tal Mountain Range +map_wind_fishs_egg Wind Fish's Egg +map_mt_tamaranch Mt. Tamaranch +map_hen_house Hen House +map_telephone_booth Telephone Booth +map_goponga_swamp Goponga Swamp +map_tal_tal_heights Tal Tal Heights +map_weird_mr_write Weird Mr. Write +map_photo_both Step right up and get your souvenir photo! +map_raft_shop Raft Shop +map_mysterious_woods Mysterious Woods +map_koholint_prairie Koholint Prairie +map_crazy_tracy Crazy Tracy's\nHealth Spa +map_tabahl_wasteland Tabahl Wasteland +map_kanalet_castle Kanalet Castle +map_rapids_ride Rapids Ride +map_witchs_hut Witch's Hut +map_cementry Cemetery +map_fishing_pond Fishing Pond +map_quadruplets_house Quadruplet's House +map_dream_shrine Dream Shrine +map_ukuku_prairie Ukuku Prairie +map_seashell_mansion Seashell Mansion +map_face_shrine Face Shrine +map_mabe_village Mabe Village +map_town_tool_shop Town Tool Shop +map_madam_meow Madam MeowMeow's House\nBeware of Dog! +map_marin_tarin Marin and Tarin's House +map_village_library Village Library +map_old_man_house Old Man Ulrira's House +map_trendy_game Trendy Game +map_south_village South of the Village +map_signpost_maze Signpost Maze +map_pothole_field Pothole Field +map_maraths_bay Martha's Bay +map_animal_village Animal Village +map_yarna_desert Yarna Desert +map_richards_villa Richard's Villa +map_toronbo_shores Toronbo Shores +map_banana_house Sale's House O'Bananas +map_bay_east East of the Bay +map_house_bay House By The Bay + + +map_level_1 Level 1--\n Tail Cave +map_level_2 Level 2--\n Bottle Grotto +map_level_3 Level 3--\n Key Cavern +map_level_4 Level 4--\n Angler's Tunnel +map_level_5 Level 5--\n Catfish's Maw +map_level_6 Level 6--\n Face Shrine +map_level_7 Level 7--\n Eagle's Tower +map_level_8 Level 8--\n Turtle Rock + + +final_boss We were born of nightmares... To take over this world, we made the Wind Fish sleep endlessly! If the Wind Fish doesn't wake up, this island will never disappear! We would have been the masters of this place... But you had to come here and disrupt our plans! Heh heh! You can never defeat us!!! Let's rumble! + +final_windfish ... ... ... ... ... ... ... ... I AM THE WIND FISH... LONG HAS BEEN MY SLUMBER... IN MY DREAMS... AN EGG APPEARED AND WAS SURROUNDED BY AN ISLAND, WITH PEOPLE, ANIMALS, AN ENTIRE WORLD! ... ... ... ... BUT, VERILY, IT BE THE NATURE OF DREAMS TO END! WHEN I DOST AWAKEN, KOHOLINT WILL BE GONE... ONLY THE MEMORY OF THIS DREAM LAND WILL EXIST IN THE WAKING WORLD... SOMEDAY, THOU MAY RECALL THIS ISLAND... THAT MEMORY MUST BE THE REAL DREAM WORLD... ... ... ... ... COME, [NAME]... LET US AWAKEN... TOGETHER!! +final_instruments PLAY THE EIGHT INSTRUMENTS! PLAY THE SONG OF AWAKENING!! + +// credits +// 1998 +credits_0 1998 STAFF + +credits_1 SUPERVISOR +credits_1_0 TAKASHI TEZUKA + +credits_2 DIRECTOR +credits_2_0 YOSINORI TUTIYAMA + +credits_3 SCRIPT WRITER +credits_3_0 NOBUO MATSUMIYA + +credits_4 PROGRAMMER +credits_4_0 EIJI NOTO +credits_4_1 KIYOSHI KODA +credits_4_2 SIGEHIRO KASAMATU + +credits_5 CHARACTER DESIGNER +credits_5_0 MIKIO MISHIMA +credits_5_1 KYOKO KIMURA + +credits_6 SOUND COMPOSER +credits_6_0 YUICHI OZAKI + +credits_7 ART WORK +credits_7_0 KEIKO IZAWA + +credits_8 TECHNICAL SUPPORT +credits_8_0 N KOGANEZAWA + +credits_9 ENGLISH SCRIPT +credits_9_0 JIM WORNELL +credits_9_1 KEIKO TAMURA +credits_9_2 TAMAYO ITO + +credits_10 SPECIAL THANKS TO +credits_10_0 AKIYA SAKAMOTO +credits_10_1 R&D2 DEBUG STAFF + +credits_11 DEBUG STAFF +credits_11_0 SUPER MARIO CLUB + +// 1993 +credits_12 1993 STAFF + +credits_13 DIRECTOR +credits_13_0 TAKASHI TEZUKA + +credits_14 DUNGEON DESIGNER +credits_14_0 YASUHISA YAMAMURA + +credits_15 SCRIPT WRITER +credits_15_0 KENSUKE TANABE +credits_15_1 YOSHIAKI KOIZUMI + +credits_16 PROGRAMMER +credits_16_0 KAZUAKI MORITA +credits_16_1 TAKAMITSU KUZUHARA + +credits_17 CHARACTER DESIGNER +credits_17_0 MASANAO ARIMOTO +credits_17_1 SHIGEFUMI HINO + +credits_18 SOUND COMPOSER +credits_18_0 KAZUMI TOTAKA +credits_18_1 MINAKO HAMANO +credits_18_2 KOZUE ISHIKAWA + +credits_19 ILLUSTRATOR +credits_19_0 YOUICHI KOTABE + +credits_20 ENGLISH SCRIPT +credits_20_0 DAN OWSEN + +credits_21 SPECIAL THANKS TO +credits_21_0 TOSHIHIKO NAKAGO +credits_21_1 KOJI KONDO +credits_21_2 TOMOAKI KUROUME +credits_21_3 MASAICHI OKUMURA +credits_21_4 KANAE WADA + +credits_22 PRODUCER +credits_22_0 SHIGERU MIYAMOTO + +credits_23 EXECUTIVE PRODUCER +credits_23_0 HIROSHI YAMAUCHI + +credits_24 +credits_24_0 + +credits_25 +credits_25_0 THE END diff --git a/bin/Data/Languages/eng.lng b/bin/Data/Languages/eng.lng new file mode 100644 index 0000000..7b56abd --- /dev/null +++ b/bin/Data/Languages/eng.lng @@ -0,0 +1,82 @@ +main_menu_select_header Player Select +main_menu_bottom_header +main_menu_new_game New Game +main_menu_settings Settings +main_menu_copy Copy +main_menu_erase Erase + +main_menu_delete_confirmation_header Erase Save? +main_menu_delete_confirmation_header_yes Yes +main_menu_delete_confirmation_header_no No + +main_menu_copy_confirmation_header Copy Save? +main_menu_copy_confirmation_header_yes Yes +main_menu_copy_confirmation_header_no No + +main_menu_copy_header Copy Save +main_menu_copy_from From +main_menu_copy_to To +main_menu_copy_empty -Empty- +main_menu_copy_arrow ± +main_menu_copy_back Back + +new_game_menu_save_name YOUR NAME? +new_game_menu_back Back +new_game_menu_start_game Start Game + +game_menu_header Menu +game_menu_back_to_game Back to Game +game_menu_settings Settings +game_menu_exit_to_the_menu Exit to the Menu + +game_menu_exit_header Are you sure? +game_menu_exit_no No +game_menu_exit_yes Yes + +gameover_header GameOver +gameover_continue Continue +gameover_quit Quit + +settings_menu_header Settings +settings_menu_game Game +settings_menu_audio Audio +settings_menu_controls Controls +settings_menu_video Video +settings_menu_back Back + +settings_audio_header Audio Settings +settings_audio_music_volume Music Volume: +settings_audio_effect_volume Effect Volume: + +settings_game_header Game Settings +settings_game_language Language: English +settings_game_change_language Change Language +settings_game_autosave Autosave +settings_game_change_smooth_camera Smooth Camera +settings_game_fullscreen_windowed Borderless Windowed +settings_game_fullscreen_mode Fullscreen + +settings_controls_header Control Settings +settings_controls_keyboad Keyboard +settings_controls_gamepad Gamepad +settings_controls_Left Left +settings_controls_Right Right +settings_controls_Up Up +settings_controls_Down Down +settings_controls_A A +settings_controls_B B +settings_controls_X X +settings_controls_Y Y +settings_controls_Select Select +settings_controls_Start Start +settings_controls_reset Reset + +settings_graphics_header Video Settings +settings_graphics_game_scale Game Scale: +settings_graphics_ui_scale UI Scale: +settings_graphics_shadow Shadows +settings_graphics_fps_lock FPS Lock + +map_overlay_close Close +overlay_map Map +overlay_inventory Inventory diff --git a/bin/Data/Light/doorLight.atlas b/bin/Data/Light/doorLight.atlas new file mode 100644 index 0000000..a0644f1 --- /dev/null +++ b/bin/Data/Light/doorLight.atlas @@ -0,0 +1,3 @@ +1 +2 +doorLight:0,0,48,48,24,24 diff --git a/bin/Data/Light/readme.txt b/bin/Data/Light/readme.txt new file mode 100644 index 0000000..2c7de70 --- /dev/null +++ b/bin/Data/Light/readme.txt @@ -0,0 +1,2 @@ +@HACK: this folder is only used to store the .atlas files for the lights +in the end there should only be one content folder that contains the compiled files and the not compiled files \ No newline at end of file diff --git a/bin/Data/Light/room blur.atlas b/bin/Data/Light/room blur.atlas new file mode 100644 index 0000000..c156208 --- /dev/null +++ b/bin/Data/Light/room blur.atlas @@ -0,0 +1,3 @@ +1 +1 +room blur:0,0,192,160,16,16 diff --git a/bin/Data/Light/room blur.png b/bin/Data/Light/room blur.png new file mode 100644 index 0000000..b014b67 Binary files /dev/null and b/bin/Data/Light/room blur.png differ diff --git a/bin/Data/Map Objects/enemies.atlas b/bin/Data/Map Objects/enemies.atlas new file mode 100644 index 0000000..7ebabd3 --- /dev/null +++ b/bin/Data/Map Objects/enemies.atlas @@ -0,0 +1,95 @@ +1 +1 +anglerFry:258,311,16,16,0,0 +anti kirby:160,371,16,14,0,0 +antiFairy:114,184,16,16,0,0 +armMimic:240,176,16,16,0,0 +armos:1,320,16,16,8,14 +armos dark:52,320,16,16,8,14 +beamos:353,306,14,14,0,0 +beamos projectile:358,300,4,4,0,0 +beetle:288,99,16,11,0,0 +bladeTrap:0,112,16,16,0,0 +bloober:210,310,16,16,0,0 +bomber:22,342,24,16,0,0 +bombite:48,368,13,16,0,0 +bombiteGreen:48,385,13,16,0,0 +bone putter:352,343,14,16,0,0 +boo buddy:336,25,16,16,0,0 +buzz blob:62,175,12,16,0,0 +camo goblin:257,352,16,16,0,0 +card boy:245,1,16,16,0,0 +cheep cheep:258,311,16,16,0,0 +crab:16,81,16,16,0,0 +crow:96,64,16,16,0,0 +d8 floor:208,432,16,16,0,0 +darknut:406,249,18,23,0,0 +darknut spear:409,208,16,16,0,0 +fireball:129,16,14,16,0,0 +fish:160,160,16,16,0,0 +flame fountain:450,56,16,16,0,0 +floor layer:208,416,16,14,0,0 +flying tile:296,185,16,16,0,0 +gel:9,132,7,7,0,0 +ghini:128,129,16,14,0,0 +giant bubble:418,5,30,30,0,0 +giant ghini:320,64,31,30,0,0 +giant goponga flower:256,130,32,30,0,0 +gibdo:320,384,16,16,0,0 +goomba:161,48,14,16,0,0 +goponga flower:224,64,16,16,0,0 +green zol:50,133,12,11,0,0 +hardHatBeetle:16,144,16,16,0,0 +ice block:40,448,16,16,0,0 +iron mask:438,146,16,14,0,0 +karakoro:381,354,24,16,0,0 +keese:48,21,16,8,0,0 +leever:32,64,16,16,0,0 +like like:0,177,16,15,0,0 +madBomber:72,235,14,12,0,0 +magicRodShot:113,1,14,14,7,7 +mask mimic:1,256,16,16,0,0 +mega thwomp:328,103,32,31,0,0 +miniMoldormHead0:146,1,16,16,0,0 +miniMoldormHead1:163,1,16,16,0,0 +miniMoldormPart0:180,1,10,10,0,0 +miniMoldormPart1:191,1,8,8,0,0 +moblin:64,96,16,16,0,0 +moblin sword:168,208,18,23,0,0 +moblinPig:160,96,16,16,0,0 +moblinPigSword:160,96,16,16,0,0 +monkey enemy:288,24,16,14,0,0 +octorok:19,44,15,15,0,0 +pairodd:160,336,16,16,0,0 +peahat:387,144,16,16,0,0 +pincer:170,134,16,16,0,0 +piranha plant:2,277,14,16,0,0 +podoboo:352,376,16,16,0,0 +pokey:1,368,16,15,8,15 +pokey body:18,369,14,14,7,14 +pols voice:336,0,16,16,0,0 +raven:113,64,16,16,0,0 +red zol:66,133,12,11,0,0 +river zora:32,208,16,16,0,0 +rock:176,416,16,16,0,0 +rope:400,102,16,16,0,0 +sea urchin:0,0,16,16,0,0 +shrouded stalfos:112,304,16,16,0,0 +spark:48,144,16,16,0,0 +spiked beetle:208,32,16,16,0,0 +spiked thwomp:8,408,32,32,0,0 +spiny beetle:80,336,15,13,0,0 +stalfos green:265,55,15,16,0,0 +stalfos orange:265,73,15,16,0,0 +star:316,307,16,13,0,0 +tektite:129,336,16,16,0,0 +thwimp:176,24,16,16,0,0 +torch trap:80,16,10,10,0,0 +vacuum:49,288,14,15,0,0 +vire:397,81,22,16,0,0 +wallKnight:320,176,16,16,0,0 +water tektite:353,146,16,14,0,0 +winged octorok:108,44,15,15,0,0 +wizzrobe:364,170,16,16,0,0 +wizzrobe shot:359,188,12,12,0,0 +zombie:112,160,16,16,0,0 diff --git a/bin/Data/Map Objects/enemies.png b/bin/Data/Map Objects/enemies.png new file mode 100644 index 0000000..50b6958 Binary files /dev/null and b/bin/Data/Map Objects/enemies.png differ diff --git a/bin/Data/Map Objects/items.atlas b/bin/Data/Map Objects/items.atlas new file mode 100644 index 0000000..11e7d2e --- /dev/null +++ b/bin/Data/Map Objects/items.atlas @@ -0,0 +1,86 @@ +1 +1 +:143,116,1,1,0,0 +arrow:152,121,8,16,0,0 +bomb:102,124,8,13,0,0 +boomerang:136,125,8,12,0,0 +bow:145,123,6,14,0,0 +cloak:180,31,16,15,0,0 +compass:83,20,8,14,0,0 +dkey1:1,19,8,15,0,0 +dkey2:11,19,8,15,0,0 +dkey3:21,19,8,15,0,0 +dkey4:31,19,8,15,0,0 +dkey5:41,19,8,15,0,0 +dmap:73,20,8,14,0,0 +fairy:123,57,8,13,0,0 +feather:58,121,7,16,0,0 +flippers:118,19,8,15,0,0 +genieSpawn0:43,155,10,10,0,0 +genieSpawn1:224,160,16,16,0,0 +genieSpawn2:184,169,16,15,0,0 +goldLeaf:151,37,8,15,0,0 +guardianAcorn:164,55,8,15,0,0 +heart:143,45,7,7,0,0 +heartMeter:174,73,16,15,0,0 +heartMeterFull:192,73,14,12,0,0 +hookshot:128,121,7,16,0,0 +hookshot_chain:29,61,4,4,0,0 +hookshot_hook:13,56,14,14,0,0 +instrument0:224,0,16,16,0,0 +instrument1:224,16,16,16,0,0 +instrument2:224,32,16,16,0,0 +instrument3:224,48,16,16,0,0 +instrument4:224,64,16,16,0,0 +instrument5:224,80,16,16,0,0 +instrument6:224,96,16,16,0,0 +instrument7:224,112,16,16,0,0 +item:1,1,13,15,0,0 +magicRod:111,122,7,15,0,0 +marin_item:63,39,16,16,0,0 +mirror shield:40,138,8,10,0,0 +nightmarekey:54,20,9,14,0,0 +ocarina:119,123,8,14,0,0 +ocarina1:63,57,16,13,0,0 +ocarina2:81,57,16,13,0,0 +ocarina3:99,57,16,13,0,0 +pegasusBoots:84,124,8,13,0,0 +pieceOfPower:133,58,12,12,0,0 +potion:108,19,8,15,0,0 +powder:49,123,8,14,0,0 +rubyBlue:126,38,7,14,0,0 +rubyGreen:64,144,7,14,0,0 +rubyRed:135,38,7,14,0,0 +shell:128,20,8,14,0,0 +shell_present:19,37,16,16,0,0 +shellMap:166,20,8,14,0,0 +shield:40,127,8,10,0,0 +shovel:93,123,8,14,0,0 +smallkey:64,21,7,13,0,0 +stonebeak:93,22,7,12,0,0 +stonelifter0:66,123,8,14,0,0 +stonelifter1:75,123,8,14,0,0 +sword1:176,148,8,16,0,0 +sword2:185,148,8,16,0,0 +swordBlink:194,148,8,16,0,0 +sword2Show:165,140,10,24,0,0 +swordShot:203,149,6,15,3,12 +swordSpawn:154,140,10,24,0,0 +toadstool:101,40,8,11,0,0 +toadstoolMap:90,40,10,11,0,0 +trade0:1,1,13,15,0,0 +trade1:16,2,16,14,0,0 +trade10:147,1,12,15,0,0 +trade11:161,2,16,14,0,0 +trade12:179,4,8,12,0,0 +trade13:189,1,15,15,0,0 +trade2:34,2,11,14,0,0 +trade3:47,1,16,15,0,0 +trade4:65,1,6,15,0,0 +trade5:73,1,14,15,0,0 +trade5Map:1,37,16,16,0,0 +trade6:89,1,12,15,0,0 +trade7:103,1,12,15,0,0 +trade8:117,4,14,12,0,0 +trade9:133,1,12,15,0,0 +heart menu:79,112,7,7,0,0 diff --git a/bin/Data/Map Objects/items.png b/bin/Data/Map Objects/items.png new file mode 100644 index 0000000..49ae680 Binary files /dev/null and b/bin/Data/Map Objects/items.png differ diff --git a/bin/Data/Map Objects/link0.atlas b/bin/Data/Map Objects/link0.atlas new file mode 100644 index 0000000..34dd5c4 --- /dev/null +++ b/bin/Data/Map Objects/link0.atlas @@ -0,0 +1,4 @@ +1 +1 +stunned particle:401,36,4,4 +:0,0,0,0 diff --git a/bin/Data/Map Objects/link0.png b/bin/Data/Map Objects/link0.png new file mode 100644 index 0000000..ddc47b6 Binary files /dev/null and b/bin/Data/Map Objects/link0.png differ diff --git a/bin/Data/Map Objects/link_cloak.png b/bin/Data/Map Objects/link_cloak.png new file mode 100644 index 0000000..a616715 Binary files /dev/null and b/bin/Data/Map Objects/link_cloak.png differ diff --git a/bin/Data/Map Objects/midboss.atlas b/bin/Data/Map Objects/midboss.atlas new file mode 100644 index 0000000..34c4eb0 --- /dev/null +++ b/bin/Data/Map Objects/midboss.atlas @@ -0,0 +1,34 @@ +1 +1 +armos knight:7,48,32,32,0,0 +ballAndChain:176,192,16,16,0,0 +blaino:250,16,22,16,0,0 +blaino glove:242,59,11,11,0,0 +buzz_0:56,293,16,10,0,0 +buzz_1:39,290,15,16,0,0 +cue ball:257,112,30,32,0,0 +desert lanmola:254,272,16,16,0,0 +giant buzz blob:68,257,24,31,0,0 +gohma:112,144,40,16,0,0 +grim creeper:146,256,24,16,0,0 +hinox:120,220,32,32,0,0 +hinox stone:200,104,16,16,0,0 +king_moblin:9,12,21,24,0,0 +ms_feet:47,112,30,16,0,0 +ms_head:48,94,27,16,0,0 +ms_shield:15,112,16,16,0,0 +ms_swing:78,89,32,39,0,0 +ms_sword:32,100,15,24,0,0 +rolling bones:51,181,20,24,0,0 +smasher:14,218,22,22,0,0 +smasher_ball:80,224,16,16,0,0 +snake big blue:328,234,32,32,0,0 +snake big green:328,234,32,32,0,0 +snake blue:256,232,16,16,0,0 +snake body:362,237,26,26,0,0 +snake body blue:310,232,16,16,0,0 +snake body green:310,250,16,16,0,0 +snake green:256,250,16,16,0,0 +stone hinox:128,96,32,32,0,0 +turtle neck:346,187,16,16,0,0 +turtle rock:256,187,28,32,0,0 diff --git a/bin/Data/Map Objects/midboss.png b/bin/Data/Map Objects/midboss.png new file mode 100644 index 0000000..6867c2d Binary files /dev/null and b/bin/Data/Map Objects/midboss.png differ diff --git a/bin/Data/Map Objects/minimap.png b/bin/Data/Map Objects/minimap.png new file mode 100644 index 0000000..4553507 Binary files /dev/null and b/bin/Data/Map Objects/minimap.png differ diff --git a/bin/Data/Map Objects/nightmares.atlas b/bin/Data/Map Objects/nightmares.atlas new file mode 100644 index 0000000..c3680ed --- /dev/null +++ b/bin/Data/Map Objects/nightmares.atlas @@ -0,0 +1,23 @@ +1 +1 +angler fish:7,133,56,48,0,0 +eagle feather:301,242,15,8,0,0 +eel_heart_0:180,240,16,16,0,0 +eel_heart_1:198,240,16,16,0,0 +eel_tail_0:134,240,16,16,0,0 +eel_tail_1:118,241,14,14,0,0 +eel_tail_2:100,240,16,16,0,0 +evil eagle:244,320,48,48,0,0 +facade:265,48,46,23,0,0 +final_part0:350,16,16,16,8,8 +final_part1:337,18,12,12,6,6 +final_part2:484,274,16,16,8,8 +genie:208,136,16,24,0,0 +hardhit beetle:9,249,32,39,0,0 +hot head:128,288,32,32,0,0 +moldorm:2,4,28,24,0,0 +moldorm:0,0,0,0,0,0 +nightmare_body:337,18,12,12,6,6 +nightmare_head:416,56,16,16,8,8 +slime eel:96,258,26,24,0,0 +slime_eye:90,18,44,32,0,0 diff --git a/bin/Data/Map Objects/nightmares.png b/bin/Data/Map Objects/nightmares.png new file mode 100644 index 0000000..2a8fed7 Binary files /dev/null and b/bin/Data/Map Objects/nightmares.png differ diff --git a/bin/Data/Map Objects/npcs.atlas b/bin/Data/Map Objects/npcs.atlas new file mode 100644 index 0000000..842bfbc --- /dev/null +++ b/bin/Data/Map Objects/npcs.atlas @@ -0,0 +1,42 @@ +1 +1 +alligator:4,50,23,23,0,0 +bird:559,4,15,14,0,0 +bowwow:353,86,16,16,0,0 +bowwow chain:310,91,6,6,3,6 +butterfly:161,205,7,5,0,0 +cock:304,176,16,16,0,0 +cock_particle_0:294,174,8,8,0,0 +cock_particle_1:295,183,6,6,0,0 +cock_particle_2:296,190,4,4,0,0 +dog:507,3,16,15,0,0 +fisherman:339,144,16,16,0,0 +ghost:448,32,16,16,0,0 +grandmother:409,63,15,16,0,0 +green_child:388,6,13,14,0,0 +hippo:494,200,19,24,0,0 +letter_bird:92,224,16,16,0,0 +letter_boy:160,256,16,18,0,0 +lost_boy:189,24,16,16,0,0 +mamu:343,204,31,32,0,0 +manbo:40,79,32,48,0,0 +manbo oh:3,135,24,16,0,0 +marin:62,181,16,16,0,0 +mermaid:121,233,16,17,8,17 +monkey:110,3,14,16,0,0 +note:262,185,7,12,0,0 +npc_bag:157,24,14,16,7,14 +npc_bat:554,31,24,16,0,0 +npc_chicken_dude:173,157,12,16,0,0 +npc_color_dungeon:313,282,15,16,0,0 +npc_fairy:103,268,21,25,0,0 +owl:314,259,14,16,0,0 +painter:514,234,21,22,0,0 +person:276,2,15,16,0,0 +photo_mouse:99,157,15,16,0,0 +raccoon:125,205,16,16,0,0 +shopkeeper:363,118,15,16,0,0 +smallBowWow:474,91,10,10,0,0 +tarin_zzz:195,195,7,8,3,4 +tracy:371,56,16,23,0,0 +walrus:183,52,32,28,0,0 diff --git a/bin/Data/Map Objects/npcs.png b/bin/Data/Map Objects/npcs.png new file mode 100644 index 0000000..135e794 Binary files /dev/null and b/bin/Data/Map Objects/npcs.png differ diff --git a/bin/Data/Map Objects/objects animated.atlas b/bin/Data/Map Objects/objects animated.atlas new file mode 100644 index 0000000..498a56a --- /dev/null +++ b/bin/Data/Map Objects/objects animated.atlas @@ -0,0 +1,23 @@ +1 +1 +:0,0,0,0,0,0 +color_tile_blue:0,176,16,16,0,0 +color_tile_green:0,160,16,16,0,0 +color_tile_red:0,144,16,16,0,0 +dungeonOneWay:144,64,16,16,0,0 +dungeonSixEntry:144,96,80,64,0,0 +lamp:0,16,16,16,0,0 +lava_2d:96,16,16,16,0,0 +spikes:114,144,16,16,0,0 +sword_particle_0:241,184,14,8,13,7 +sword_particle_1:256,180,12,12,11,11 +sword_particle_2:269,178,8,14,7,13 +sword_particle_3:278,176,4,16,2,15 +sword_particle_4:283,178,8,14,1,13 +sword_particle_5:292,180,12,12,1,11 +sword_particle_6:305,184,14,8,1,7 +sword_spawn:142,189,16,16,0,0 +sword_thunder_0:105,189,32,48,32,48 +sword_thunder_1:105,189,32,48,16,0 +tower:32,272,48,16,0,0 +weather_bird:32,208,16,32,0,0 diff --git a/bin/Data/Map Objects/objects animated.png b/bin/Data/Map Objects/objects animated.png new file mode 100644 index 0000000..3cae2aa Binary files /dev/null and b/bin/Data/Map Objects/objects animated.png differ diff --git a/bin/Data/Map Objects/objects.atlas b/bin/Data/Map Objects/objects.atlas new file mode 100644 index 0000000..e1e6921 --- /dev/null +++ b/bin/Data/Map Objects/objects.atlas @@ -0,0 +1,251 @@ +1 +1 +aquatic_plant:331,74,16,16,0,0 +aquatic_plant_bottom:338,84,8,6,0,0 +aquatic_plant_top:331,74,14,10,0,0 +ball:366,94,14,15,0,0 +bananas:544,80,16,16,8,16 +barrier_0:304,145,11,14,0,0 +barrier_1:316,145,11,14,0,0 +barrier_2:328,145,11,14,0,0 +barrier_bottom_0:304,160,11,10,0,0 +barrier_bottom_1:316,160,11,10,0,0 +barrier_bottom_2:328,160,11,10,0,0 +boat:259,186,40,15,20,15 +book_0:489,85,8,11,0,0 +book_1:498,85,8,11,0,0 +book_2:507,85,8,11,0,0 +book_3:516,85,8,11,0,0 +book_open:525,86,16,10,0,0 +breaking_floor_0:456,0,16,16,0,0 +breaking_floor_1:473,0,16,16,0,0 +breaking_floor_2:490,0,16,16,0,0 +breaking_floor_3:507,0,16,16,0,0 +breaking_floor_4:524,0,16,16,0,0 +breaking_floor_5:541,0,16,16,0,0 +breaking_floor_6:558,0,16,16,0,0 +breaking_floor_7:575,0,16,16,0,0 +breaking_floor_8:592,0,16,16,0,0 +bridge:395,68,16,16,0,0 +bush_0:361,1,14,14,7,7 +bush_1:376,1,14,14,7,7 +button:335,111,16,16,0,0 +cactus:397,85,12,15,6,15 +candy_grabber:490,67,16,16,0,0 +candy_grabber_controls_button_0:527,69,6,6,0,0 +candy_grabber_controls_button_1:527,76,6,6,0,0 +candy_grabber_controls_top:512,67,14,15,0,0 +candy_grabber_left:473,67,8,16,0,0 +candy_grabber_left_closed:490,67,8,16,0,0 +candy_grabber_line:507,67,4,16,0,0 +candy_grabber_right:481,67,8,16,0,0 +candy_grabber_right_closed:498,67,8,16,0,0 +candy_grabber_top:456,67,16,8,0,0 +castle_door:489,34,48,32,0,0 +castle_roof_0:304,209,16,16,0,17 +castle_roof_1:321,209,16,16,0,17 +castle_roof_2:338,209,16,16,0,17 +castle_roof_3:304,226,16,16,0,0 +castle_roof_4:321,226,16,16,0,16 +castle_roof_5:304,226,16,16,0,16 +cave_bed:321,176,16,32,0,0 +cave_table:338,176,32,16,0,1 +caveFairyStatue:34,83,16,32,8,28 +chest:259,51,16,16,0,0 +chest_back:259,51,16,7,0,0 +chest_front:259,58,16,9,0,6 +cloud_0:0,286,32,16,0,0 +cloud_1:0,303,32,16,0,0 +cloud_2:33,287,80,32,0,0 +color_tile_0:304,128,16,16,0,0 +color_tile_1:321,128,16,16,0,0 +color_tile_2:338,128,16,16,0,0 +crystal_0:259,0,16,16,0,0 +crystal_1:276,0,16,16,0,0 +crystal_2:293,0,16,16,0,0 +crystal_hard:310,0,16,16,0,0 +d5_entry:406,151,48,32,0,0 +d5_entry_shadow:406,151,48,30,0,0 +d6_statue:439,51,16,31,0,0 +desertPillar:51,84,15,31,8,27 +destroyable_barrier:344,17,16,16,0,0 +destroyableStone:456,34,32,32,0,0 +dungeon_color_head:544,32,16,16,0,0 +dungeon_door:259,68,16,16,0,0 +dungeon_entrance:259,17,16,16,0,0 +dungeon_owl:309,85,16,16,0,0 +dungeon_switch:292,85,16,16,0,0 +dungeon3Head:135,66,16,16,8,12 +dungeon7_keyhole:152,84,16,15,8,13 +dungeonOneStatue:0,83,16,32,8,28 +dungeonOneStatueKey:17,83,16,32,8,28 +dungeonStatue_0:51,66,16,16,8,13 +dungeonStatue_1:68,66,16,16,8,13 +dungeonStatue_2:135,83,16,16,8,13 +eel_floor:445,117,16,16,0,0 +eel_floor_broken:541,0,16,16,0,0 +eel_wall:412,117,32,16,0,0 +eel_wall_open:412,134,32,16,0,0 +egg_entry:546,112,16,22,8,22 +fence:327,3,6,13,3,12 +fence_shadow:327,3,6,12,3,12 +flower_0:129,116,16,16,0,0 +flower_1:129,133,16,16,0,0 +flower_2:129,150,16,16,0,0 +flower_3:129,167,16,16,0,0 +flower_4:129,184,16,16,0,0 +flower_5:129,201,16,16,0,0 +flower_6:129,218,16,16,0,0 +grass:349,91,8,8,0,0 +grass_0:513,145,20,20,10,10 +grass_0_0:515,145,16,18,8,10 +grass_0_1:515,145,18,20,8,10 +grass_0_2:513,145,18,20,10,10 +grass_0_3:513,145,20,18,10,10 +grass_1:533,145,20,20,10,10 +grass_2:553,145,20,20,10,10 +gravejardFence:85,68,15,14,7,10 +gravestone:361,17,16,16,0,0 +hole_0:456,17,16,16,0,0 +hole_1:473,17,16,16,0,0 +horse_head_down:473,84,14,16,0,0 +horse_head_up:456,84,16,16,0,0 +itemShop:101,66,16,16,8,14 +keyhole_block:259,85,16,16,0,0 +lava:194,235,16,16,0,0 +leaf:331,91,8,6,0,0 +mermaid_statue:304,177,16,31,8,27 +movestone_0:378,17,16,16,0,0 +movestone_1:395,17,16,16,0,0 +movestone_2:412,17,16,16,0,0 +movestone_3:429,17,16,16,0,0 +moving_platform:259,102,32,16,0,0 +overworld_gradient:144,321,16,77,0,0 +overworldDonut:34,66,16,16,8,0 +owl_statue:372,178,16,16,0,12 +owl_statue_shadow:372,178,16,13,0,12 +painting:276,202,16,27,8,27 +phone:67,95,16,20,8,18 +photohouse_light:372,195,21,24,0,24 +pillar_bottom:384,144,16,16,0,0 +pillar_middle:384,128,16,16,0,0 +pillar_top:384,112,16,16,0,0 +platformchain:293,135,8,16,0,0 +pot_0:408,34,15,16,0,0 +pot_1:424,34,14,16,0,0 +pot_2:439,34,16,16,0,0 +pull_bridge:259,135,16,16,0,0 +pull_bridge_end:259,162,16,2,0,0 +pull_bridge_hook:259,152,16,9,0,0 +pull_bridge_middle:259,165,16,8,0,0 +pull_bridge_rope:259,161,16,4,0,0 +pull_bridge_start:259,165,16,6,0,0 +pull_lever:317,111,16,16,0,0 +pull_lever_top:323,107,4,4,0,0 +raft:259,202,16,15,0,0 +rollband_0:412,83,16,16,0,0 +rollband_1:412,100,16,16,0,0 +roof_0:0,0,48,32,0,18 +roof_1:49,0,48,32,0,18 +roof_2:98,0,48,32,0,18 +roof_3:169,83,48,16,0,16 +roof_4:464,145,48,32,0,18 +roof_5:464,178,48,32,0,18 +sand_0:194,116,16,16,0,0 +sand_1:194,133,16,16,0,0 +sand_2:194,150,16,16,0,0 +seashell_house:464,112,48,32,24,24 +seashell_house_shadow:464,112,48,24,24,24 +seashell_post:372,113,9,47,0,0 +shell_bar:372,161,16,16,0,0 +shell_present:389,161,16,16,0,0 +signpost_0:395,52,16,15,8,15 +signpost_1:412,52,16,15,8,15 +skull:393,35,14,15,0,0 +small_platform:276,135,16,16,0,0 +small_stone_0:349,75,7,6,3,6 +small_stone_1:358,77,5,4,2,4 +small_stones:348,74,16,16,0,0 +stairs_0:152,66,16,16,0,0 +stairs_1:169,66,16,16,0,0 +stairs_2:186,66,16,16,0,0 +stairs_3:203,66,16,16,0,0 +statue_d3:84,84,16,31,8,29 +statue_d3_key:101,84,16,31,8,29 +statue_mermaid:118,84,16,31,8,27 +statueCastle:118,66,16,16,8,14 +stone_0:361,35,15,15,0,0 +stone_1:377,35,15,15,0,0 +stone_mountain_0:361,51,16,16,8,13 +stone_mountain_1:378,52,16,15,8,12 +stone_particle:340,91,8,8,0,0 +stone_particle_1:340,100,8,8,0,0 +stone_wall_0:259,34,16,16,0,0 +stone_wall_1:276,34,16,16,0,0 +stone_wall_10:225,68,16,16,0,0 +stone_wall_11:225,85,16,16,0,0 +stone_wall_12:276,17,48,16,0,0 +stone_wall_2:293,34,16,16,0,0 +stone_wall_3:310,34,16,16,0,0 +stone_wall_4:327,34,16,16,0,0 +stone_wall_5:344,34,16,16,0,0 +stone_wall_6:242,34,16,16,0,0 +stone_wall_7:242,51,16,16,0,0 +stone_wall_8:242,68,16,16,0,0 +stone_wall_9:242,85,16,16,0,0 +strandPlant:0,66,16,16,8,12 +strandPlantShadow:0,66,16,12,8,12 +strandShell:17,66,16,16,8,12 +strandShellShadow:17,66,16,12,8,12 +teleporter_middle:383,76,10,10,0,0 +teleporter_outer:384,87,4,4,0,0 +tower_clouds:114,287,159,32,0,0 +tree_0:0,33,32,32,16,24 +tree_0_shadow:0,33,32,28,16,24 +tree_1:33,33,32,32,16,24 +tree_1_shadow:33,33,32,24,16,24 +tree_2:66,33,32,32,16,24 +tree_2_shadow:66,33,32,28,16,24 +tree_3:99,33,32,32,16,24 +tree_4:132,33,32,32,16,24 +tree_4_shadow:132,33,32,28,16,24 +tree_5:165,33,32,32,16,24 +tree_5_shadow:165,33,32,28,16,24 +tree_6:198,34,32,31,16,24 +tree_7:147,0,32,32,16,24 +tree_8:180,0,16,32,8,24 +tree_8_shadow:180,0,16,27,8,24 +tree_9:513,112,32,32,16,24 +tree_9_shadow:513,112,32,24,16,24 +tree_phonehouse:197,0,48,32,24,24 +tree_phonehouse_shadow:196,0,49,27,24,27 +vase_empty:561,88,8,8,4,8 +vase_flower:570,80,12,16,7,16 +water:367,74,12,8,0,0 +water_0:0,116,16,16,0,0 +water_1:0,150,16,16,0,0 +water_12:99,269,64,16,0,0 +water_2:0,133,16,16,0,0 +water_2d_0:16,269,16,16,0,0 +water_2d_1:49,269,16,16,0,0 +water_2d_2:82,269,16,16,0,0 +water_2d_3:81,252,16,16,0,0 +water_2d_4:114,252,16,16,0,0 +water_3:0,167,16,16,0,0 +water_4:0,184,16,16,0,0 +water_5:0,201,16,16,0,0 +water_6:0,218,16,16,0,0 +water_7:0,235,16,16,0,0 +water_8:0,252,16,16,0,0 +water_down:194,167,16,16,0,0 +water_left:194,184,16,16,0,0 +water_right:194,218,16,16,0,0 +water_up:194,201,16,16,0,0 +waterfall:0,252,16,16,0,0 +wave_3:0,320,16,16,0,0 +wave_4:0,337,16,16,0,0 +wave_5:0,354,16,16,0,0 +wave_6:0,371,16,16,0,0 +witch_house:406,184,48,32,0,30 +witch_house_shadow:406,184,48,30,0,30 +empty:135,114,1,1,0,0 diff --git a/bin/Data/Map Objects/objects.png b/bin/Data/Map Objects/objects.png new file mode 100644 index 0000000..2c02bf6 Binary files /dev/null and b/bin/Data/Map Objects/objects.png differ diff --git a/bin/Data/Maps/0 test map - Copy (2).map b/bin/Data/Maps/0 test map - Copy (2).map new file mode 100644 index 0000000..8614800 --- /dev/null +++ b/bin/Data/Maps/0 test map - Copy (2).map @@ -0,0 +1,715 @@ +3 +0 +0 +cave.png +28 +22 +3 +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,25,25,19,19,19,19,19,25,25,25,25,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,19,19,25,25,25,25,25,25,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,19,19,19,19,19,19,19,25,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,19,19,19,19,19,19,19,25,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,19,19,19,19,19,19,19,25,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +117 +0;80;64;;; +0;80;80;;; +0;80;96;;; +0;80;112;;; +0;80;128;;; +0;80;144;;; +0;80;160;;; +0;80;176;;; +0;80;192;;; +0;80;208;;; +0;80;224;;; +0;80;240;;; +0;80;256;;; +0;80;272;;; +0;96;64;;; +0;96;80;;; +0;96;96;;; +0;96;112;;; +0;96;128;;; +0;96;144;;; +0;96;160;;; +0;96;176;;; +0;96;192;;; +0;96;208;;; +0;96;224;;; +0;96;240;;; +0;96;256;;; +0;96;272;;; +0;112;64;;; +0;112;128;;; +0;112;224;;; +0;112;240;;; +0;112;256;;; +0;128;64;;; +0;128;128;;; +0;128;224;;; +0;128;240;;; +0;128;256;;; +0;144;64;;; +0;144;144;;; +0;144;224;;; +0;144;240;;; +0;144;256;;; +0;160;64;;; +0;160;144;;; +0;160;224;;; +0;160;240;;; +0;160;256;;; +0;176;64;;; +0;176;144;;; +0;176;224;;; +0;176;240;;; +0;176;256;;; +0;192;64;;; +0;192;144;;; +0;192;224;;; +0;192;240;;; +0;192;256;;; +0;208;64;;; +0;208;144;;; +0;208;224;;; +0;208;240;;; +0;208;256;;; +0;224;64;;; +0;224;128;;; +0;224;144;;; +0;224;176;;; +0;224;192;;; +0;224;208;;; +0;224;224;;; +0;224;240;;; +0;224;256;;; +0;240;64;;; +0;240;128;;; +0;240;224;;; +0;240;240;;; +0;240;256;;; +0;256;64;;; +0;256;128;;; +0;256;224;;; +0;256;240;;; +0;256;256;;; +0;272;64;;; +0;272;128;;; +0;272;224;;; +0;272;240;;; +0;272;256;;; +0;288;64;;; +0;288;224;;; +0;288;240;;; +0;288;256;;; +0;304;64;;; +0;304;224;;; +0;304;240;;; +0;304;256;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +0;320;112;;; +0;320;128;;; +0;320;144;;; +0;320;160;;; +0;320;176;;; +0;320;192;;; +0;320;208;;; +0;320;224;;; +0;320;240;;; +0;320;256;;; +261;224;160;;test_door;2; +334;160;96;btest1;; +334;176;96;btest1;; +334;192;96;btest1;; +330;160;112;btest1 +406;200;160 +168;176;192;test_door;!test_button; +167;192;192;test_button;0 +170;224;160;test_button;;;; diff --git a/bin/Data/Maps/0 test map - Copy (2).map.data b/bin/Data/Maps/0 test map - Copy (2).map.data new file mode 100644 index 0000000..2f8b14b --- /dev/null +++ b/bin/Data/Maps/0 test map - Copy (2).map.data @@ -0,0 +1,24 @@ +28 +22 +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - Copy - Copy.map b/bin/Data/Maps/0 test map - Copy - Copy.map new file mode 100644 index 0000000..1e292b4 --- /dev/null +++ b/bin/Data/Maps/0 test map - Copy - Copy.map @@ -0,0 +1,654 @@ +3 +0 +0 +cave.png +28 +22 +3 +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +56 +0;80;64;;; +0;80;80;;; +0;80;96;;; +0;80;112;;; +0;80;128;;; +0;80;144;;; +0;80;160;;; +0;80;176;;; +0;80;192;;; +0;80;208;;; +0;80;224;;; +0;80;240;;; +0;80;256;;; +0;96;64;;; +0;96;256;;; +0;112;64;;; +0;112;256;;; +0;128;64;;; +0;128;256;;; +0;144;64;;; +0;144;256;;; +0;160;64;;; +0;160;256;;; +0;176;64;;; +0;176;256;;; +0;192;64;;; +0;192;256;;; +0;208;64;;; +0;208;256;;; +0;224;64;;; +0;224;256;;; +0;240;64;;; +0;240;128;;; +0;240;256;;; +0;256;64;;; +0;256;256;;; +0;272;64;;; +0;272;256;;; +0;288;64;;; +0;288;256;;; +0;304;64;;; +0;304;256;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +0;320;112;;; +0;320;128;;; +0;320;144;;; +0;320;160;;; +0;320;176;;; +0;320;192;;; +0;320;208;;; +0;320;224;;; +0;320;240;;; +0;320;256;;; +503;272;128;; diff --git a/bin/Data/Maps/0 test map - Copy - Copy.map.data b/bin/Data/Maps/0 test map - Copy - Copy.map.data new file mode 100644 index 0000000..2f8b14b --- /dev/null +++ b/bin/Data/Maps/0 test map - Copy - Copy.map.data @@ -0,0 +1,24 @@ +28 +22 +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - Copy.map.data b/bin/Data/Maps/0 test map - Copy.map.data new file mode 100644 index 0000000..2f8b14b --- /dev/null +++ b/bin/Data/Maps/0 test map - Copy.map.data @@ -0,0 +1,24 @@ +28 +22 +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - barrier.map b/bin/Data/Maps/0 test map - barrier.map new file mode 100644 index 0000000..2750c67 --- /dev/null +++ b/bin/Data/Maps/0 test map - barrier.map @@ -0,0 +1,649 @@ +3 +0 +0 +cave.png +28 +22 +3 +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,81,19,19,19,19,19,19,19,19,19,81,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +51 +171;80;112;;;btest1;1;False; +334;112;64;btest1;; +334;112;160;btest1;; +334;128;64;btest1;; +334;128;160;btest1;; +334;144;64;btest1;; +334;144;160;btest1;; +334;160;64;btest1;; +334;160;96;btest1;; +334;160;160;btest1;; +334;176;64;btest1;; +334;176;96;btest1;; +334;176;160;btest1;; +334;192;64;btest1;; +334;192;96;btest1;; +334;192;160;btest1;; +334;208;64;btest1;; +334;208;160;btest1;; +335;112;80;btest1;; +335;112;96;btest1;; +335;112;112;btest1;; +335;112;128;btest1;; +335;112;144;btest1;; +335;128;80;btest1;; +335;128;96;btest1;; +335;128;112;btest1;; +335;128;128;btest1;; +335;128;144;btest1;; +335;144;80;btest1;; +335;144;96;btest1;; +335;144;112;btest1;; +335;144;128;btest1;; +335;144;144;btest1;; +335;160;80;btest1;; +335;160;128;btest1;; +335;160;144;btest1;; +335;176;80;btest1;; +335;176;112;btest1;; +335;176;128;btest1;; +335;176;144;btest1;; +335;192;80;btest1;; +335;192;112;btest1;; +335;192;128;btest1;; +335;192;144;btest1;; +335;208;80;btest1;; +335;208;96;btest1;; +335;208;112;btest1;; +335;208;128;btest1;; +335;208;144;btest1;; +330;160;112;btest1 +170;240;112;test_button;;;; diff --git a/bin/Data/Maps/0 test map - barrier.map.data b/bin/Data/Maps/0 test map - barrier.map.data new file mode 100644 index 0000000..2f8b14b --- /dev/null +++ b/bin/Data/Maps/0 test map - barrier.map.data @@ -0,0 +1,24 @@ +28 +22 +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - beamos.map b/bin/Data/Maps/0 test map - beamos.map new file mode 100644 index 0000000..e474121 --- /dev/null +++ b/bin/Data/Maps/0 test map - beamos.map @@ -0,0 +1,585 @@ +3 +0 +0 +cave.png +16 +15 +3 +19,19,19,19,19,19,19,19,,,,,,,,, +19,19,19,19,19,19,19,19,19,,,,,,,, +19,19,19,19,19,19,19,19,19,,,,,,,, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +8 +470;0;48 +227;0;96; +227;32;0; +227;32;144; +227;48;16; +227;48;64; +227;48;80; +227;48;144; diff --git a/bin/Data/Maps/0 test map - beamos.map.data b/bin/Data/Maps/0 test map - beamos.map.data new file mode 100644 index 0000000..6524555 --- /dev/null +++ b/bin/Data/Maps/0 test map - beamos.map.data @@ -0,0 +1,17 @@ +16 +15 +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - blured cave.map b/bin/Data/Maps/0 test map - blured cave.map new file mode 100644 index 0000000..40156ac --- /dev/null +++ b/bin/Data/Maps/0 test map - blured cave.map @@ -0,0 +1,693 @@ +3 +1 +1 +cave.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,39,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,37,, +,45,88,88,89,86,70,63,70,70,63,70,63,63,69,46,46,46,46,71,44,, +,45,70,63,89,86,86,70,63,63,27,63,70,87,44,22,29,29,23,45,44,, +,45,63,70,88,86,86,86,87,63,70,70,70,89,44,24,70,70,21,45,44,, +,45,86,63,63,70,70,70,89,24,28,28,21,89,68,47,20,47,47,67,44,, +,45,86,86,27,86,63,70,88,86,86,86,86,88,70,63,70,70,27,70,44,, +,36,46,71,86,86,86,27,70,29,29,29,29,70,70,70,70,70,70,69,38,, +,,,36,46,16,15,46,46,46,46,46,46,46,46,16,15,46,46,38,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,,,,,,,,,,,,,,,,,,,4,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,1,,,,,,,,,,,,,,,,,,,2,0, +0,0,0,1,,,,,,,,,,,,,,,,2,0,0, +,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +131 +382;-8;64; +0;16;32;;; +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;32;16;;; +0;32;112;;; +0;48;16;;; +0;48;112;;; +0;64;16;;; +0;64;128;;; +0;80;16;;; +0;88;144;;; +0;96;16;;; +0;112;16;;; +0;112;128;;; +0;128;16;;; +0;128;128;;; +0;144;16;;; +0;144;128;;; +0;160;16;;; +0;160;128;;; +0;176;16;;; +0;176;128;;; +0;192;16;;; +0;192;128;;; +0;208;16;;; +0;208;128;;; +0;224;16;;; +0;224;128;;; +0;240;16;;; +0;248;144;;; +0;256;16;;; +0;272;16;;; +0;272;128;;; +0;288;16;;; +0;288;128;;; +0;304;16;;; +0;304;112;;; +0;320;32;;; +0;320;48;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +19;288;48;;; +20;144;80;;; +20;240;64;;; +21;192;80;;; +21;288;64;;; +3;80;128;;; +3;240;128;;; +4;96;128;;; +4;256;128;;; +18;240;48;;; +286;-8;40;;;; +275;32;80; +275;32;96; +275;48;96; +275;64;112; +275;80;32; +275;80;48; +275;80;96; +275;80;112; +275;96;48; +275;96;112; +298;88;128;;;;;; +298;248;128;;;;;; +199;128;32;ruby20;;c5_r20;; +199;272;48;ruby50;;c5_r50;; +153;88;136;;;c5_1;overworld.map;c5_1;1;; +153;248;136;;;c5_2;overworld.map;c5_2;1;; +423;32;64;; +423;64;96;; +423;240;96;; +423;256;96;; +423;272;96;; +341;32;32;;;;;; +341;48;32;;;;;; +341;64;32;;;;;; +341;64;48;;;;;; +341;64;64;;;;;; +341;80;64;;;;;; +341;96;64;;;;;; +341;112;64;;;;;; +341;128;64;;;;;; +341;128;80;;;;;; +341;128;96;;;;;; +341;144;96;;;;;; +341;160;96;;;;;; +341;176;96;;;;;; +341;192;96;;;;;; +341;208;48;;;;;; +341;208;64;;;;;; +341;208;80;;;;;; +341;208;96;;;;;; +162;272;80;;18;;8;;;;; +10;160;80;;; +10;176;80;;; +11;144;110;;; +11;160;110;;; +11;176;110;;; +11;192;110;;; +11;256;48;;; +11;272;48;;; +25;224;32;;;; +25;224;48;;;; +25;224;64;;;; +25;224;80;;;; +25;240;32;;;; +25;240;80;;;; +25;256;32;;;; +25;272;32;;;; +25;272;80;;;; +25;288;32;;;; +25;288;80;;;; +25;304;32;;;; +25;304;48;;;; +25;304;64;;;; +25;304;80;;;; +287;-8;16;37 +160;256;80; +230;272;64;;;;;; +246;240;48; +246;240;64; +246;256;48; +246;256;64; +246;256;80; +246;272;64; +246;288;48; +246;288;64; diff --git a/bin/Data/Maps/0 test map - blured cave.map.data b/bin/Data/Maps/0 test map - blured cave.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/0 test map - blured cave.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - color jump tile.map b/bin/Data/Maps/0 test map - color jump tile.map new file mode 100644 index 0000000..8a856cd --- /dev/null +++ b/bin/Data/Maps/0 test map - color jump tile.map @@ -0,0 +1,567 @@ +3 +1 +0 +cave.png +12 +10 +3 +70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +5 +0;80;83;;; +0;96;83;;; +0;112;83;;; +0;128;83;;; +352;96;64; diff --git a/bin/Data/Maps/0 test map - color jump tile.map.data b/bin/Data/Maps/0 test map - color jump tile.map.data new file mode 100644 index 0000000..966622a --- /dev/null +++ b/bin/Data/Maps/0 test map - color jump tile.map.data @@ -0,0 +1,12 @@ +12 +10 +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - dialog.map b/bin/Data/Maps/0 test map - dialog.map new file mode 100644 index 0000000..aaaef7f --- /dev/null +++ b/bin/Data/Maps/0 test map - dialog.map @@ -0,0 +1,662 @@ +3 +0 +0 +cave.png +28 +22 +3 +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +524 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +waterfallSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +63 +241;112;144;;book6;1 +0;80;64;;; +0;80;80;;; +0;80;96;;; +0;80;112;;; +0;80;128;;; +0;80;144;;; +0;80;160;;; +0;80;176;;; +0;80;192;;; +0;80;208;;; +0;80;224;;; +0;80;240;;; +0;80;256;;; +0;96;64;;; +0;96;256;;; +0;112;64;;; +0;112;256;;; +0;128;64;;; +0;128;256;;; +0;144;64;;; +0;144;256;;; +0;160;64;;; +0;160;256;;; +0;176;64;;; +0;176;256;;; +0;192;64;;; +0;192;256;;; +0;208;64;;; +0;208;256;;; +0;224;64;;; +0;224;256;;; +0;240;64;;; +0;240;256;;; +0;256;64;;; +0;256;256;;; +0;272;64;;; +0;272;256;;; +0;288;64;;; +0;288;256;;; +0;304;64;;; +0;304;256;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +0;320;112;;; +0;320;128;;; +0;320;144;;; +0;320;160;;; +0;320;176;;; +0;320;192;;; +0;320;208;;; +0;320;224;;; +0;320;240;;; +0;320;256;;; +503;176;96;; +203;112;112;smallkey;;; +203;136;144;test_dialog;;; +203;160;144;test_dialog_1;;; +203;184;144;test_dialog_2;;; +203;208;144;test_dialog_3;;; +203;232;144;test_dialog_4;;; +203;288;144;maria_0_0;;; diff --git a/bin/Data/Maps/0 test map - dialog.map.data b/bin/Data/Maps/0 test map - dialog.map.data new file mode 100644 index 0000000..2f8b14b --- /dev/null +++ b/bin/Data/Maps/0 test map - dialog.map.data @@ -0,0 +1,24 @@ +28 +22 +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - enemies - damage - holes.map b/bin/Data/Maps/0 test map - enemies - damage - holes.map new file mode 100644 index 0000000..cec1c14 --- /dev/null +++ b/bin/Data/Maps/0 test map - enemies - damage - holes.map @@ -0,0 +1,823 @@ +3 +0 +0 +cave.png +110 +48 +3 +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +147 +339;0;4;;;;;; +339;0;104;;;;;; +339;0;304;;;;;; +339;0;404;;;;;; +339;0;504;;;;;; +339;0;604;;;;;; +339;0;704;;;;;; +339;160;4;;;;;; +339;160;204;;;;;; +339;160;304;;;;;; +339;160;404;;;;;; +339;160;504;;;;;; +339;160;604;;;;;; +339;160;704;;;;;; +339;320;4;;;;;; +339;320;204;;;;;; +339;320;304;;;;;; +339;320;404;;;;;; +339;320;504;;;;;; +339;320;604;;;;;; +339;320;704;;;;;; +339;480;4;;;;;; +339;480;204;;;;;; +339;480;304;;;;;; +339;480;404;;;;;; +339;480;504;;;;;; +339;480;604;;;;;; +339;480;704;;;;;; +339;640;4;;;;;; +339;640;204;;;;;; +339;640;304;;;;;; +339;640;504;;;;;; +339;640;604;;;;;; +339;640;704;;;;;; +339;800;4;;;;;; +339;800;204;;;;;; +339;800;304;;;;;; +339;800;404;;;;;; +339;800;504;;;;;; +339;800;604;;;;;; +339;800;704;;;;;; +339;960;4;;;;;; +339;960;204;;;;;; +339;960;304;;;;;; +339;960;404;;;;;; +339;960;504;;;;;; +339;960;604;;;;;; +339;960;704;;;;;; +339;1120;4;;;;;; +339;1120;204;;;;;; +339;1120;304;;;;;; +339;1120;404;;;;;; +339;1120;504;;;;;; +339;1120;604;;;;;; +339;1120;704;;;;;; +339;1280;4;;;;;; +339;1280;204;;;;;; +339;1280;304;;;;;; +339;1280;404;;;;;; +339;1280;504;;;;;; +339;1280;604;;;;;; +339;1440;4;;;;;; +339;1440;204;;;;;; +339;1440;304;;;;;; +339;1440;404;;;;;; +339;1440;504;;;;;; +339;1440;604;;;;;; +339;1600;4;;;;;; +339;1600;204;;;;;; +339;1600;304;;;;;; +339;1600;404;;;;;; +339;1600;604;;;;;; +339;1604;504;;;;;; +165;0;0;;e1; +165;0;100;;e_darknutSpear; +165;0;300;;e_antiFairy; +165;0;400;;e_Vacuum; +165;0;500;;e23; +165;0;600;;maskMimic; +165;0;700;;e_karakoro; +165;160;0;;e2; +165;160;200;;e_darknut; +165;160;300;;e12; +165;160;400;;e_bombite; +165;160;500;;e_Beetle; +165;160;600;;e_ArmMimic; +165;160;700;;e_gibdo; +165;320;0;;e_wingedOctorok; +165;320;200;;e_wallKnight; +165;320;300;;polsVoice; +165;320;400;;e_bombiteGreen; +165;320;500;;e_BeetleSpawner; +165;320;600;;e_waterTektite; +165;320;700;;e_antiKirby; +165;480;0;;e3; +165;480;200;;e_madBomber; +165;480;300;;e_dungeonGhost; +165;480;400;;e16; +165;480;500;;spikedBeetle; +165;480;600;;e_peahat; +165;480;700;;e_vire; +165;640;0;;e4; +165;640;200;;e6; +165;640;300;;e_bomber; +165;640;500;;goponga_flower; +165;640;600;;e_ironMask; +165;640;700;;e_rope; +165;800;0;;e5; +165;800;200;;e8; +165;800;300;;e_pokey; +165;800;400;;e18; +165;800;500;;goponga_flower_giant; +165;800;600;;e_star; +165;800;700;;e_flameFountain; +165;960;0;;moblinSword; +165;960;200;;e9; +165;960;300;;e_spinyBeetle; +165;960;400;;e20; +165;960;500;;e_fish; +165;960;600;;e_flyingTile; +165;960;700;;e_floorLayer; +165;1120;0;;shroudedStalfos; +165;1120;200;;e15; +165;1120;300;;e_tektite; +165;1120;400;;e_raven; +165;1120;500;;cardboy; +165;1120;600;;e_wizzrobe; +165;1120;700;;e_rockSpawner; +165;1280;0;;stalfosKnight; +165;1280;200;;e7; +165;1280;300;;e13; +165;1280;400;;e21; +165;1280;500;;monkey; +165;1280;600;;e_beamos; +165;1328;1104;;e17; +165;1440;0;;e19; +165;1440;200;;e10; +165;1440;300;;stalfosGreen; +165;1440;400;;e_giantGhini; +165;1440;500;;torchTrap; +165;1440;600;;e_camoGoblin; +165;1600;0;;e_moblinPigSword; +165;1600;200;;e11; +165;1600;300;;e_armos; +165;1600;400;;zombie; +165;1600;500;;e_pairodd; +165;1600;600;;e_bonePutter; diff --git a/bin/Data/Maps/0 test map - enemies - damage - holes.map.data b/bin/Data/Maps/0 test map - enemies - damage - holes.map.data new file mode 100644 index 0000000..5a11213 --- /dev/null +++ b/bin/Data/Maps/0 test map - enemies - damage - holes.map.data @@ -0,0 +1,50 @@ +110 +48 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - enemies - damage.map b/bin/Data/Maps/0 test map - enemies - damage.map new file mode 100644 index 0000000..0a51919 --- /dev/null +++ b/bin/Data/Maps/0 test map - enemies - damage.map @@ -0,0 +1,753 @@ +3 +0 +0 +cave.png +110 +48 +3 +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +77 +382;-32;0; +473;48;672;;test; +473;80;688;;; +165;0;0;;e1; +165;0;100;;e_darknutSpear; +165;0;300;;e_antiFairy; +165;0;400;;e_Vacuum; +165;0;500;;e23; +165;0;600;;maskMimic; +165;0;700;;e_karakoro; +165;160;0;;e2; +165;160;200;;e_darknut; +165;160;300;;e12; +165;160;400;;e_bombite; +165;160;500;;e_Beetle; +165;160;600;;e_ArmMimic; +165;160;700;;e_gibdo; +165;320;0;;e_wingedOctorok; +165;320;200;;e_wallKnight; +165;320;300;;polsVoice; +165;320;400;;e_bombiteGreen; +165;320;500;;e_BeetleSpawner; +165;320;600;;e_waterTektite; +165;320;700;;e_antiKirby; +165;480;0;;e3; +165;480;200;;e_madBomber; +165;480;300;;e_dungeonGhost; +165;480;400;;e16; +165;480;500;;spikedBeetle; +165;480;600;;e_peahat; +165;480;700;;e_vire; +165;640;0;;e4; +165;640;200;;e6; +165;640;300;;e_bomber; +165;640;500;;goponga_flower; +165;640;600;;e_ironMask; +165;640;700;;e_rope; +165;800;0;;e5; +165;800;200;;e8; +165;800;300;;e_pokey; +165;800;400;;e18; +165;800;500;;goponga_flower_giant; +165;800;600;;e_star; +165;800;700;;e_flameFountain; +165;960;0;;moblinSword; +165;960;200;;e9; +165;960;300;;e_spinyBeetle; +165;960;400;;e20; +165;960;500;;e_fish; +165;960;600;;e_flyingTile; +165;960;700;;e_floorLayer; +165;1120;0;;shroudedStalfos; +165;1120;200;;e15; +165;1120;300;;e_tektite; +165;1120;400;;e_raven; +165;1120;500;;cardboy; +165;1120;600;;e_wizzrobe; +165;1120;700;;e_rockSpawner; +165;1280;0;;stalfosKnight; +165;1280;200;;e7; +165;1280;300;;e13; +165;1280;400;;e21; +165;1280;500;;monkey; +165;1280;600;;e_beamos; +165;1328;1104;;e17; +165;1440;0;;e19; +165;1440;200;;e10; +165;1440;300;;stalfosGreen; +165;1440;400;;e_giantGhini; +165;1440;500;;torchTrap; +165;1440;600;;e_camoGoblin; +165;1600;0;;e_moblinPigSword; +165;1600;200;;e11; +165;1600;300;;e_armos; +165;1600;400;;zombie; +165;1600;500;;e_pairodd; +165;1600;600;;e_bonePutter; diff --git a/bin/Data/Maps/0 test map - enemies - damage.map.data b/bin/Data/Maps/0 test map - enemies - damage.map.data new file mode 100644 index 0000000..5a11213 --- /dev/null +++ b/bin/Data/Maps/0 test map - enemies - damage.map.data @@ -0,0 +1,50 @@ +110 +48 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - enemies small.map b/bin/Data/Maps/0 test map - enemies small.map new file mode 100644 index 0000000..1be3ce9 --- /dev/null +++ b/bin/Data/Maps/0 test map - enemies small.map @@ -0,0 +1,570 @@ +3 +0 +0 +cave.png +10 +5 +3 +89,89,89,89,89,89,89,89,89,89, +89,19,19,19,19,19,19,19,19,89, +89,19,19,19,19,19,19,19,19,89, +89,19,19,19,19,19,19,19,19,89, +89,89,89,89,89,89,89,89,89,89, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +23 +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;16;16;;; +0;16;48;;; +0;32;16;;; +0;32;48;;; +0;48;16;;; +0;48;48;;; +0;64;16;;; +0;64;48;;; +0;80;16;;; +0;80;48;;; +0;96;16;;; +0;96;48;;; +0;112;16;;; +0;112;48;;; +0;128;16;;; +0;128;48;;; +0;144;16;;; +0;144;32;;; +0;144;48;;; +441;80;32 diff --git a/bin/Data/Maps/0 test map - enemies small.map.data b/bin/Data/Maps/0 test map - enemies small.map.data new file mode 100644 index 0000000..4791235 --- /dev/null +++ b/bin/Data/Maps/0 test map - enemies small.map.data @@ -0,0 +1,7 @@ +10 +5 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - enemies.map b/bin/Data/Maps/0 test map - enemies.map new file mode 100644 index 0000000..858ca99 --- /dev/null +++ b/bin/Data/Maps/0 test map - enemies.map @@ -0,0 +1,1043 @@ +3 +0 +0 +cave.png +70 +80 +3 +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19,81,81,81,81,81,81,81,81,81,81,19,19,19,19,19,19,19,19,19,19, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +524 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +waterfallSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +270 +0;960;512;;; +0;960;624;;; +0;976;512;;; +0;976;624;;; +0;992;512;;; +0;992;624;;; +0;1008;512;;; +0;1008;624;;; +0;1024;512;;; +0;1024;624;;; +0;1040;512;;; +0;1040;624;;; +0;1056;512;;; +0;1056;624;;; +0;1072;512;;; +0;1072;624;;; +0;1088;512;;; +0;1088;624;;; +0;1104;512;;; +0;1104;528;;; +0;1104;544;;; +0;1104;560;;; +0;1104;576;;; +0;1104;592;;; +0;1104;608;;; +0;1104;624;;; +459;32;928;;testboy +459;48;992;2;testboy +459;96;944;1;testboy +429;1000;280 +429;1008;344 +429;1064;312 +476;384;1232 +476;400;1184 +476;416;1216 +464;672;912 +464;688;960 +464;752;944 +464;768;928 +464;768;944 +439;512;544; +439;552;600; +439;608;560; +471;672;1056 +471;688;1104 +471;736;1056 +471;736;1088 +471;736;1104 +454;336;800 +454;416;816 +433;680;416 +433;712;464 +433;752;432 +441;824;592 +441;856;528 +441;880;576 +441;912;552 +442;1024;584 +442;1036;540 +442;1072;596 +442;1076;556 +473;992;1040; +473;1008;1088; +473;1072;1056; +473;1072;1104; +472;832;1040; +472;832;1088; +472;912;1056; +419;512;152 +419;544;216 +419;592;160 +418;688;152 +418;704;208 +418;744;152 +432;528;416; +432;544;464; +432;592;448; +458;1024;816 +458;1040;848 +479;832;1168 +479;880;1168 +480;1120;1152;; +469;352;1040;;; +469;368;1104;;; +469;416;1056;;; +469;416;1120;;; +449;1008;672; +475;208;1232 +475;240;1184 +475;240;1200 +467;16;1056 +467;80;1056 +467;96;1104 +474;16;1248;;test; +474;48;1184;;test; +474;112;1200;;test; +421;840;208 +421;864;152 +421;896;192 +417;352;152 +417;392;208 +417;432;144 +462;352;960 +462;384;928 +462;400;960 +466;1008;944 +466;1056;960 +466;1072;928 +434;824;472 +434;856;424 +434;904;456 +447;664;672 +447;712;728 +447;752;680 +481;1024;1184;; +481;1040;1232;; +478;672;1184 +478;704;1232 +478;736;1184 +435;1000;416; +435;1040;464; +435;1096;432; +468;192;1056 +468;240;1104 +468;272;1056 +436;24;592 +436;32;536 +436;72;584 +436;120;552 +440;688;536;;; +440;712;592;;; +440;752;552;;; +477;544;1200 +477;560;1248 +465;832;912 +465;832;928 +465;848;976 +465;912;928 +409;360;88 +409;368;24 +409;416;40 +409;416;80 +470;496;1056 +470;528;1104 +470;576;1088 +470;592;1056 +407;24;24 +407;24;64 +407;72;64 +407;104;32 +427;680;280 +427;696;336 +427;752;304 +428;824;272;;; +428;872;320;;; +428;920;288;;; +430;32;408 +430;64;456 +430;104;424 +437;176;536; +437;208;592; +437;240;600; +437;264;544; +425;344;280 +425;384;304 +425;384;336 +425;416;288 +443;32;656 +443;64;720 +443;104;680 +444;192;728 +444;208;664 +444;240;728 +444;280;672 +445;400;720 +416;200;160 +416;208;224 +416;288;184 +408;184;16 +408;216;72 +408;280;40 +446;512;664; +446;560;712; +446;600;672; +448;840;664;; +448;840;728;; +448;896;664;; +448;912;720;; +452;208;800 +452;256;832 +410;512;16 +410;544;88 +410;608;40 +411;672;16 +411;688;80 +411;768;24 +412;832;80 +412;856;40 +412;896;32 +412;912;88 +422;1024;168;;;; +422;1040;216;;;; +426;512;320 +426;544;320 +426;552;288 +426;552;320 +426;576;296 +426;576;304 +426;576;312 +426;576;320 +423;16;272 +423;48;328 +423;104;288 +424;184;280;; +424;208;344;; +424;240;312;; +424;256;336;; +424;280;288;; +456;656;848 +456;688;800 +456;720;816 +456;720;864 +457;832;816 +200;16;736;;;shield0;; +463;512;944 +463;560;976 +463;576;928 +413;1000;16 +413;1000;80 +413;1064;64 +460;224;944 +431;192;400 +431;208;464 +431;280;456 +414;352;408 +414;376;464 +414;432;456 +455;528;816 +455;560;848 +455;592;816 +438;344;536 +438;368;600 +438;392;568 +438;432;544 +415;24;152 +415;72;176 +415;112;144 +102;400;672;;;;;; +102;400;688;;;;;; +102;400;704;;;;;; +102;400;720;;;;;; +102;416;672;;;;;; +102;416;688;;;;;; +102;416;704;;;;;; +102;416;720;;;;;; +158;400;672 +158;400;688 +158;400;704 +158;400;720 +158;416;672 +158;416;688 +158;416;704 +158;416;720 +450;48;816 +450;48;832 +450;64;864 +450;80;832 +450;80;864 +450;96;800 +450;112;848 diff --git a/bin/Data/Maps/0 test map - enemies.map.data b/bin/Data/Maps/0 test map - enemies.map.data new file mode 100644 index 0000000..6764ac4 --- /dev/null +++ b/bin/Data/Maps/0 test map - enemies.map.data @@ -0,0 +1,82 @@ +70 +80 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - fence.map b/bin/Data/Maps/0 test map - fence.map new file mode 100644 index 0000000..54ce8d9 --- /dev/null +++ b/bin/Data/Maps/0 test map - fence.map @@ -0,0 +1,562 @@ +3 +0 +0 +cave.png +9 +7 +3 +81,19,81,19,81,19,81,19,81, +19,81,19,81,19,81,19,81,19, +81,19,81,19,81,19,81,19,81, +19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19, +,,,,,,,,, +,,,,,,,,, +,,,,,,,,, +,,,,,,,,, +,,,,,,,,, +,,,,,,,,, +,,,,,,,,, +,,,,,,,,, +,,,,,,,,, +,,,,,,,,, +,,,,,,,,, +,,,,,,,,, +,,,,,,,,, +,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +9 +138;16;16; +138;48;16; +138;64;0; +138;80;16; +138;112;16; +150;48;0; +149;32;0; +148;16;0; +147;0;0; diff --git a/bin/Data/Maps/0 test map - fence.map.data b/bin/Data/Maps/0 test map - fence.map.data new file mode 100644 index 0000000..5d27899 --- /dev/null +++ b/bin/Data/Maps/0 test map - fence.map.data @@ -0,0 +1,9 @@ +9 +7 +;;;;;;;;; +;;;;;;;;; +;;;;;;;;; +;;;;;;;;; +;;;;;;;;; +;;;;;;;;; +;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - floor layer.map b/bin/Data/Maps/0 test map - floor layer.map new file mode 100644 index 0000000..9cee915 --- /dev/null +++ b/bin/Data/Maps/0 test map - floor layer.map @@ -0,0 +1,545 @@ +3 +0 +0 +cave.png +4 +4 +3 +19,19,19,19, +19,19,19,19, +19,19,19,19, +19,19,19,19, +,,,, +,,,, +,,,, +,,,, +,,,, +,,,, +,,,, +,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +1 +479;0;32;; diff --git a/bin/Data/Maps/0 test map - floor layer.map.data b/bin/Data/Maps/0 test map - floor layer.map.data new file mode 100644 index 0000000..e50338c --- /dev/null +++ b/bin/Data/Maps/0 test map - floor layer.map.data @@ -0,0 +1,6 @@ +4 +4 +;;;; +;;;; +;;;; +;;;; diff --git a/bin/Data/Maps/0 test map - gbs test.map b/bin/Data/Maps/0 test map - gbs test.map new file mode 100644 index 0000000..e927eba --- /dev/null +++ b/bin/Data/Maps/0 test map - gbs test.map @@ -0,0 +1,581 @@ +3 +0 +0 +cave.png +17 +16 +3 +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +1 +287;80;64;52 diff --git a/bin/Data/Maps/0 test map - gbs test.map.data b/bin/Data/Maps/0 test map - gbs test.map.data new file mode 100644 index 0000000..ce1007e --- /dev/null +++ b/bin/Data/Maps/0 test map - gbs test.map.data @@ -0,0 +1,18 @@ +17 +16 +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - holes.map b/bin/Data/Maps/0 test map - holes.map new file mode 100644 index 0000000..5ada6da --- /dev/null +++ b/bin/Data/Maps/0 test map - holes.map @@ -0,0 +1,637 @@ +3 +0 +0 +cave.png +28 +22 +3 +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,89,89,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,89,89,89,89,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,89,89,89,89,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,89,89,89,89,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,89,89,89,89,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +39 +341;112;112;;;;;; +341;128;112;;;;;; +341;160;128;;;;;; +341;160;144;;;;;; +341;160;160;;;;;; +341;160;176;;;;;; +341;176;128;;;;;; +341;176;144;;;;;; +341;176;160;;;;;; +341;176;176;;;;;; +341;192;128;;;;;; +341;192;144;;;;;; +341;192;160;;;;;; +341;192;176;;;;;; +341;208;128;;;;;; +341;208;144;;;;;; +341;208;160;;;;;; +341;208;176;;;;;; +456;192;256 +223;64;80;;;;;;;; +223;82;37;;;;;;;; +223;128;128;;;;;;;; +223;128;144;;;;;;;; +223;128;160;;;;;;;; +223;128;176;;;;;;;; +223;132;64;;;;;;;; +223;144;80;;;;;;;; +223;160;80;;;;;;;; +223;176;80;;;;;;;; +223;192;80;;;;;;;; +223;208;80;;;;;;;; +223;240;128;;;;;;;; +223;240;144;;;;;;;; +223;240;160;;;;;;;; +223;240;176;;;;;;;; +340;112;16;;;;;; +340;112;32;;;;;; +340;128;16;;;;;; +340;128;32;;;;;; diff --git a/bin/Data/Maps/0 test map - holes.map.data b/bin/Data/Maps/0 test map - holes.map.data new file mode 100644 index 0000000..2f8b14b --- /dev/null +++ b/bin/Data/Maps/0 test map - holes.map.data @@ -0,0 +1,24 @@ +28 +22 +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - hookshot.map b/bin/Data/Maps/0 test map - hookshot.map new file mode 100644 index 0000000..369c080 --- /dev/null +++ b/bin/Data/Maps/0 test map - hookshot.map @@ -0,0 +1,623 @@ +3 +0 +0 +cave.png +28 +22 +3 +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,89,89,89,89,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,46,71,89,89,89,89,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,52,89,89,89,89,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,52,89,89,89,89,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +25 +0;128;144;;; +0;144;144;;; +0;144;160;;; +0;144;176;;; +330;128;112;test +341;160;128;;;;;; +341;160;144;;;;;; +341;160;160;;;;;; +341;160;176;;;;;; +341;176;128;;;;;; +341;176;144;;;;;; +341;176;160;;;;;; +341;176;176;;;;;; +341;192;128;;;;;; +341;192;144;;;;;; +341;192;160;;;;;; +341;192;176;;;;;; +341;208;128;;;;;; +341;208;144;;;;;; +341;208;160;;;;;; +341;208;176;;;;;; +223;128;128;;;;;;;; +223;336;144;;;;;;;; +223;352;128;;;;;;;; +223;368;144;;;;;;;; diff --git a/bin/Data/Maps/0 test map - hookshot.map.data b/bin/Data/Maps/0 test map - hookshot.map.data new file mode 100644 index 0000000..2f8b14b --- /dev/null +++ b/bin/Data/Maps/0 test map - hookshot.map.data @@ -0,0 +1,24 @@ +28 +22 +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - item test.map b/bin/Data/Maps/0 test map - item test.map new file mode 100644 index 0000000..09a6040 --- /dev/null +++ b/bin/Data/Maps/0 test map - item test.map @@ -0,0 +1,604 @@ +3 +1 +0 +cave.png +38 +17 +3 +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,,,,,,,,,,,,,,,,,, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,,,,,,,,,,,,,,,,,, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,,,,,,,,,,,,,,,,,, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,,,,,,,,,,,,,,,,,, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,,,,,,,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,,,,,,,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,,,,,,,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,,,,,,,,,,,,,,,,,, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,,,,,,,,,,,,,,,,,, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,,,,,,,,,,,,,,,,,, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,,,,,,,,,,,,,,,,,, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,,,,,,,,,,,,,,,,,, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,,,,19,19,19,19,19,19,19,19,19,19,19,19,19,, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,,,,19,19,19,19,19,19,19,19,19,19,19,19,19,, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,,,,19,19,19,19,19,19,19,19,19,19,19,19,19,, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,,,,19,19,19,19,19,19,19,19,19,19,19,19,19,, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +524 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +waterfallSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +20 +340;416;80;;;;;; +200;400;224;;;heartMeterFull;; +200;424;80;;;ruby5;; +200;432;112;;;ruby;; +200;432;224;;;heartMeter;; +200;448;112;;;ruby;; +200;464;112;;;ruby;; +200;464;224;;;heartMeterSilent;; +200;480;48;;;ruby200;; +200;480;112;;;ruby;; +200;496;48;;;ruby200;; +200;496;112;;;ruby;; +200;496;224;;;trade0;; +200;512;48;;;ruby200;; +200;512;112;;;ruby;; +200;528;112;;;ruby;; +200;544;112;;;ruby;; +200;576;80;;test_marin_collected;marin;; +201;16;16;10 +287;-32;0;12 diff --git a/bin/Data/Maps/0 test map - item test.map.data b/bin/Data/Maps/0 test map - item test.map.data new file mode 100644 index 0000000..610b72a --- /dev/null +++ b/bin/Data/Maps/0 test map - item test.map.data @@ -0,0 +1,19 @@ +38 +17 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - kirby.map b/bin/Data/Maps/0 test map - kirby.map new file mode 100644 index 0000000..0bd1a62 --- /dev/null +++ b/bin/Data/Maps/0 test map - kirby.map @@ -0,0 +1,560 @@ +3 +0 +0 +cave.png +3 +5 +3 +48,48,48, +48,48,48, +48,48,48, +48,48,48, +48,48,48, +,,, +,,, +,,, +,,, +,,, +,,, +,,, +,,, +,,, +,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +13 +0;0;0;;; +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;0;64;;; +0;16;0;;; +0;16;64;;; +0;32;0;;; +0;32;16;;; +0;32;32;;; +0;32;48;;; +0;32;64;;; +475;16;48 diff --git a/bin/Data/Maps/0 test map - kirby.map.data b/bin/Data/Maps/0 test map - kirby.map.data new file mode 100644 index 0000000..93c116a --- /dev/null +++ b/bin/Data/Maps/0 test map - kirby.map.data @@ -0,0 +1,7 @@ +3 +5 +;;; +;;; +;;; +;;; +;;; diff --git a/bin/Data/Maps/0 test map - levels.map b/bin/Data/Maps/0 test map - levels.map new file mode 100644 index 0000000..913ce63 --- /dev/null +++ b/bin/Data/Maps/0 test map - levels.map @@ -0,0 +1,635 @@ +3 +0 +0 +cave.png +18 +15 +3 +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,8,6,6,6,6,6,6,6,71,63,63,63,63,63, +63,63,63,63,7,48,48,48,48,48,48,48,5,63,63,63,63,63, +63,63,63,63,7,48,48,48,48,48,48,48,5,63,63,63,63,63, +63,63,63,63,7,48,48,48,48,48,48,48,5,63,63,63,63,63, +63,63,63,63,7,48,48,48,48,48,48,48,5,63,63,63,63,63, +63,63,63,63,9,4,4,4,20,4,4,4,10,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +58 +334;224;96;barrierTest;; +334;224;112;barrierTest;; +334;224;128;barrierTest;True; +334;224;144;barrierTest;True; +330;248;136;barrierTest +25;64;64;;;; +25;64;80;;;; +25;64;96;;;; +25;64;112;;;; +25;64;128;;;; +25;64;144;;;; +25;80;64;;;; +25;80;144;;;; +25;96;64;;;; +25;96;144;;;; +25;112;64;;;; +25;112;144;;;; +25;128;64;;;; +25;144;64;;;; +25;144;144;;;; +25;160;64;;;; +25;160;144;;;; +25;176;64;;;; +25;176;144;;;; +25;192;64;;;; +25;192;80;;;; +25;192;96;;;; +25;192;112;;;; +25;192;128;;;; +25;192;144;;;; +246;80;80; +246;80;96; +246;80;112; +246;80;128; +246;96;80; +246;96;96; +246;96;112; +246;96;128; +246;112;80; +246;112;96; +246;112;112; +246;112;128; +246;128;80; +246;128;96; +246;128;112; +246;128;128; +246;144;80; +246;144;96; +246;144;112; +246;144;128; +246;160;80; +246;160;96; +246;160;112; +246;160;128; +246;176;80; +246;176;96; +246;176;112; +246;176;128; diff --git a/bin/Data/Maps/0 test map - levels.map.data b/bin/Data/Maps/0 test map - levels.map.data new file mode 100644 index 0000000..091c9bf --- /dev/null +++ b/bin/Data/Maps/0 test map - levels.map.data @@ -0,0 +1,17 @@ +18 +15 +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - mermaid.map b/bin/Data/Maps/0 test map - mermaid.map new file mode 100644 index 0000000..7cdcb32 --- /dev/null +++ b/bin/Data/Maps/0 test map - mermaid.map @@ -0,0 +1,589 @@ +3 +0 +0 +cave.png +16 +14 +3 +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +15 +374;16;16; +158;16;16 +158;16;32 +158;16;48 +158;16;64 +158;16;80 +158;16;96 +158;32;96 +158;48;96 +158;64;96 +158;80;96 +158;96;96 +158;112;96 +158;128;96 +158;144;96 diff --git a/bin/Data/Maps/0 test map - mermaid.map.data b/bin/Data/Maps/0 test map - mermaid.map.data new file mode 100644 index 0000000..9aa64d6 --- /dev/null +++ b/bin/Data/Maps/0 test map - mermaid.map.data @@ -0,0 +1,16 @@ +16 +14 +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - music test.map b/bin/Data/Maps/0 test map - music test.map new file mode 100644 index 0000000..5923246 --- /dev/null +++ b/bin/Data/Maps/0 test map - music test.map @@ -0,0 +1,557 @@ +3 +0 +0 +cave.png +10 +8 +3 +19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +1 +287;16;16;88 diff --git a/bin/Data/Maps/0 test map - music test.map.data b/bin/Data/Maps/0 test map - music test.map.data new file mode 100644 index 0000000..c90cdd4 --- /dev/null +++ b/bin/Data/Maps/0 test map - music test.map.data @@ -0,0 +1,10 @@ +10 +8 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - new draw pool.map b/bin/Data/Maps/0 test map - new draw pool.map new file mode 100644 index 0000000..f79e881 --- /dev/null +++ b/bin/Data/Maps/0 test map - new draw pool.map @@ -0,0 +1,845 @@ +3 +1 +0 +cave.png +157 +104 +3 +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +1 +195;16;16;; diff --git a/bin/Data/Maps/0 test map - new draw pool.map.data b/bin/Data/Maps/0 test map - new draw pool.map.data new file mode 100644 index 0000000..1984cf4 --- /dev/null +++ b/bin/Data/Maps/0 test map - new draw pool.map.data @@ -0,0 +1,106 @@ +157 +104 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - qicksand.map b/bin/Data/Maps/0 test map - qicksand.map new file mode 100644 index 0000000..439edad --- /dev/null +++ b/bin/Data/Maps/0 test map - qicksand.map @@ -0,0 +1,585 @@ +3 +0 +0 +cave.png +18 +15 +3 +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +8 +191;0;0;0.25;0.25; +191;0;16;0.25;0.25; +191;0;32;0.25;0.25; +191;0;48;0.25;0.25; +191;16;0;-0.25;0.25; +191;16;16;-0.25;0.25; +191;16;32;-0.25;0.25; +191;16;48;-0.25;0.25; diff --git a/bin/Data/Maps/0 test map - qicksand.map.data b/bin/Data/Maps/0 test map - qicksand.map.data new file mode 100644 index 0000000..091c9bf --- /dev/null +++ b/bin/Data/Maps/0 test map - qicksand.map.data @@ -0,0 +1,17 @@ +18 +15 +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - raft.map b/bin/Data/Maps/0 test map - raft.map new file mode 100644 index 0000000..5dbf223 --- /dev/null +++ b/bin/Data/Maps/0 test map - raft.map @@ -0,0 +1,815 @@ +3 +0 +0 +cave.png +16 +14 +3 +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +241 +243;32;-16;raft_active +29;0;-16;;;; +29;16;-16;;;; +29;32;-16;;;; +29;48;-16;;;; +29;64;-16;;;; +29;80;-16;;;; +29;96;-16;;;; +29;112;-16;;;; +29;128;-16;;;; +29;144;-16;;;; +29;160;-16;;;; +29;176;-16;;;; +29;192;-16;;;; +29;208;-16;;;; +29;224;-16;;;; +29;240;-16;;;; +158;0;0 +158;0;16 +158;0;32 +158;0;48 +158;0;64 +158;0;80 +158;0;96 +158;0;112 +158;0;128 +158;0;144 +158;0;160 +158;0;176 +158;0;192 +158;0;208 +158;16;0 +158;16;16 +158;16;32 +158;16;48 +158;16;64 +158;16;80 +158;16;96 +158;16;112 +158;16;128 +158;16;144 +158;16;160 +158;16;176 +158;16;192 +158;16;208 +158;32;0 +158;32;16 +158;32;32 +158;32;48 +158;32;64 +158;32;80 +158;32;96 +158;32;112 +158;32;128 +158;32;144 +158;32;160 +158;32;176 +158;32;192 +158;32;208 +158;48;0 +158;48;16 +158;48;32 +158;48;48 +158;48;64 +158;48;80 +158;48;96 +158;48;112 +158;48;128 +158;48;144 +158;48;160 +158;48;176 +158;48;192 +158;48;208 +158;64;0 +158;64;16 +158;64;32 +158;64;48 +158;64;64 +158;64;80 +158;64;96 +158;64;112 +158;64;128 +158;64;144 +158;64;160 +158;64;176 +158;64;192 +158;64;208 +158;80;0 +158;80;16 +158;80;32 +158;80;48 +158;80;64 +158;80;80 +158;80;96 +158;80;112 +158;80;128 +158;80;144 +158;80;160 +158;80;176 +158;80;192 +158;80;208 +158;96;0 +158;96;16 +158;96;32 +158;96;48 +158;96;64 +158;96;80 +158;96;96 +158;96;112 +158;96;128 +158;96;144 +158;96;160 +158;96;176 +158;96;192 +158;96;208 +158;112;0 +158;112;16 +158;112;32 +158;112;48 +158;112;64 +158;112;80 +158;112;96 +158;112;112 +158;112;128 +158;112;144 +158;112;160 +158;112;176 +158;112;192 +158;112;208 +158;128;0 +158;128;16 +158;128;32 +158;128;48 +158;128;64 +158;128;80 +158;128;96 +158;128;112 +158;128;128 +158;128;144 +158;128;160 +158;128;176 +158;128;192 +158;128;208 +158;144;0 +158;144;16 +158;144;32 +158;144;48 +158;144;64 +158;144;80 +158;144;96 +158;144;112 +158;144;128 +158;144;144 +158;144;160 +158;144;176 +158;144;192 +158;144;208 +158;160;0 +158;160;16 +158;160;32 +158;160;48 +158;160;64 +158;160;80 +158;160;96 +158;160;112 +158;160;128 +158;160;144 +158;160;160 +158;160;176 +158;160;192 +158;160;208 +158;176;0 +158;176;16 +158;176;32 +158;176;48 +158;176;64 +158;176;80 +158;176;96 +158;176;112 +158;176;128 +158;176;144 +158;176;160 +158;176;176 +158;176;192 +158;176;208 +158;192;0 +158;192;16 +158;192;32 +158;192;48 +158;192;64 +158;192;80 +158;192;96 +158;192;112 +158;192;128 +158;192;144 +158;192;160 +158;192;176 +158;192;192 +158;192;208 +158;208;0 +158;208;16 +158;208;32 +158;208;48 +158;208;64 +158;208;80 +158;208;96 +158;208;112 +158;208;128 +158;208;144 +158;208;160 +158;208;176 +158;208;192 +158;208;208 +158;224;0 +158;224;16 +158;224;32 +158;224;48 +158;224;64 +158;224;80 +158;224;96 +158;224;112 +158;224;128 +158;224;144 +158;224;160 +158;224;176 +158;224;192 +158;224;208 +158;240;0 +158;240;16 +158;240;32 +158;240;48 +158;240;64 +158;240;80 +158;240;96 +158;240;112 +158;240;128 +158;240;144 +158;240;160 +158;240;176 +158;240;192 +158;240;208 diff --git a/bin/Data/Maps/0 test map - raft.map.data b/bin/Data/Maps/0 test map - raft.map.data new file mode 100644 index 0000000..9aa64d6 --- /dev/null +++ b/bin/Data/Maps/0 test map - raft.map.data @@ -0,0 +1,16 @@ +16 +14 +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - rail jump.map b/bin/Data/Maps/0 test map - rail jump.map new file mode 100644 index 0000000..1987b4f --- /dev/null +++ b/bin/Data/Maps/0 test map - rail jump.map @@ -0,0 +1,620 @@ +3 +0 +0 +cave.png +28 +22 +3 +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,70,70,70,70,70,70,70,70,70,70,70,70,70,70,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,70,70,70,70,70,70,70,70,70,70,70,70,70,70,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,70,70,70,70,70,70,70,70,70,70,70,70,70,70,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,70,70,70,70,70,70,70,70,70,70,70,70,70,70,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,70,70,70,69,46,71,70,70,70,4,4,4,29,70,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,70,70,70,30,70,52,70,70,70,4,4,70,70,70,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,70,70,70,70,47,74,70,70,70,4,70,70,70,70,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,70,70,70,70,70,70,70,70,70,70,70,70,70,70,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,70,70,70,70,70,70,70,70,70,70,70,70,70,70,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,70,70,70,70,70,70,70,70,70,70,70,70,70,70,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +22 +0;112;144;;; +0;128;112;;; +0;128;192;;; +0;144;144;;; +0;144;176;;; +0;160;160;;; +0;208;144;;; +0;208;160;;; +0;208;176;;; +0;224;144;;; +0;224;160;;; +0;240;144;;; +4;112;160;;; +2;256;144;;; +162;112;160;-10;4;;;;;;; +162;128;112;;-18;;;;;;; +162;128;192;;18;;;;;;; +162;160;160;18;;;;;;;; +162;208;144;;48;;;;;;; +162;224;144;;32;;;;;;; +162;240;144;;16;;;;;;; +162;256;144;;8;;;;;;; diff --git a/bin/Data/Maps/0 test map - rail jump.map.data b/bin/Data/Maps/0 test map - rail jump.map.data new file mode 100644 index 0000000..2f8b14b --- /dev/null +++ b/bin/Data/Maps/0 test map - rail jump.map.data @@ -0,0 +1,24 @@ +28 +22 +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - sequence.map b/bin/Data/Maps/0 test map - sequence.map new file mode 100644 index 0000000..2e7d8b4 --- /dev/null +++ b/bin/Data/Maps/0 test map - sequence.map @@ -0,0 +1,560 @@ +3 +0 +0 +cave.png +13 +9 +3 +19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19, +,,,,,,,,,,,,, +,,,,,,,,,,,,, +,,,,,,,,,,,,, +,,,,,,,,,,,,, +,,,,,,,,,,,,, +,,,,,,,,,,,,, +,,,,,,,,,,,,, +,,,,,,,,,,,,, +,,,,,,,,,,,,, +,,,,,,,,,,,,, +,,,,,,,,,,,,, +,,,,,,,,,,,,, +,,,,,,,,,,,,, +,,,,,,,,,,,,, +,,,,,,,,,,,,, +,,,,,,,,,,,,, +,,,,,,,,,,,,, +,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +1 +175;0;0;;;test_sequence diff --git a/bin/Data/Maps/0 test map - sequence.map.data b/bin/Data/Maps/0 test map - sequence.map.data new file mode 100644 index 0000000..560c295 --- /dev/null +++ b/bin/Data/Maps/0 test map - sequence.map.data @@ -0,0 +1,11 @@ +13 +9 +;;;;;;;;;;;;; +;;;;;;;;;;;;; +;;;;;;;;;;;;; +;;;;;;;;;;;;; +;;;;;;;;;;;;; +;;;;;;;;;;;;; +;;;;;;;;;;;;; +;;;;;;;;;;;;; +;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - sprites.map b/bin/Data/Maps/0 test map - sprites.map new file mode 100644 index 0000000..dcc19b5 --- /dev/null +++ b/bin/Data/Maps/0 test map - sprites.map @@ -0,0 +1,639 @@ +3 +0 +0 +cave.png +31 +24 +3 +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,81,19,81,19,81,19,81,19,81,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,81,19,81,19,81,19,81,19,81,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,81,19,81,19,81,19,81,19,81,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,81,19,81,19,81,19,81,19,81,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,81,19,81,19,81,19,81,19,81,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +35 +59;80;128;;;;;; +63;16;160;;;;;; +54;80;80;;;;;; +56;144;80;;;;;; +62;144;128;;;;;; +69;112;192;;;;;; +49;112;48;;;;;; +50;80;48;;;;;; +51;144;64;;;;;; +53;48;96;;;;;; +52;16;96;;;;;; +55;112;96;;;;;; +58;48;128;;;;;; +68;80;192;;;;;; +64;112;160;;;;;; +70;144;192;;;;;; +57;16;128;;;;;; +44;400;16;;;;;; +61;112;128;;;;;; +65;144;144;;;;;; +66;16;176;;;;;; +67;48;176;;;;;; +47;16;64;;;;;; +48;48;64;;;; +43;464;16;;;;;; +35;16;16;;;;;; +38;160;16;;;;;; +39;208;16;;;;;; +40;256;16;;;;;; +41;304;16;;;;;; +42;352;16;;;;;; +36;64;16;;;;;; +37;112;16;;;;;; +73;48;160;;;; +74;80;160;;;; diff --git a/bin/Data/Maps/0 test map - sprites.map.data b/bin/Data/Maps/0 test map - sprites.map.data new file mode 100644 index 0000000..b3aef6f --- /dev/null +++ b/bin/Data/Maps/0 test map - sprites.map.data @@ -0,0 +1,26 @@ +31 +24 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - stop music test.map b/bin/Data/Maps/0 test map - stop music test.map new file mode 100644 index 0000000..8d7d12e --- /dev/null +++ b/bin/Data/Maps/0 test map - stop music test.map @@ -0,0 +1,565 @@ +3 +0 +0 +cave.png +20 +10 +3 +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +3 +287;-32;0;2 +203;16;16;test_sign_0;;; +203;48;16;test_sign_1;;; diff --git a/bin/Data/Maps/0 test map - stop music test.map.data b/bin/Data/Maps/0 test map - stop music test.map.data new file mode 100644 index 0000000..3692ce6 --- /dev/null +++ b/bin/Data/Maps/0 test map - stop music test.map.data @@ -0,0 +1,12 @@ +20 +10 +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - transition bug.map b/bin/Data/Maps/0 test map - transition bug.map new file mode 100644 index 0000000..4010ce1 --- /dev/null +++ b/bin/Data/Maps/0 test map - transition bug.map @@ -0,0 +1,572 @@ +3 +0 +0 +cave.png +17 +13 +3 +,,,,,,,,19,,,,,,,,, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +1 +153;128;0;;;d6;0 test map dungeon.map;d6;3;; diff --git a/bin/Data/Maps/0 test map - transition bug.map.data b/bin/Data/Maps/0 test map - transition bug.map.data new file mode 100644 index 0000000..281a5f8 --- /dev/null +++ b/bin/Data/Maps/0 test map - transition bug.map.data @@ -0,0 +1,15 @@ +17 +13 +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - turtle head.map b/bin/Data/Maps/0 test map - turtle head.map new file mode 100644 index 0000000..e974fef --- /dev/null +++ b/bin/Data/Maps/0 test map - turtle head.map @@ -0,0 +1,1215 @@ +3 +0 +0 +cave.png +28 +22 +3 +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +617 +509;208;0; +212;0;0 +212;0;16 +212;0;32 +212;0;48 +212;0;64 +212;0;80 +212;0;96 +212;0;112 +212;0;128 +212;0;144 +212;0;160 +212;0;176 +212;0;192 +212;0;208 +212;0;224 +212;0;240 +212;0;256 +212;0;272 +212;0;288 +212;0;304 +212;0;320 +212;0;336 +212;16;0 +212;16;16 +212;16;32 +212;16;48 +212;16;64 +212;16;80 +212;16;96 +212;16;112 +212;16;128 +212;16;144 +212;16;160 +212;16;176 +212;16;192 +212;16;208 +212;16;224 +212;16;240 +212;16;256 +212;16;272 +212;16;288 +212;16;304 +212;16;320 +212;16;336 +212;32;0 +212;32;16 +212;32;32 +212;32;48 +212;32;64 +212;32;80 +212;32;96 +212;32;112 +212;32;128 +212;32;144 +212;32;160 +212;32;176 +212;32;192 +212;32;208 +212;32;224 +212;32;240 +212;32;256 +212;32;272 +212;32;288 +212;32;304 +212;32;320 +212;32;336 +212;48;0 +212;48;16 +212;48;32 +212;48;48 +212;48;64 +212;48;80 +212;48;96 +212;48;112 +212;48;128 +212;48;144 +212;48;160 +212;48;176 +212;48;192 +212;48;208 +212;48;224 +212;48;240 +212;48;256 +212;48;272 +212;48;288 +212;48;304 +212;48;320 +212;48;336 +212;64;0 +212;64;16 +212;64;32 +212;64;48 +212;64;64 +212;64;80 +212;64;96 +212;64;112 +212;64;128 +212;64;144 +212;64;160 +212;64;176 +212;64;192 +212;64;208 +212;64;224 +212;64;240 +212;64;256 +212;64;272 +212;64;288 +212;64;304 +212;64;320 +212;64;336 +212;80;0 +212;80;16 +212;80;32 +212;80;48 +212;80;64 +212;80;80 +212;80;96 +212;80;112 +212;80;128 +212;80;144 +212;80;160 +212;80;176 +212;80;192 +212;80;208 +212;80;224 +212;80;240 +212;80;256 +212;80;272 +212;80;288 +212;80;304 +212;80;320 +212;80;336 +212;96;0 +212;96;16 +212;96;32 +212;96;48 +212;96;64 +212;96;80 +212;96;96 +212;96;112 +212;96;128 +212;96;144 +212;96;160 +212;96;176 +212;96;192 +212;96;208 +212;96;224 +212;96;240 +212;96;256 +212;96;272 +212;96;288 +212;96;304 +212;96;320 +212;96;336 +212;112;0 +212;112;16 +212;112;32 +212;112;48 +212;112;64 +212;112;80 +212;112;96 +212;112;112 +212;112;128 +212;112;144 +212;112;160 +212;112;176 +212;112;192 +212;112;208 +212;112;224 +212;112;240 +212;112;256 +212;112;272 +212;112;288 +212;112;304 +212;112;320 +212;112;336 +212;128;0 +212;128;16 +212;128;32 +212;128;48 +212;128;64 +212;128;80 +212;128;96 +212;128;112 +212;128;128 +212;128;144 +212;128;160 +212;128;176 +212;128;192 +212;128;208 +212;128;224 +212;128;240 +212;128;256 +212;128;272 +212;128;288 +212;128;304 +212;128;320 +212;128;336 +212;144;0 +212;144;16 +212;144;32 +212;144;48 +212;144;64 +212;144;80 +212;144;96 +212;144;112 +212;144;128 +212;144;144 +212;144;160 +212;144;176 +212;144;192 +212;144;208 +212;144;224 +212;144;240 +212;144;256 +212;144;272 +212;144;288 +212;144;304 +212;144;320 +212;144;336 +212;160;0 +212;160;16 +212;160;32 +212;160;48 +212;160;64 +212;160;80 +212;160;96 +212;160;112 +212;160;128 +212;160;144 +212;160;160 +212;160;176 +212;160;192 +212;160;208 +212;160;224 +212;160;240 +212;160;256 +212;160;272 +212;160;288 +212;160;304 +212;160;320 +212;160;336 +212;176;0 +212;176;16 +212;176;32 +212;176;48 +212;176;64 +212;176;80 +212;176;96 +212;176;112 +212;176;128 +212;176;144 +212;176;160 +212;176;176 +212;176;192 +212;176;208 +212;176;224 +212;176;240 +212;176;256 +212;176;272 +212;176;288 +212;176;304 +212;176;320 +212;176;336 +212;192;0 +212;192;16 +212;192;32 +212;192;48 +212;192;64 +212;192;80 +212;192;96 +212;192;112 +212;192;128 +212;192;144 +212;192;160 +212;192;176 +212;192;192 +212;192;208 +212;192;224 +212;192;240 +212;192;256 +212;192;272 +212;192;288 +212;192;304 +212;192;320 +212;192;336 +212;208;0 +212;208;16 +212;208;32 +212;208;48 +212;208;64 +212;208;80 +212;208;96 +212;208;112 +212;208;128 +212;208;144 +212;208;160 +212;208;176 +212;208;192 +212;208;208 +212;208;224 +212;208;240 +212;208;256 +212;208;272 +212;208;288 +212;208;304 +212;208;320 +212;208;336 +212;224;0 +212;224;16 +212;224;32 +212;224;48 +212;224;64 +212;224;80 +212;224;96 +212;224;112 +212;224;128 +212;224;144 +212;224;160 +212;224;176 +212;224;192 +212;224;208 +212;224;224 +212;224;240 +212;224;256 +212;224;272 +212;224;288 +212;224;304 +212;224;320 +212;224;336 +212;240;0 +212;240;16 +212;240;32 +212;240;48 +212;240;64 +212;240;80 +212;240;96 +212;240;112 +212;240;128 +212;240;144 +212;240;160 +212;240;176 +212;240;192 +212;240;208 +212;240;224 +212;240;240 +212;240;256 +212;240;272 +212;240;288 +212;240;304 +212;240;320 +212;240;336 +212;256;0 +212;256;16 +212;256;32 +212;256;48 +212;256;64 +212;256;80 +212;256;96 +212;256;112 +212;256;128 +212;256;144 +212;256;160 +212;256;176 +212;256;192 +212;256;208 +212;256;224 +212;256;240 +212;256;256 +212;256;272 +212;256;288 +212;256;304 +212;256;320 +212;256;336 +212;272;0 +212;272;16 +212;272;32 +212;272;48 +212;272;64 +212;272;80 +212;272;96 +212;272;112 +212;272;128 +212;272;144 +212;272;160 +212;272;176 +212;272;192 +212;272;208 +212;272;224 +212;272;240 +212;272;256 +212;272;272 +212;272;288 +212;272;304 +212;272;320 +212;272;336 +212;288;0 +212;288;16 +212;288;32 +212;288;48 +212;288;64 +212;288;80 +212;288;96 +212;288;112 +212;288;128 +212;288;144 +212;288;160 +212;288;176 +212;288;192 +212;288;208 +212;288;224 +212;288;240 +212;288;256 +212;288;272 +212;288;288 +212;288;304 +212;288;320 +212;288;336 +212;304;0 +212;304;16 +212;304;32 +212;304;48 +212;304;64 +212;304;80 +212;304;96 +212;304;112 +212;304;128 +212;304;144 +212;304;160 +212;304;176 +212;304;192 +212;304;208 +212;304;224 +212;304;240 +212;304;256 +212;304;272 +212;304;288 +212;304;304 +212;304;320 +212;304;336 +212;320;0 +212;320;16 +212;320;32 +212;320;48 +212;320;64 +212;320;80 +212;320;96 +212;320;112 +212;320;128 +212;320;144 +212;320;160 +212;320;176 +212;320;192 +212;320;208 +212;320;224 +212;320;240 +212;320;256 +212;320;272 +212;320;288 +212;320;304 +212;320;320 +212;320;336 +212;336;0 +212;336;16 +212;336;32 +212;336;48 +212;336;64 +212;336;80 +212;336;96 +212;336;112 +212;336;128 +212;336;144 +212;336;160 +212;336;176 +212;336;192 +212;336;208 +212;336;224 +212;336;240 +212;336;256 +212;336;272 +212;336;288 +212;336;304 +212;336;320 +212;336;336 +212;352;0 +212;352;16 +212;352;32 +212;352;48 +212;352;64 +212;352;80 +212;352;96 +212;352;112 +212;352;128 +212;352;144 +212;352;160 +212;352;176 +212;352;192 +212;352;208 +212;352;224 +212;352;240 +212;352;256 +212;352;272 +212;352;288 +212;352;304 +212;352;320 +212;352;336 +212;368;0 +212;368;16 +212;368;32 +212;368;48 +212;368;64 +212;368;80 +212;368;96 +212;368;112 +212;368;128 +212;368;144 +212;368;160 +212;368;176 +212;368;192 +212;368;208 +212;368;224 +212;368;240 +212;368;256 +212;368;272 +212;368;288 +212;368;304 +212;368;320 +212;368;336 +212;384;0 +212;384;16 +212;384;32 +212;384;48 +212;384;64 +212;384;80 +212;384;96 +212;384;112 +212;384;128 +212;384;144 +212;384;160 +212;384;176 +212;384;192 +212;384;208 +212;384;224 +212;384;240 +212;384;256 +212;384;272 +212;384;288 +212;384;304 +212;384;320 +212;384;336 +212;400;0 +212;400;16 +212;400;32 +212;400;48 +212;400;64 +212;400;80 +212;400;96 +212;400;112 +212;400;128 +212;400;144 +212;400;160 +212;400;176 +212;400;192 +212;400;208 +212;400;224 +212;400;240 +212;400;256 +212;400;272 +212;400;288 +212;400;304 +212;400;320 +212;400;336 +212;416;0 +212;416;16 +212;416;32 +212;416;48 +212;416;64 +212;416;80 +212;416;96 +212;416;112 +212;416;128 +212;416;144 +212;416;160 +212;416;176 +212;416;192 +212;416;208 +212;416;224 +212;416;240 +212;416;256 +212;416;272 +212;416;288 +212;416;304 +212;416;320 +212;416;336 +212;432;0 +212;432;16 +212;432;32 +212;432;48 +212;432;64 +212;432;80 +212;432;96 +212;432;112 +212;432;128 +212;432;144 +212;432;160 +212;432;176 +212;432;192 +212;432;208 +212;432;224 +212;432;240 +212;432;256 +212;432;272 +212;432;288 +212;432;304 +212;432;320 +212;432;336 diff --git a/bin/Data/Maps/0 test map - turtle head.map.data b/bin/Data/Maps/0 test map - turtle head.map.data new file mode 100644 index 0000000..2f8b14b --- /dev/null +++ b/bin/Data/Maps/0 test map - turtle head.map.data @@ -0,0 +1,24 @@ +28 +22 +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map - walrus.map b/bin/Data/Maps/0 test map - walrus.map new file mode 100644 index 0000000..01093ef --- /dev/null +++ b/bin/Data/Maps/0 test map - walrus.map @@ -0,0 +1,581 @@ +3 +0 +0 +cave.png +20 +16 +3 +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +1 +373;144;112; diff --git a/bin/Data/Maps/0 test map - walrus.map.data b/bin/Data/Maps/0 test map - walrus.map.data new file mode 100644 index 0000000..c56ac4a --- /dev/null +++ b/bin/Data/Maps/0 test map - walrus.map.data @@ -0,0 +1,18 @@ +20 +16 +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map color jump tile.map.data b/bin/Data/Maps/0 test map color jump tile.map.data new file mode 100644 index 0000000..966622a --- /dev/null +++ b/bin/Data/Maps/0 test map color jump tile.map.data @@ -0,0 +1,12 @@ +12 +10 +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map levels.map.data b/bin/Data/Maps/0 test map levels.map.data new file mode 100644 index 0000000..091c9bf --- /dev/null +++ b/bin/Data/Maps/0 test map levels.map.data @@ -0,0 +1,17 @@ +18 +15 +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map new draw pool.map.data b/bin/Data/Maps/0 test map new draw pool.map.data new file mode 100644 index 0000000..1984cf4 --- /dev/null +++ b/bin/Data/Maps/0 test map new draw pool.map.data @@ -0,0 +1,106 @@ +157 +104 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map qicksand.map.data b/bin/Data/Maps/0 test map qicksand.map.data new file mode 100644 index 0000000..091c9bf --- /dev/null +++ b/bin/Data/Maps/0 test map qicksand.map.data @@ -0,0 +1,17 @@ +18 +15 +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/0 test map.map b/bin/Data/Maps/0 test map.map new file mode 100644 index 0000000..8614800 --- /dev/null +++ b/bin/Data/Maps/0 test map.map @@ -0,0 +1,715 @@ +3 +0 +0 +cave.png +28 +22 +3 +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,25,25,19,19,19,19,19,25,25,25,25,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,19,19,25,25,25,25,25,25,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,19,19,19,19,19,19,19,25,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,19,19,19,19,19,19,19,25,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,19,19,19,19,19,19,19,25,19,19,19,19,19,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,19,19,19,19,19,19,19, +19,19,19,19,19,25,25,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +117 +0;80;64;;; +0;80;80;;; +0;80;96;;; +0;80;112;;; +0;80;128;;; +0;80;144;;; +0;80;160;;; +0;80;176;;; +0;80;192;;; +0;80;208;;; +0;80;224;;; +0;80;240;;; +0;80;256;;; +0;80;272;;; +0;96;64;;; +0;96;80;;; +0;96;96;;; +0;96;112;;; +0;96;128;;; +0;96;144;;; +0;96;160;;; +0;96;176;;; +0;96;192;;; +0;96;208;;; +0;96;224;;; +0;96;240;;; +0;96;256;;; +0;96;272;;; +0;112;64;;; +0;112;128;;; +0;112;224;;; +0;112;240;;; +0;112;256;;; +0;128;64;;; +0;128;128;;; +0;128;224;;; +0;128;240;;; +0;128;256;;; +0;144;64;;; +0;144;144;;; +0;144;224;;; +0;144;240;;; +0;144;256;;; +0;160;64;;; +0;160;144;;; +0;160;224;;; +0;160;240;;; +0;160;256;;; +0;176;64;;; +0;176;144;;; +0;176;224;;; +0;176;240;;; +0;176;256;;; +0;192;64;;; +0;192;144;;; +0;192;224;;; +0;192;240;;; +0;192;256;;; +0;208;64;;; +0;208;144;;; +0;208;224;;; +0;208;240;;; +0;208;256;;; +0;224;64;;; +0;224;128;;; +0;224;144;;; +0;224;176;;; +0;224;192;;; +0;224;208;;; +0;224;224;;; +0;224;240;;; +0;224;256;;; +0;240;64;;; +0;240;128;;; +0;240;224;;; +0;240;240;;; +0;240;256;;; +0;256;64;;; +0;256;128;;; +0;256;224;;; +0;256;240;;; +0;256;256;;; +0;272;64;;; +0;272;128;;; +0;272;224;;; +0;272;240;;; +0;272;256;;; +0;288;64;;; +0;288;224;;; +0;288;240;;; +0;288;256;;; +0;304;64;;; +0;304;224;;; +0;304;240;;; +0;304;256;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +0;320;112;;; +0;320;128;;; +0;320;144;;; +0;320;160;;; +0;320;176;;; +0;320;192;;; +0;320;208;;; +0;320;224;;; +0;320;240;;; +0;320;256;;; +261;224;160;;test_door;2; +334;160;96;btest1;; +334;176;96;btest1;; +334;192;96;btest1;; +330;160;112;btest1 +406;200;160 +168;176;192;test_door;!test_button; +167;192;192;test_button;0 +170;224;160;test_button;;;; diff --git a/bin/Data/Maps/0 test map.map.data b/bin/Data/Maps/0 test map.map.data new file mode 100644 index 0000000..2f8b14b --- /dev/null +++ b/bin/Data/Maps/0 test map.map.data @@ -0,0 +1,24 @@ +28 +22 +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/Tilesets/blur tileset.png b/bin/Data/Maps/Tilesets/blur tileset.png new file mode 100644 index 0000000..e113c0f Binary files /dev/null and b/bin/Data/Maps/Tilesets/blur tileset.png differ diff --git a/bin/Data/Maps/Tilesets/castle.png b/bin/Data/Maps/Tilesets/castle.png new file mode 100644 index 0000000..9363790 Binary files /dev/null and b/bin/Data/Maps/Tilesets/castle.png differ diff --git a/bin/Data/Maps/Tilesets/cave.png b/bin/Data/Maps/Tilesets/cave.png new file mode 100644 index 0000000..c84a512 Binary files /dev/null and b/bin/Data/Maps/Tilesets/cave.png differ diff --git a/bin/Data/Maps/Tilesets/desertTempleTileset.png b/bin/Data/Maps/Tilesets/desertTempleTileset.png new file mode 100644 index 0000000..5832bdc Binary files /dev/null and b/bin/Data/Maps/Tilesets/desertTempleTileset.png differ diff --git a/bin/Data/Maps/Tilesets/dreamShrineTileset.png b/bin/Data/Maps/Tilesets/dreamShrineTileset.png new file mode 100644 index 0000000..a1d057e Binary files /dev/null and b/bin/Data/Maps/Tilesets/dreamShrineTileset.png differ diff --git a/bin/Data/Maps/Tilesets/dungeon 1.png b/bin/Data/Maps/Tilesets/dungeon 1.png new file mode 100644 index 0000000..2fa82d3 Binary files /dev/null and b/bin/Data/Maps/Tilesets/dungeon 1.png differ diff --git a/bin/Data/Maps/Tilesets/dungeon 2.png b/bin/Data/Maps/Tilesets/dungeon 2.png new file mode 100644 index 0000000..649c740 Binary files /dev/null and b/bin/Data/Maps/Tilesets/dungeon 2.png differ diff --git a/bin/Data/Maps/Tilesets/dungeon 3.png b/bin/Data/Maps/Tilesets/dungeon 3.png new file mode 100644 index 0000000..0352f1f Binary files /dev/null and b/bin/Data/Maps/Tilesets/dungeon 3.png differ diff --git a/bin/Data/Maps/Tilesets/dungeon 4.png b/bin/Data/Maps/Tilesets/dungeon 4.png new file mode 100644 index 0000000..92f710b Binary files /dev/null and b/bin/Data/Maps/Tilesets/dungeon 4.png differ diff --git a/bin/Data/Maps/Tilesets/dungeon 5.png b/bin/Data/Maps/Tilesets/dungeon 5.png new file mode 100644 index 0000000..1a47ca2 Binary files /dev/null and b/bin/Data/Maps/Tilesets/dungeon 5.png differ diff --git a/bin/Data/Maps/Tilesets/dungeon 6.png b/bin/Data/Maps/Tilesets/dungeon 6.png new file mode 100644 index 0000000..992e62c Binary files /dev/null and b/bin/Data/Maps/Tilesets/dungeon 6.png differ diff --git a/bin/Data/Maps/Tilesets/dungeon 7.png b/bin/Data/Maps/Tilesets/dungeon 7.png new file mode 100644 index 0000000..aec0973 Binary files /dev/null and b/bin/Data/Maps/Tilesets/dungeon 7.png differ diff --git a/bin/Data/Maps/Tilesets/dungeon 8.png b/bin/Data/Maps/Tilesets/dungeon 8.png new file mode 100644 index 0000000..ca19d47 Binary files /dev/null and b/bin/Data/Maps/Tilesets/dungeon 8.png differ diff --git a/bin/Data/Maps/Tilesets/dungeon color.png b/bin/Data/Maps/Tilesets/dungeon color.png new file mode 100644 index 0000000..73c12da Binary files /dev/null and b/bin/Data/Maps/Tilesets/dungeon color.png differ diff --git a/bin/Data/Maps/Tilesets/egg.png b/bin/Data/Maps/Tilesets/egg.png new file mode 100644 index 0000000..cc3a378 Binary files /dev/null and b/bin/Data/Maps/Tilesets/egg.png differ diff --git a/bin/Data/Maps/Tilesets/hole.png b/bin/Data/Maps/Tilesets/hole.png new file mode 100644 index 0000000..769d89a Binary files /dev/null and b/bin/Data/Maps/Tilesets/hole.png differ diff --git a/bin/Data/Maps/Tilesets/house.png b/bin/Data/Maps/Tilesets/house.png new file mode 100644 index 0000000..da9894a Binary files /dev/null and b/bin/Data/Maps/Tilesets/house.png differ diff --git a/bin/Data/Maps/Tilesets/tileset 2d.png b/bin/Data/Maps/Tilesets/tileset 2d.png new file mode 100644 index 0000000..e342df2 Binary files /dev/null and b/bin/Data/Maps/Tilesets/tileset 2d.png differ diff --git a/bin/Data/Maps/Tilesets/tileset size.txt b/bin/Data/Maps/Tilesets/tileset size.txt new file mode 100644 index 0000000..e9d80ba --- /dev/null +++ b/bin/Data/Maps/Tilesets/tileset size.txt @@ -0,0 +1,3 @@ +// this file can be used to set the size of tiles for tilesets that do not uses tiles that are 16x16 +//dungeon five.png:32 +//tileset0.png:48 \ No newline at end of file diff --git a/bin/Data/Maps/Tilesets/tileset0.png b/bin/Data/Maps/Tilesets/tileset0.png new file mode 100644 index 0000000..63fa686 Binary files /dev/null and b/bin/Data/Maps/Tilesets/tileset0.png differ diff --git a/bin/Data/Maps/bridge.map b/bin/Data/Maps/bridge.map new file mode 100644 index 0000000..db3a05a --- /dev/null +++ b/bin/Data/Maps/bridge.map @@ -0,0 +1,608 @@ +3 +1 +0 +tileset 2d.png +12 +9 +3 +,1,1,1,1,1,1,1,1,1,1,, +,35,35,35,35,35,35,35,35,35,35,, +,37,60,6,5,6,5,6,5,6,5,, +,26,36,34,34,34,34,34,34,34,34,, +,7,13,0,0,0,0,0,0,0,0,, +,7,13,4,0,0,0,0,4,4,0,, +,7,7,12,0,0,4,0,14,10,10,, +,7,7,7,10,10,10,10,7,7,7,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +0,,,,,,,,,,,, +0,,,,,,,,,,,, +0,,,,,,,,,,,, +0,,,,,,,,,,,, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +49 +126;48;64;;;;; +126;64;64;;;;; +126;80;64;;;;; +126;96;64;;;;; +126;112;64;;;;; +126;128;64;;;;; +126;144;64;;;;; +126;160;64;;;;; +345;78;56 +0;32;32;;; +0;32;48;;; +0;32;64;;; +0;32;80;;; +0;48;96;;; +0;64;112;;; +0;80;112;;; +0;96;112;;; +0;112;112;;; +0;128;96;;; +0;144;96;;; +0;160;96;;; +0;176;32;;; +0;176;48;;; +153;176;64;;32;bridge;overworld.map;bridge;;3;False +257;-8;0 +287;-8;48;57 +177;-8;24 +158;48;64 +158;48;80 +158;64;64 +158;64;80 +158;64;96 +158;80;64 +158;80;80 +158;80;96 +158;96;64 +158;96;80 +158;96;96 +158;112;64 +158;112;80 +158;112;96 +158;128;64 +158;128;80 +158;144;64 +158;144;80 +158;160;64 +158;160;80 +158;176;64 +158;176;80 diff --git a/bin/Data/Maps/bridge.map.data b/bin/Data/Maps/bridge.map.data new file mode 100644 index 0000000..f8d4ad1 --- /dev/null +++ b/bin/Data/Maps/bridge.map.data @@ -0,0 +1,11 @@ +12 +9 +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; diff --git a/bin/Data/Maps/castle1.map b/bin/Data/Maps/castle1.map new file mode 100644 index 0000000..a8e984c --- /dev/null +++ b/bin/Data/Maps/castle1.map @@ -0,0 +1,770 @@ +3 +2 +1 +castle.png +24 +18 +3 +,,,,,,,,,,,,,,,,,,,,,,,, +,,,,58,61,61,61,60,61,61,61,61,61,61,61,61,61,61,59,,,,, +,,,58,69,14,14,14,14,14,14,14,14,14,14,14,14,14,14,66,59,,,, +,,58,69,14,5,13,13,13,13,13,13,13,13,0,13,13,13,4,14,66,59,,, +,,64,0,13,27,58,61,61,61,61,61,61,61,9,61,61,59,28,13,0,63,,, +,61,69,58,61,61,69,0,0,0,0,0,0,0,0,0,0,66,61,61,59,66,61,, +,,58,69,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,59,,, +,,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,63,,, +,,64,0,0,0,0,0,0,0,0,68,62,62,62,62,62,62,62,62,62,56,,, +,,64,0,0,0,0,0,0,0,0,66,61,61,61,61,61,61,61,61,61,59,,, +,,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,,, +,,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,,, +,,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,,, +,,57,62,62,62,62,62,62,62,62,62,62,67,0,0,0,0,0,0,68,56,,, +,,,,,,,,,,,,,64,0,2,29,29,3,0,63,,,, +,,,,,,,,,,,,,64,0,7,43,42,8,0,63,,,, +,,,,,,,,,,,,,57,62,55,40,39,54,62,56,,,, +,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,, +,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,, +,,0,0,,,,,,,,,,,,,,,,,0,0,,, +,0,0,,,,,,,,,,,,,,,,,,,0,0,, +,0,,,,,,,,,,,,,,,,,,,,,0,, +0,0,,,,,,,,,,,,,,,,,,,,,0,0, +0,0,,,,,,,,,,,,,,,,,,,,,0,0, +0,0,,,,,,,,,,,,,,,,,,,,,0,0, +,0,,,,,,,,,,,,,,,,,,,,,0,, +,0,,,,,,,,,,,,,,,,,,,,,0,, +,0,,,,,,,,,,,,,,,,,,,,,0,, +,0,,,,,,,,,,,,,,,,,,,,,0,, +,0,,,,,,,,,,,,,,,,,,,,,0,, +,0,,,,,,,,,,,,,,,,,,,,,0,, +,0,,,,,,,,,,,,,,,,,,,,,0,, +,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,0,0,, +,,,,,,,,,,,,0,,,,,,,,,0,,, +,,,,,,,,,,,,0,,,,,,,,,0,,, +,,,,,,,,,,,,0,0,0,0,,,0,0,0,0,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +184 +169;320;112;ow_castle_button +0;32;112;;; +0;32;128;;; +0;32;144;;; +0;32;160;;; +0;32;176;;; +0;32;192;;; +0;48;48;;; +0;48;96;;; +0;48;208;;; +0;64;32;;; +0;64;208;;; +0;80;16;;; +0;80;208;;; +0;96;16;;; +0;96;208;;; +0;112;16;;; +0;112;208;;; +0;128;208;;; +0;144;16;;; +0;144;208;;; +0;160;16;;; +0;160;208;;; +0;176;16;;; +0;176;128;;; +0;176;144;;; +0;176;208;;; +0;192;16;;; +0;192;128;;; +0;192;144;;; +0;192;208;;; +0;208;16;;; +0;208;128;;; +0;208;144;;; +0;208;208;;; +0;208;224;;; +0;208;240;;; +0;224;16;;; +0;224;128;;; +0;224;144;;; +0;224;256;;; +0;240;16;;; +0;240;128;;; +0;240;144;;; +0;240;256;;; +0;256;16;;; +0;256;128;;; +0;256;144;;; +0;272;16;;; +0;272;128;;; +0;272;144;;; +0;288;16;;; +0;288;128;;; +0;288;144;;; +0;288;256;;; +0;304;32;;; +0;304;128;;; +0;304;144;;; +0;304;256;;; +0;320;48;;; +0;320;80;;; +0;320;96;;; +0;320;128;;; +0;320;144;;; +0;320;208;;; +0;320;224;;; +0;320;240;;; +0;336;64;;; +0;336;112;;; +0;336;160;;; +0;336;176;;; +0;336;192;;; +20;288;64;;; +21;80;64;;; +1;248;240;;; +1;280;240;;; +3;256;256;;; +4;272;256;;; +16;288;48;;; +17;80;48;;; +153;128;16;;;c1_2;castle2.map;c1_2;3;; +153;264;264;;;c1_1;overworld.map;c1_1;1;; +299;264;256;;;;;; +284;32;288;;;;125 +428;144;192 +418;128;112 +417;80;96 +417;80;160 +417;128;160 +417;288;96 +426;256;112 +424;64;192 +252;56;152;castle_et_1 +22;128;16;;;; +22;264;272;;;; +302;48;64;;;;; +302;48;112;;;;; +302;112;80;;;;; +302;224;208;;;;; +302;224;224;;;;; +302;224;240;;;;; +302;256;80;;;;; +302;304;96;;;;; +302;304;208;;;;; +302;304;224;;;;; +302;304;240;;;;; +302;320;64;;;;; +307;96;16;;;;; +307;160;16;;;;; +10;64;64;;; +10;96;48;;; +10;112;48;;; +10;128;48;;; +10;144;48;;; +10;160;48;;; +10;176;48;;; +10;192;48;;; +10;208;48;;; +10;240;48;;; +10;256;48;;; +10;272;48;;; +10;304;64;;; +25;64;80;;;; +25;80;80;;;; +25;96;64;;;; +25;96;80;;;; +25;112;64;;;; +25;128;64;;;; +25;144;64;;;; +25;160;64;;;; +25;176;64;;;; +25;192;64;;;; +25;208;64;;;; +25;240;64;;;; +25;256;64;;;; +25;272;64;;;; +25;272;80;;;; +25;288;80;;;; +25;304;80;;;; +287;96;288;18 +164;368;112;ow_castle_button;1;dialogBox;ow_castle_door;False +166;104;176;castle_et_1;1;castle_spawn_0 +160;224;64; +61;80;128;;;;;; +61;80;144;;;;;; +61;128;128;;;;;; +61;128;144;;;;;; +61;240;160;;;;;; +61;288;160;;;;;; +246;64;48; +246;64;64; +246;80;32; +246;80;48; +246;80;64; +246;96;32; +246;96;48; +246;112;32; +246;112;48; +246;128;32; +246;128;48; +246;144;32; +246;144;48; +246;160;32; +246;160;48; +246;176;32; +246;176;48; +246;192;32; +246;192;48; +246;208;32; +246;208;48; +246;224;32; +246;224;48; +246;224;64; +246;240;32; +246;240;48; +246;256;32; +246;256;48; +246;272;32; +246;272;48; +246;288;32; +246;288;48; +246;288;64; +246;304;48; +246;304;64; diff --git a/bin/Data/Maps/castle1.map.data b/bin/Data/Maps/castle1.map.data new file mode 100644 index 0000000..f7da95f --- /dev/null +++ b/bin/Data/Maps/castle1.map.data @@ -0,0 +1,20 @@ +24 +18 +;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/castle2.map b/bin/Data/Maps/castle2.map new file mode 100644 index 0000000..7782867 --- /dev/null +++ b/bin/Data/Maps/castle2.map @@ -0,0 +1,875 @@ +3 +2 +2 +castle.png +23 +19 +3 +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,64,,,,,,,,,, +,,,58,61,61,65,61,61,61,61,61,61,69,58,61,61,61,61,61,61,59,, +,,58,69,0,0,14,0,0,0,0,0,0,12,64,50,50,50,50,50,50,63,, +,61,69,13,13,13,0,13,13,13,13,13,4,12,64,50,0,0,0,0,50,63,, +,,58,61,70,61,9,61,61,70,61,59,10,12,64,50,0,0,0,0,50,63,, +,,64,0,0,0,0,0,0,0,0,63,10,12,64,50,0,0,0,0,50,63,, +,,64,0,0,0,0,0,0,0,0,63,10,12,64,50,0,0,0,0,50,63,, +,,64,0,0,0,0,0,0,0,0,63,10,12,64,50,0,0,0,68,62,56,, +,,57,62,62,62,62,62,62,62,62,56,10,12,57,62,24,22,62,56,,,, +,,26,11,11,11,11,11,11,11,11,11,6,12,58,61,25,23,61,59,,,, +,,28,13,13,13,0,0,13,13,13,13,13,27,64,14,14,14,14,63,,,, +,,58,61,61,61,9,9,61,61,61,59,58,61,69,0,14,14,0,66,61,59,, +,,64,0,0,0,14,14,0,0,0,63,64,0,0,0,14,14,0,0,0,63,, +,,64,0,0,0,14,14,0,0,0,63,64,0,0,0,14,14,0,0,0,63,, +,,64,0,0,2,29,29,3,0,0,63,64,0,0,2,29,29,3,0,0,63,, +,,64,0,0,7,43,42,8,0,0,63,64,0,0,7,43,42,8,0,0,63,, +,,57,62,62,55,40,39,54,62,62,56,57,62,62,55,40,39,54,62,62,56,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,0,0,0,,,,,,,,, +,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +,0,0,,,,,,,,,,,,,,,,,,,,0, +0,0,,,,,,,,,,,,,,,,,,,,,0, +0,0,,,,,,,,,,,,,,,,,,,,,0, +0,0,,,,,,,,,,,,,,,,,,,,,0, +,0,,,,,,,,,,,,,,,,,,,,,0, +,0,,,,,,,,,,,,,,,,,,,,,0, +,0,,,,,,,,,,,,,,,,,,,,,0, +,0,,,,,,,,,,,,,,,,,,,0,0,0, +,0,,,,,,,,,,,,,,,,,,,0,,, +,0,,,,,,,,,,,,,,,,,,,0,0,0, +,0,,,,,,,,,,,,,,,,,,,,,0, +,0,,,,,,,,,,,,,,,,,,,,,0, +,0,,,,,,,,,,,,,,,,,,,,,0, +,0,,,,,,,,,,,,,,,,,,,,,0, +,0,,,,,,,,,,,,,,,,,,,,,0, +,0,,,,,,,,,,,,,,,,,,,,,0, +,0,0,0,0,0,,,0,0,0,0,0,0,0,0,,,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +286 +279;240;64; +279;240;80; +279;240;96; +279;240;112; +279;240;128; +279;256;48; +279;272;48; +279;288;48; +279;304;48; +279;320;64; +279;320;80; +279;320;96; +279;320;112; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;16;128;;; +0;16;144;;; +0;16;160;;; +0;16;176;;; +0;16;192;;; +0;32;64;;; +0;32;192;;; +0;32;208;;; +0;32;224;;; +0;32;240;;; +0;32;256;;; +0;48;48;;; +0;48;272;;; +0;64;32;;; +0;64;272;;; +0;80;32;;; +0;80;272;;; +0;112;32;;; +0;128;32;;; +0;128;272;;; +0;144;32;;; +0;144;272;;; +0;160;32;;; +0;160;272;;; +0;176;32;;; +0;176;208;;; +0;176;224;;; +0;176;240;;; +0;176;256;;; +0;192;32;;; +0;192;208;;; +0;192;224;;; +0;192;240;;; +0;192;256;;; +0;208;32;;; +0;208;272;;; +0;224;272;;; +0;240;32;;; +0;240;144;;; +0;240;160;;; +0;240;272;;; +0;256;32;;; +0;272;32;;; +0;288;32;;; +0;288;144;;; +0;288;160;;; +0;288;272;;; +0;304;32;;; +0;304;128;;; +0;304;144;;; +0;304;160;;; +0;304;176;;; +0;304;192;;; +0;304;272;;; +0;320;32;;; +0;320;128;;; +0;320;192;;; +0;320;272;;; +0;336;48;;; +0;336;64;;; +0;336;80;;; +0;336;96;;; +0;336;112;;; +0;336;208;;; +0;336;224;;; +0;336;240;;; +0;336;256;;; +20;32;176;;; +21;208;176;;; +14;192;160;;; +1;88;256;;; +1;120;256;;; +1;248;256;;; +1;280;256;;; +3;96;272;;; +3;256;144;;; +3;256;160;;; +3;256;272;;; +4;112;272;;; +4;272;144;;; +4;272;160;;; +4;272;272;;; +16;192;64;;; +18;32;160;;; +261;264;144;;castle_door;1; +261;264;160;;castle_door;3; +153;96;32;;;c1_2;castle1.map;c1_2;3;; +153;104;280;;;c2_1;overworld.map;c2_1;1;; +153;264;280;;;c2_2;overworld.map;c2_2;1;; +284;32;304;;;;125 +419;64;80;True +419;144;80; +427;96;132;3;; +22;96;32;;;; +22;104;288;;;; +22;200;48;;;; +22;200;64;;;; +22;264;288;;;; +253;264;160;1024;castle_pot;;;;; +342;264;128; +168;360;152;castle_door;castle_pot&(!castle_enter|castle_boss); +167;384;152;castle_enter;0 +302;64;112;;;;; +302;64;256;;;;; +302;144;112;;;;; +302;144;256;;;;; +302;224;256;;;;; +302;240;48;;;;; +302;304;256;;;;; +302;320;48;;;;; +307;80;32;;;;; +307;112;32;;;;; +170;264;144;castle_enter;1;;; +10;48;64;;; +10;48;176;;; +10;64;64;;; +10;64;176;;; +10;80;64;;; +10;80;176;;; +10;112;64;;; +10;128;64;;; +10;128;176;;; +10;144;64;;; +10;144;176;;; +10;160;64;;; +10;160;176;;; +10;176;64;;; +10;176;176;;; +10;192;176;;; +11;48;160;;; +11;64;160;;; +11;80;160;;; +11;96;160;;; +11;112;160;;; +11;128;160;;; +11;144;160;;; +11;160;160;;; +11;176;160;;; +12;192;80;;; +12;192;96;;; +12;192;112;;; +12;192;128;;; +12;192;144;;; +13;208;48;;; +13;208;64;;; +13;208;80;;; +13;208;96;;; +13;208;112;;; +13;208;128;;; +13;208;144;;; +13;208;160;;; +25;32;80;;;; +25;32;96;;;; +25;32;112;;;; +25;32;128;;;; +25;32;144;;;; +25;48;80;;;; +25;48;144;;;; +25;48;192;;;; +25;64;80;;;; +25;64;144;;;; +25;64;192;;;; +25;80;80;;;; +25;80;144;;;; +25;80;192;;;; +25;96;144;;;; +25;112;80;;;; +25;112;144;;;; +25;128;80;;;; +25;128;144;;;; +25;128;192;;;; +25;144;80;;;; +25;144;144;;;; +25;144;192;;;; +25;160;80;;;; +25;160;144;;;; +25;160;192;;;; +25;176;80;;;; +25;176;96;;;; +25;176;112;;;; +25;176;128;;;; +25;176;144;;;; +25;176;192;;;; +25;192;192;;;; +25;208;192;;;; +25;224;48;;;; +25;224;64;;;; +25;224;80;;;; +25;224;96;;;; +25;224;112;;;; +25;224;128;;;; +25;224;144;;;; +25;224;160;;;; +25;224;176;;;; +25;224;192;;;; +498;280;80;castle_boss +287;64;304;18 +165;288;192;castle_door;pot; +164;360;176;castle_door;1;dialogBox;castle_boss_door_sound;False +164;384;176;castle_boss;1;dialogBox;castle_boss_door_open;False +231;208;208;;bomb_1;;;; +231;208;224;;;;;; +231;224;208;;;;;; +231;240;192;;;;;; +231;304;208;;;;;; +231;320;208;;;;;; +231;320;224;;heart;;;; +160;96;80; +160;96;192; +160;112;192; +61;48;208;;;;;; +61;160;208;;;;;; +246;32;160; +246;32;176; +246;48;64; +246;48;160; +246;48;176; +246;64;48; +246;64;64; +246;64;160; +246;64;176; +246;80;48; +246;80;64; +246;80;160; +246;80;176; +246;96;48; +246;96;64; +246;96;80; +246;96;160; +246;96;176; +246;96;192; +246;112;48; +246;112;64; +246;112;160; +246;112;176; +246;112;192; +246;128;48; +246;128;64; +246;128;160; +246;128;176; +246;144;48; +246;144;64; +246;144;160; +246;144;176; +246;160;48; +246;160;64; +246;160;160; +246;160;176; +246;176;48; +246;176;64; +246;176;160; +246;176;176; +246;192;48; +246;192;64; +246;192;80; +246;192;96; +246;192;112; +246;192;128; +246;192;144; +246;192;160; +246;192;176; +246;208;48; +246;208;64; +246;208;80; +246;208;96; +246;208;112; +246;208;128; +246;208;144; +246;208;160; +246;208;176; diff --git a/bin/Data/Maps/castle2.map.data b/bin/Data/Maps/castle2.map.data new file mode 100644 index 0000000..beb0e7d --- /dev/null +++ b/bin/Data/Maps/castle2.map.data @@ -0,0 +1,21 @@ +23 +19 +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/castleTunnel.map b/bin/Data/Maps/castleTunnel.map new file mode 100644 index 0000000..200b5e8 --- /dev/null +++ b/bin/Data/Maps/castleTunnel.map @@ -0,0 +1,623 @@ +3 +1 +0 +castle.png +22 +9 +3 +,49,49,49,49,49,49,49,49,37,44,44,48,1,30,47,47,38,30,47,47,, +,49,49,49,49,49,49,49,49,37,44,44,48,18,41,46,46,45,41,46,46,, +,33,52,36,34,34,34,34,34,34,34,34,34,34,34,34,33,52,36,34,34,, +,15,52,32,35,35,35,35,35,35,35,35,35,35,35,35,31,52,16,17,17,, +,15,52,71,71,71,71,71,71,71,71,71,71,71,71,71,71,52,16,17,17,, +,15,71,71,71,71,71,71,71,71,71,71,71,71,71,71,52,20,17,17,17,, +,17,21,19,51,20,19,51,51,20,21,21,19,71,71,71,52,16,17,17,17,, +,17,17,17,17,17,17,17,17,17,17,17,17,21,21,21,21,17,17,17,17,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +64 +0;16;32;;; +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;32;96;;; +0;48;32;;; +0;48;48;;; +0;48;96;;; +0;64;48;;; +0;64;112;;; +0;80;48;;; +0;80;96;;; +0;96;48;;; +0;96;96;;; +0;112;48;;; +0;112;112;;; +0;128;48;;; +0;128;112;;; +0;144;48;;; +0;144;96;;; +0;160;48;;; +0;160;96;;; +0;176;48;;; +0;176;96;;; +0;192;48;;; +0;192;96;;; +0;208;48;;; +0;208;112;;; +0;224;48;;; +0;224;112;;; +0;240;48;;; +0;240;112;;; +0;256;32;;; +0;256;48;;; +0;256;112;;; +0;272;80;;; +0;272;96;;; +0;288;32;;; +0;288;48;;; +0;288;64;;; +153;32;24;;;tunelcastleleft;overworld.map;tunelcastleleft;3;; +153;272;24;;;tunelcastleright;overworld.map;tunelcastleright;3;; +284;-16;0;;;; +258;32;32; +258;32;48; +258;32;64; +258;256;80; +258;256;96; +258;272;32; +258;272;48; +258;272;64; +259;256;80; +484;208;96 +484;240;96 +303;64;80;;;;; +303;128;80;;;;; +303;224;80;;;;; +297;32;32;;;;;100; +297;288;-16;160;;;;150; +257;-16;32 +287;-16;64;37 +348;64;96 +348;112;96 +348;128;96 diff --git a/bin/Data/Maps/castleTunnel.map.data b/bin/Data/Maps/castleTunnel.map.data new file mode 100644 index 0000000..e6c70f1 --- /dev/null +++ b/bin/Data/Maps/castleTunnel.map.data @@ -0,0 +1,11 @@ +22 +9 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave bird.map.data b/bin/Data/Maps/cave bird.map.data new file mode 100644 index 0000000..ac712ae --- /dev/null +++ b/bin/Data/Maps/cave bird.map.data @@ -0,0 +1,18 @@ +10 +16 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/cave rooster.map b/bin/Data/Maps/cave rooster.map new file mode 100644 index 0000000..d36ec26 --- /dev/null +++ b/bin/Data/Maps/cave rooster.map @@ -0,0 +1,706 @@ +3 +0 +0 +cave.png +12 +18 +3 +,,,,,,,,,,,, +,,39,47,47,47,47,47,47,37,,, +,39,67,,,,,,,68,37,, +,45,,,69,46,46,71,,,44,, +,45,,,44,70,70,45,,,44,, +,45,,,44,70,70,45,,,44,, +,45,,,68,20,20,67,,,44,, +,36,71,,,,,,,69,38,, +,,36,46,71,63,63,69,46,38,,, +,,,,45,63,63,44,,,,, +,,,,45,63,63,44,,,,, +,,,,45,63,63,44,,,,, +,,,,45,63,63,44,,,,, +,,,,45,63,63,44,,,,, +,,,,45,63,63,44,,,,, +,,,,45,63,14,44,,,,, +,,,,36,46,46,38,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,0,0,0,0,0,0,0,0,0,0,, +0,0,3,,,,,,,4,0,0, +0,3,,,,,,,,,4,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,1,,,,,,,,,2,0, +0,0,1,,,,,,,2,0,0, +,0,0,0,,,,,0,0,0,, +,,,0,,,,,0,,,, +,,,0,,,,,0,,,, +,,,0,,,,,0,,,, +,,,0,,,,,0,,,, +,,,0,,,,,0,,,, +,,,0,,,,,0,,,, +,,,0,1,,,2,0,,,, +,,,0,0,0,0,0,0,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +120 +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;32;32;;; +0;32;112;;; +0;48;16;;; +0;48;128;;; +0;64;16;;; +0;64;128;;; +0;64;144;;; +0;64;160;;; +0;64;176;;; +0;64;192;;; +0;64;208;;; +0;64;224;;; +0;64;240;;; +0;80;16;;; +0;80;256;;; +0;96;16;;; +0;96;256;;; +0;112;16;;; +0;112;128;;; +0;112;144;;; +0;112;160;;; +0;112;176;;; +0;112;192;;; +0;112;208;;; +0;112;224;;; +0;112;240;;; +0;128;16;;; +0;128;128;;; +0;144;32;;; +0;144;112;;; +0;160;48;;; +0;160;64;;; +0;160;80;;; +0;160;96;;; +286;-16;256;;;; +298;96;240;;;;;; +386;88;64;rooster_respawned +153;96;240;;;cave_rooster;overworld.map;cave_rooster;;1; +162;72;64;-18;;8;32;;;;; +162;80;56;;-18;32;8;;;;; +162;112;64;18;;8;32;;;;; +25;64;48;;;; +25;64;64;;;; +25;64;80;;;; +25;64;96;;;; +25;80;48;;;; +25;96;48;;;; +25;112;48;;;; +25;112;64;;;; +25;112;80;;;; +25;112;96;;;; +287;-16;224;37 +160;80;96; +160;96;96; +246;80;64; +246;80;80; +246;80;96; +246;96;64; +246;96;80; +246;96;96; +157;32;48; +157;32;64; +157;32;80; +157;32;96; +157;48;32; +157;48;48; +157;48;64; +157;48;80; +157;48;96; +157;48;112; +157;64;32; +157;64;112; +157;80;32; +157;80;112; +157;96;32; +157;96;112; +157;112;32; +157;112;112; +157;128;32; +157;128;48; +157;128;64; +157;128;80; +157;128;96; +157;128;112; +157;144;48; +157;144;64; +157;144;80; +157;144;96; +108;32;48;;;;;; +108;32;64;;;;;; +108;32;80;;;;;; +108;32;96;;;;;; +108;48;32;;;;;; +108;48;48;;;;;; +108;48;64;;;;;; +108;48;80;;;;;; +108;48;96;;;;;; +108;48;112;;;;;; +108;64;32;;;;;; +108;64;112;;;;;; +108;80;32;;;;;; +108;80;112;;;;;; +108;96;32;;;;;; +108;96;112;;;;;; +108;112;32;;;;;; +108;112;112;;;;;; +108;128;32;;;;;; +108;128;48;;;;;; +108;128;64;;;;;; +108;128;80;;;;;; +108;128;96;;;;;; +108;128;112;;;;;; +108;144;48;;;;;; +108;144;64;;;;;; +108;144;80;;;;;; +108;144;96;;;;;; diff --git a/bin/Data/Maps/cave rooster.map.data b/bin/Data/Maps/cave rooster.map.data new file mode 100644 index 0000000..44ce7cb --- /dev/null +++ b/bin/Data/Maps/cave rooster.map.data @@ -0,0 +1,20 @@ +12 +18 +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;2;2;;;;;; +;;;;;2;2;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave0.map b/bin/Data/Maps/cave0.map new file mode 100644 index 0000000..6a63355 --- /dev/null +++ b/bin/Data/Maps/cave0.map @@ -0,0 +1,611 @@ +3 +1 +1 +cave.png +12 +10 +3 +,,,,,,,,,,,, +,,,39,47,47,47,47,37,,,, +,,39,67,70,70,70,70,68,37,,, +,39,67,70,70,27,70,70,70,68,37,, +,45,70,70,,,14,,70,70,44,, +,45,70,70,,,,,70,70,44,, +,36,71,70,70,,,70,27,69,38,, +,,36,71,70,70,70,70,69,38,,, +,,,36,46,46,46,46,38,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,0,0,0,0,0,0,0,0,,, +,0,0,3,,,,,4,0,0,, +0,0,3,,,,,,,4,0,0, +0,3,,,,,,,,,4,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,1,,,,,,,,,2,0, +0,0,1,,,,,,,2,0,0, +,0,0,1,,,,,2,0,0,, +,,0,0,0,0,0,0,0,0,,, +524 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +waterfallSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +48 +383;16;192; +0;16;64;;; +0;16;80;;; +0;32;48;;; +0;32;96;;; +0;48;32;;; +0;48;112;;; +0;64;16;;; +0;64;128;;; +0;80;16;;; +0;80;128;;; +0;96;16;;; +0;96;128;;; +0;112;16;;; +0;112;128;;; +0;128;32;;; +0;128;112;;; +0;144;48;;; +0;144;96;;; +0;160;64;;; +0;160;80;;; +286;16;160;;;;100 +153;96;64;;;;overworld.map;cave0;;1; +153;96;80;;;cave0;;;3;2;False +200;80;80;item;cave0_heart;heartMeter;; +167;192;64;sequence_fountain_marin;0 +298;88;72;126;;200;150;150; +287;48;160;37 +378;96;110;spawnMouseFountain;mouseSeqFountain +175;96;80;;;seq_fountain_mouse_spawn +157;64;64; +157;64;80; +157;80;64; +157;80;80; +157;80;96; +157;96;80; +157;96;96; +157;112;64; +157;112;80; +108;64;64;;;;;; +108;64;80;;;;;; +108;80;64;;;;;; +108;80;80;;;;;; +108;80;96;;;;;; +108;96;80;;;;;; +108;96;96;;;;;; +108;112;64;;;;;; +108;112;80;;;;;; diff --git a/bin/Data/Maps/cave0.map.data b/bin/Data/Maps/cave0.map.data new file mode 100644 index 0000000..4ad69f3 --- /dev/null +++ b/bin/Data/Maps/cave0.map.data @@ -0,0 +1,12 @@ +12 +10 +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;2;2;2;2;;;;; +;;;2;2;;2;2;2;;;; +;;2;2;;;;;2;2;;; +;;2;2;;;;;2;2;;; +;;;2;2;;;2;;;;; +;;;;2;2;2;2;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave1.map b/bin/Data/Maps/cave1.map new file mode 100644 index 0000000..fd6b245 --- /dev/null +++ b/bin/Data/Maps/cave1.map @@ -0,0 +1,720 @@ +3 +1 +1 +cave.png +22 +18 +3 +,,,,,,,,,,,,,,,,,,,,,, +,39,47,47,47,47,47,47,47,47,37,,,,,,,,,,,, +,45,63,70,63,63,70,70,70,63,68,47,47,47,47,37,,,,,,, +,45,70,63,63,70,70,63,63,70,70,70,70,70,70,68,37,,,,,, +,45,63,63,70,70,63,70,63,70,70,70,70,70,70,70,44,,,,,, +,45,63,70,63,63,70,63,63,63,69,46,46,71,70,70,44,,,,,, +,45,70,63,63,70,70,70,63,70,44,,,36,71,70,44,,,,,, +,36,71,63,70,63,70,63,63,69,38,,,,45,70,44,,,,,, +,,36,46,46,16,15,46,46,38,,,,,45,70,44,,,,,, +,,,,,,,,,,,39,47,47,67,70,68,47,47,37,,, +,,,,,,,,,,,45,86,86,86,86,86,86,86,68,37,, +,,,,,,,,,,,45,86,87,63,63,86,86,86,86,44,, +,,,,,,,,,,,45,86,88,63,63,63,70,86,86,44,, +,,,,,,,,,,,45,86,70,63,63,63,70,70,63,44,, +,,,,,,,,,,,45,86,86,86,86,63,70,63,63,44,, +,,,,,,,,,,,45,86,70,70,70,70,69,46,46,38,, +,,,,,,,,,,,36,46,46,46,16,15,38,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,, +0,3,,,,,,,,,4,0,0,0,0,0,0,,,,,, +0,,,,,,,,,,,,,,,4,0,0,,,,, +0,,,,,,,,,,,,,,,,4,0,,,,, +0,,,,,,,,,,,,,,,,,0,,,,, +0,,,,,,,,,,,,,,,,,0,,,,, +0,,,,,,,,,,,0,0,1,,,,0,,,,, +0,1,,,,,,,,,2,0,0,0,,,,0,,,,, +0,0,1,,,,,,,2,0,0,0,0,,,,0,0,0,0,, +,0,0,0,0,,,0,0,0,0,3,,,,,,,,4,0,0, +,,,,,,,,,,0,,,,,,,,,,4,0, +,,,,,,,,,,0,,,,,,,,,,,0, +,,,,,,,,,,0,,,,,,,,,,,0, +,,,,,,,,,,0,,,,,,,,,,,0, +,,,,,,,,,,0,,,,,,,,,,,0, +,,,,,,,,,,0,,,,,,,,,,2,0, +,,,,,,,,,,0,1,,,,,,2,0,0,0,0, +,,,,,,,,,,0,0,0,0,0,,,0,0,,,, +524 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +waterfallSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +133 +0;16;32;;; +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;32;16;;; +0;32;112;;; +0;48;16;;; +0;48;128;;; +0;64;16;;; +0;64;128;;; +0;80;16;;; +0;88;144;;; +0;96;16;;; +0;112;16;;; +0;112;128;;; +0;128;16;;; +0;128;128;;; +0;144;16;;; +0;144;112;;; +0;160;32;;; +0;160;80;;; +0;160;96;;; +0;176;32;;; +0;176;80;;; +0;176;160;;; +0;176;176;;; +0;176;192;;; +0;176;208;;; +0;176;224;;; +0;176;240;;; +0;192;32;;; +0;192;80;;; +0;192;144;;; +0;192;256;;; +0;208;32;;; +0;208;80;;; +0;208;144;;; +0;208;256;;; +0;224;32;;; +0;224;96;;; +0;224;112;;; +0;224;128;;; +0;224;144;;; +0;224;256;;; +0;240;48;;; +0;248;272;;; +0;256;64;;; +0;256;80;;; +0;256;96;;; +0;256;112;;; +0;256;128;;; +0;256;144;;; +0;272;144;;; +0;272;240;;; +0;272;256;;; +0;288;144;;; +0;288;240;;; +0;304;160;;; +0;304;240;;; +0;320;176;;; +0;320;192;;; +0;320;208;;; +0;320;224;;; +3;80;128;;; +3;240;256;;; +4;96;128;;; +4;256;256;;; +286;64;280;;;; +275;192;160; +275;192;176; +275;192;192; +275;192;208; +275;192;224; +275;192;240; +275;208;160; +275;224;160; +275;240;160; +275;256;160; +275;272;160; +275;288;160; +275;288;176; +275;288;192; +275;304;176; +275;304;192; +272;96;80;;;; +272;224;176;;;; +272;224;192;;;; +272;224;208;;;; +272;240;176;;;; +272;256;192;;;; +272;256;208;;;; +299;88;128;;;;;; +299;248;256;;;;;; +199;240;192;ruby50;;cave1chest;; +153;88;136;;;c1n;overworld.map;c1n;1;; +153;248;264;;;c1m;overworld.map;c1m;1;; +427;208;176 +427;208;224 +427;256;176 +427;272;176 +424;224;64;; +424;240;80;; +342;208;176;;;;;; +342;208;192;;;;;; +342;208;224;;;;;; +342;224;224;;;;;; +342;240;224;;;;;; +342;256;176;;;;;; +342;272;176;;;;;; +343;248;256; +200;64;64;;cave1_heartMeter;heartMeter;; +224;32;32;;;;;;;; +224;32;80;;;;;;;; +224;48;96;;;;;;;; +224;48;112;;;;;;;; +224;64;48;0;;;;;;; +224;64;80;;;;;;;; +224;64;96;;;;;;;; +224;80;32;0;;;;;;; +224;80;80;;;;;;;; +224;96;64;;;;;;;; +224;112;48;;;;;;;; +224;112;80;;;;;;;; +224;128;48;;;;;;;; +224;128;64;;;;;;;; +224;128;96;;;;;;;; +224;144;80;;;;;;;; +224;240;208;5;;;;;;; +224;256;224;1;;;;;;; +287;16;280;37 +230;80;64;;;;;; +230;96;48;;;;;; diff --git a/bin/Data/Maps/cave1.map.data b/bin/Data/Maps/cave1.map.data new file mode 100644 index 0000000..a21acce --- /dev/null +++ b/bin/Data/Maps/cave1.map.data @@ -0,0 +1,20 @@ +22 +18 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;2;;;2;2;2;;;;;;;;;;;;;; +;;2;;;2;2;;;2;2;2;2;2;2;;;;;;;; +;;;;2;2;;2;;2;2;2;2;2;2;2;;;;;;; +;;;2;;;2;;;;;;;;2;2;;;;;;; +;;2;;;2;2;2;;2;;;;;;2;;;;;;; +;;;;2;;2;;;;;;;;;2;;;;;;; +;;;;;;;;;;;;;;;2;;;;;;; +;;;;;;;;;;;;;;;2;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;2;;;;; +;;;;;;;;;;;;;2;;;;2;2;;;; +;;;;;;;;;;;;;;;;;2;;;;; +;;;;;;;;;;;;;2;2;2;2;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave10.map b/bin/Data/Maps/cave10.map new file mode 100644 index 0000000..db9f8ff --- /dev/null +++ b/bin/Data/Maps/cave10.map @@ -0,0 +1,674 @@ +3 +1 +1 +cave.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,,39,47,47,47,47,37,,,,,,39,47,47,47,47,47,37,,, +,39,67,87,86,86,86,68,47,47,47,47,47,67,86,86,63,70,70,68,37,, +,45,87,88,70,70,70,86,86,86,86,86,86,87,14,70,63,70,70,89,44,, +,45,89,70,14,70,70,70,70,70,70,70,70,89,70,87,87,87,86,88,44,, +,45,89,70,70,86,70,70,86,70,70,70,70,89,63,89,89,89,70,70,44,, +,45,88,87,70,70,86,70,70,70,70,70,87,89,87,89,88,88,86,69,38,, +,36,71,88,86,86,86,86,86,86,86,86,88,88,88,88,69,46,46,38,,, +,,36,46,46,46,46,46,46,46,46,46,46,46,46,46,38,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,0,0,0,0,0,0,0,0,,,,0,0,0,0,0,0,0,0,0,, +0,0,3,,,,,4,0,0,0,0,0,3,,,,,,4,0,0, +0,3,,,,,,,,,,,,,,,,,,,4,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,2,0, +0,1,,,,,,,,,,,,,,,,,,2,0,0, +0,0,1,,,,,,,,,,,,,,2,0,0,0,0,, +,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +112 +382;-24;64; +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;32;32;;; +0;32;112;;; +0;48;16;;; +0;48;128;;; +0;64;16;;; +0;64;128;;; +0;80;16;;; +0;80;128;;; +0;96;16;;; +0;96;128;;; +0;112;32;;; +0;112;128;;; +0;128;32;;; +0;128;128;;; +0;144;32;;; +0;144;128;;; +0;160;32;;; +0;160;128;;; +0;176;32;;; +0;176;128;;; +0;192;32;;; +0;192;128;;; +0;208;32;;; +0;208;128;;; +0;224;16;;; +0;224;128;;; +0;240;16;;; +0;240;128;;; +0;256;16;;; +0;256;112;;; +0;272;16;;; +0;272;112;;; +0;288;16;;; +0;288;112;;; +0;304;32;;; +0;304;96;;; +0;320;48;;; +0;320;64;;; +0;320;80;;; +286;-24;40;;;; +298;64;64;;;;;; +298;224;48;;;;;; +266;224;80;;cave10_rock;;; +153;64;64;;;cave10_l;overworld.map;cave10_l;;1; +153;224;48;;;cave10_r;overworld.map;cave10_r;3;1; +426;32;96 +426;112;48 +426;256;64 +422;112;96 +341;32;48;;;;;; +341;32;64;;;;;; +341;32;80;;;;;; +341;32;96;;;;;; +341;48;32;;;;;; +341;48;48;;;;;; +341;48;96;;;;;; +341;48;112;;;;;; +341;64;32;;;;;; +341;64;112;;;;;; +341;80;32;;;;;; +341;80;80;;;;;; +341;80;112;;;;;; +341;96;32;;;;;; +341;96;96;;;;;; +341;96;112;;;;;; +341;112;48;;;;;; +341;112;112;;;;;; +341;128;48;;;;;; +341;128;80;;;;;; +341;128;112;;;;;; +341;144;48;;;;;; +341;144;112;;;;;; +341;160;48;;;;;; +341;160;112;;;;;; +341;176;48;;;;;; +341;176;112;;;;;; +341;192;48;;;;;; +341;192;96;;;;;; +341;192;112;;;;;; +341;208;48;;;;;; +341;208;64;;;;;; +341;208;80;;;;;; +341;208;96;;;;;; +341;208;112;;;;;; +341;224;32;;;;;; +341;224;96;;;;;; +341;224;112;;;;;; +341;240;32;;;;;; +341;240;64;;;;;; +341;240;80;;;;;; +341;240;96;;;;;; +341;240;112;;;;;; +341;256;64;;;;;; +341;256;80;;;;;; +341;256;96;;;;;; +341;272;64;;;;;; +341;272;80;;;;;; +341;272;96;;;;;; +341;288;64;;;;;; +341;288;96;;;;;; +341;304;48;;;;;; +341;304;64;;;;;; +200;272;32;;cave10_heartMeter;heartMeter;; +224;256;32;;;;;;;; +224;256;48;;;;;;;; +224;304;80;;;;;;;; +287;-24;16;37 diff --git a/bin/Data/Maps/cave10.map.data b/bin/Data/Maps/cave10.map.data new file mode 100644 index 0000000..72b3c57 --- /dev/null +++ b/bin/Data/Maps/cave10.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;2;2;2;;;; +;;;;2;2;2;;;;;;;;;2;2;2;2;;;; +;;;2;;2;2;2;2;2;2;2;2;;2;;;;;;;; +;;;2;2;;2;2;;2;2;2;2;;2;;;;2;2;;; +;;;;2;2;;2;2;2;2;2;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave11.map b/bin/Data/Maps/cave11.map new file mode 100644 index 0000000..547a2aa --- /dev/null +++ b/bin/Data/Maps/cave11.map @@ -0,0 +1,724 @@ +3 +1 +1 +cave.png +21 +18 +3 +,,,,,,,,,,,,,,,,,,,,, +,,,39,47,47,47,47,37,,,,,,,,,,,,, +,,,45,70,70,70,70,44,,,,,,39,47,47,47,37,,, +,,,45,70,70,70,70,44,,,,,39,67,,,,68,37,, +,,39,67,70,70,70,70,68,37,,,,45,,,70,,,44,, +,,45,70,70,70,70,70,70,44,,,,45,,70,70,70,,44,, +,39,67,70,70,70,70,70,70,68,37,39,47,67,,,70,,,44,, +,45,70,70,70,70,70,70,70,70,82,82,70,70,70,,,,69,38,, +,45,70,70,70,70,70,70,70,70,44,36,46,46,46,46,46,46,38,,, +,45,70,70,70,70,70,70,70,70,44,,,,,,,,,,, +,45,70,70,70,70,70,70,70,70,44,,,,,,,,,,, +,45,70,70,70,70,70,70,70,70,44,,,,,,,,,,, +,45,63,63,63,63,63,70,63,63,44,,,,,,,,,,, +,45,70,70,70,70,70,70,70,70,44,,,,,,,,,,, +,45,70,70,70,70,70,70,70,70,44,,,,,,,,,,, +,36,71,70,70,70,70,70,70,69,38,,,,,,,,,,, +,,36,46,16,15,46,46,46,38,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,0,0,0,0,0,0,0,0,,,,,,,,,,,, +,,0,3,,,,,4,0,,,,0,0,0,0,0,0,0,, +,,0,,,,,,,0,,,0,0,3,,,,4,0,0, +,0,0,,,,,,,0,0,,0,3,,,,,,4,0, +,0,3,,,,,,,4,0,,0,,,,,,,,0, +0,0,,,,,,,,,0,0,0,,,,,,,,0, +0,3,,,,,,,,,4,3,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,2,0, +0,,,,,,,,,,,,,,,,,,2,0,0, +0,,,,,,,,,,,0,0,0,0,0,0,0,0,0,, +0,,,,,,,,,,,0,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,, +0,1,,,,,,,,,2,0,,,,,,,,,, +0,0,1,,,,,,,2,0,0,,,,,,,,,, +,0,0,0,,,0,0,0,0,0,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +138 +382;-16;288; +0;16;112;;; +0;16;128;;; +0;16;144;;; +0;16;160;;; +0;16;176;;; +0;16;192;;; +0;16;208;;; +0;16;224;;; +0;32;80;;; +0;32;96;;; +0;32;240;;; +0;48;32;;; +0;48;48;;; +0;48;64;;; +0;48;256;;; +0;64;16;;; +0;72;272;;; +0;80;16;;; +0;96;16;;; +0;96;256;;; +0;112;16;;; +0;112;256;;; +0;128;32;;; +0;128;48;;; +0;128;64;;; +0;128;256;;; +0;144;80;;; +0;144;96;;; +0;144;240;;; +0;160;96;;; +0;160;128;;; +0;160;144;;; +0;160;160;;; +0;160;176;;; +0;160;192;;; +0;160;208;;; +0;160;224;;; +0;176;96;;; +0;176;128;;; +0;192;96;;; +0;192;128;;; +0;208;64;;; +0;208;80;;; +0;208;96;;; +0;208;128;;; +0;224;48;;; +0;224;128;;; +0;240;32;;; +0;240;128;;; +0;256;32;;; +0;256;128;;; +0;272;32;;; +0;272;128;;; +0;288;48;;; +0;288;112;;; +0;304;64;;; +0;304;80;;; +0;304;96;;; +3;64;256;;; +4;80;256;;; +286;-16;256;;;; +298;72;256;;;;;125; +298;256;80;;;;;125; +199;144;208;ruby50;;cave11_r50;; +268;160;112;;cave11_wall;;; +153;72;264;;;cave11;overworld.map;cave11;1;; +248;176;16;cave11_wall;; +427;32;220;2;False; +427;64;28;2;False; +22;72;256;;;; +22;160;112;;;; +274;32;192;;;; +274;48;192;;;; +274;64;192;;;; +274;80;192;;;; +274;96;192;;;; +274;144;192;;;; +200;256;80;;cave11_heartMeter;heartMeter;; +224;32;208;0;;;;;;; +224;48;208;0;;;;;;; +224;64;96;0;;;;;;; +224;64;112;0;;;;;;; +224;64;128;0;;;;;;; +224;64;144;0;;;;;;; +224;64;160;0;;;;;;; +224;64;176;0;;;;;;; +224;64;208;0;;;;;;; +224;80;176;0;;;;;;; +224;80;208;0;;;;;;; +224;96;32;0;;;;;;; +224;96;48;0;;;;;;; +224;96;64;0;;;;;;; +224;96;80;0;;;;;;; +224;96;96;0;;;;;;; +224;96;112;0;;;;;;; +224;96;128;0;;;;;;; +224;96;144;0;;;;;;; +224;96;176;0;;;;;;; +224;112;176;0;;;;;;; +224;112;208;0;;;;;;; +224;112;224;0;;;;;;; +224;112;240;0;;;;;;; +224;128;176;0;;;;;;; +224;128;192;1;;;;;;; +287;-16;224;37 +157;224;64; +157;224;80; +157;224;96; +157;240;48; +157;240;64; +157;240;96; +157;240;112; +157;256;48; +157;256;112; +157;272;48; +157;272;64; +157;272;96; +157;272;112; +157;288;64; +157;288;80; +157;288;96; +108;224;64;;;;;; +108;224;80;;;;;; +108;224;96;;;;;; +108;240;48;;;;;; +108;240;64;;;;;; +108;240;96;;;;;; +108;240;112;;;;;; +108;256;48;;;;;; +108;256;112;;;;;; +108;272;48;;;;;; +108;272;64;;;;;; +108;272;96;;;;;; +108;272;112;;;;;; +108;288;64;;;;;; +108;288;80;;;;;; +108;288;96;;;;;; diff --git a/bin/Data/Maps/cave11.map.data b/bin/Data/Maps/cave11.map.data new file mode 100644 index 0000000..4c1ab4f --- /dev/null +++ b/bin/Data/Maps/cave11.map.data @@ -0,0 +1,20 @@ +21 +18 +;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;; +;;;;2;2;;2;;;;;;;;;;;;;; +;;;;2;2;;2;;;;;;;;;;;;;; +;;;;2;2;;2;;;;;;;;;2;;;;; +;;;2;2;2;;2;2;;;;;;;2;2;2;;;; +;;;2;;2;;2;2;;;;;;;;2;;;;; +;;2;2;;2;;2;2;2;;;2;2;2;;;;;;; +;;2;2;;2;;2;2;2;;;;;;;;;;;; +;;2;2;;2;;2;2;2;;;;;;;;;;;; +;;2;2;;2;2;2;2;2;;;;;;;;;;;; +;;2;2;;;;;;2;;;;;;;;;;;; +;;;;;;;2;;;;;;;;;;;;;; +;;;;;;2;;2;;;;;;;;;;;;; +;;2;2;2;2;2;;2;2;;;;;;;;;;;; +;;;2;2;2;2;;2;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave12.map b/bin/Data/Maps/cave12.map new file mode 100644 index 0000000..0b6b39c --- /dev/null +++ b/bin/Data/Maps/cave12.map @@ -0,0 +1,670 @@ +3 +1 +1 +cave.png +22 +18 +3 +,,,,,,,,,,,,,,,,,,,,,, +,,39,47,47,47,47,47,47,37,,,,,,,,,,,,, +,39,67,70,70,70,70,70,70,68,37,,,,,,,,,,,, +,45,70,27,70,70,27,27,70,70,44,,,,,,,,,,,, +,45,27,70,70,70,70,27,70,70,44,,,,,,,,,,,, +,45,70,70,70,27,70,70,70,70,44,,,,,,,,,,,, +,45,70,70,70,70,70,70,70,70,44,,,,,,,,,,,, +,36,71,70,70,70,70,70,27,69,38,,,,,,,,,,,, +,,36,46,46,83,46,46,46,38,,,,,,,,,,,,, +,,39,47,47,83,47,47,47,37,,,39,47,47,47,47,47,47,37,,, +,39,67,70,70,70,70,70,70,68,37,39,67,63,63,63,63,63,63,68,37,, +,45,70,27,70,70,27,27,70,70,44,45,63,70,63,63,70,70,63,63,44,, +,45,27,70,70,70,70,27,70,86,68,67,70,63,63,63,63,70,63,63,44,, +,45,70,86,70,27,70,70,70,70,70,70,63,63,63,70,63,63,63,63,44,, +,45,70,70,70,70,70,70,70,70,69,71,63,63,63,63,63,63,14,63,44,, +,36,71,86,70,70,70,70,27,69,38,36,71,63,63,63,63,63,70,69,38,, +,,36,46,46,46,46,46,46,38,,,36,46,46,46,46,46,46,38,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,, +0,0,3,,,,,,,4,0,0,,,,,,,,,,, +0,3,,,,,,,,,4,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,1,,,,,,,,,2,0,,,,,,,,,,, +0,0,1,,,,,,,2,0,0,0,0,0,0,0,0,0,0,0,, +0,0,3,,,,,,,4,0,0,3,,,,,,,4,0,0, +0,3,,,,,,,,,,,,,,,,,,,4,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,1,,,,,,,,,,,,,,,,,,,2,0, +0,0,1,,,,,,,2,0,0,1,,,,,,,2,0,0, +,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +84 +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;16;176;;; +0;16;192;;; +0;16;208;;; +0;16;224;;; +0;32;32;;; +0;32;112;;; +0;32;160;;; +0;32;240;;; +0;48;16;;; +0;48;128;;; +0;48;144;;; +0;48;256;;; +0;64;16;;; +0;64;128;;; +0;64;144;;; +0;64;256;;; +0;80;16;;; +0;80;256;;; +0;96;16;;; +0;96;128;;; +0;96;144;;; +0;96;256;;; +0;112;16;;; +0;112;128;;; +0;112;144;;; +0;112;256;;; +0;128;16;;; +0;128;128;;; +0;128;144;;; +0;128;256;;; +0;144;32;;; +0;144;112;;; +0;144;160;;; +0;144;240;;; +0;160;48;;; +0;160;64;;; +0;160;80;;; +0;160;96;;; +0;160;176;;; +0;160;192;;; +0;160;224;;; +0;176;176;;; +0;176;192;;; +0;176;224;;; +0;192;160;;; +0;192;240;;; +0;208;144;;; +0;208;256;;; +0;224;144;;; +0;224;256;;; +0;240;144;;; +0;240;256;;; +0;256;144;;; +0;256;256;;; +0;272;144;;; +0;272;256;;; +0;288;144;;; +0;288;256;;; +0;304;160;;; +0;304;240;;; +0;320;176;;; +0;320;192;;; +0;320;208;;; +0;320;224;;; +286;16;288;;;; +298;88;200;;;;;; +298;288;224;;;;;; +268;80;144;;cave12_wall;3;; +153;88;200;;;cave12_fall;overworld.map;;3;6; +153;288;224;;;cave12;overworld.map;cave12;;1; +248;16;16;cave12_wall;; +451;48;208 +451;48;240 +451;144;192 +341;48;208;;;;;; +341;48;240;;;;;; +341;144;192;;;;;; +200;72;40;;cave12_heartMeter;heartMeter;; +287;48;288;37 +164;80;192;ow_desertLanmola;1;item;.dkey3Collected.dkey3;False diff --git a/bin/Data/Maps/cave12.map.data b/bin/Data/Maps/cave12.map.data new file mode 100644 index 0000000..2b49e17 --- /dev/null +++ b/bin/Data/Maps/cave12.map.data @@ -0,0 +1,20 @@ +22 +18 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;2;2;2;2;2;2;;;;;;;;;;;;;; +;;2;;2;2;;;2;2;;;;;;;;;;;;; +;;;2;2;2;2;;2;2;;;;;;;;;;;;; +;;2;2;2;;2;2;2;2;;;;;;;;;;;;; +;;2;2;2;2;2;2;2;2;;;;;;;;;;;;; +;;;2;2;2;2;2;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;2;2;2;2;2;2;;;;;;;;;;;;;; +;;2;;2;2;;;2;2;;;;2;;;2;2;;;;; +;;;2;2;2;2;;2;;;;2;;;;;2;;;;; +;;2;;2;;2;2;2;2;2;2;;;;2;;;;;;; +;;2;2;2;2;2;2;2;2;;;;;;;;;;;;; +;;;;2;2;2;2;;;;;;;;;;;2;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave13.map b/bin/Data/Maps/cave13.map new file mode 100644 index 0000000..07e2069 --- /dev/null +++ b/bin/Data/Maps/cave13.map @@ -0,0 +1,676 @@ +3 +1 +1 +cave.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,,,,39,47,47,47,47,47,47,47,47,47,47,47,47,47,47,37,,, +,,,,45,27,70,63,63,70,63,63,70,86,86,86,86,63,70,44,,, +,,39,47,67,63,86,86,86,86,70,70,86,86,86,86,63,63,70,68,37,, +,39,67,27,70,86,63,63,63,63,63,63,63,63,86,86,63,63,17,70,44,, +,45,70,63,87,63,63,63,63,63,63,63,63,63,87,63,63,86,63,63,44,, +,45,27,70,89,63,63,87,86,86,70,70,86,86,88,63,86,86,86,63,44,, +,45,70,27,89,63,63,89,70,63,63,63,63,86,86,63,63,86,86,86,44,, +,36,46,46,46,16,15,46,46,46,46,46,46,46,46,46,46,46,46,46,38,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,, +,,,0,3,,,,,,,,,,,,,,,4,0,, +,0,0,0,,,,,,,,,,,,,,,,,0,0, +0,0,3,,,,,,,,,,,,,,,,,,4,0, +0,3,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,1,,,,,,,,,,,,,,,,,,,2,0, +0,0,0,0,0,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +114 +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;32;64;;; +0;32;128;;; +0;48;48;;; +0;48;128;;; +0;64;32;;; +0;64;48;;; +0;64;128;;; +0;80;16;;; +0;88;144;;; +0;96;16;;; +0;112;16;;; +0;112;128;;; +0;128;16;;; +0;128;128;;; +0;144;16;;; +0;144;128;;; +0;160;16;;; +0;160;128;;; +0;176;16;;; +0;176;128;;; +0;192;16;;; +0;192;128;;; +0;208;16;;; +0;208;128;;; +0;224;16;;; +0;224;128;;; +0;240;16;;; +0;240;128;;; +0;256;16;;; +0;256;128;;; +0;272;16;;; +0;272;128;;; +0;288;16;;; +0;288;128;;; +0;304;32;;; +0;304;48;;; +0;304;128;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +0;320;112;;; +3;80;128;;; +4;96;128;;; +275;208;32; +275;208;112; +275;224;32; +275;224;64; +275;224;112; +275;240;32; +275;240;48; +275;240;64; +275;256;32; +275;256;96; +275;272;80; +275;272;96; +275;272;112; +275;288;96; +275;288;112; +275;304;112; +272;240;112;;;; +272;256;48;;;; +272;256;80;;;; +272;304;80;;;; +298;88;128;;;;;; +298;288;64;;;;;; +153;88;136;;;cave_13_left;overworld.map;cave_13;1;; +153;288;64;;;cave_13_right;cave14.map;cave_14_left;2;1; +426;80;64 +426;128;48 +426;144;96 +422;96;64 +423;240;32;; +423;256;96;; +252;176;32;c13_et +341;64;80;;;;;; +341;64;96;;;;;; +341;64;112;;;;;; +341;80;64;;;;;; +341;96;48;;;;;; +341;112;48;;;;;; +341;112;96;;;;;; +341;112;112;;;;;; +341;128;48;;;;;; +341;128;96;;;;;; +341;144;48;;;;;; +341;144;96;;;;;; +341;192;48;;;;;; +341;192;96;;;;;; +341;208;48;;;;;; +341;208;96;;;;;; +341;224;48;;;;;; +341;224;80;;;;;; +341;224;96;;;;;; +285;16;152;;;; +167;176;0;c13_et; +302;160;48;;;;; +302;160;96;;;;; +302;176;48;;;;; +302;176;96;;;;; +224;208;64;;;;;;;; +224;240;80;;;;;;;; +224;240;96;;;;;;;; +224;256;64;;;;;;;; +224;256;112;;;;;;;; +224;272;32;;;;;;;; +224;272;48;;;;;;;; +224;272;64;;;;;;;; +224;288;80;;;;;;;; +224;304;96;;;;;;;; +287;40;152;37 +460;176;48;c13_et diff --git a/bin/Data/Maps/cave13.map.data b/bin/Data/Maps/cave13.map.data new file mode 100644 index 0000000..7fbab45 --- /dev/null +++ b/bin/Data/Maps/cave13.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;2;;;2;;;2;;;;;;2;;;; +;;;;;;;;;;;;;;;;;;2;;;; +;;;;2;;;;;;;;;;;;;;;2;;; +;;2;;;;;;;;;;;;;;;;;;;; +;;;2;;;;;;;;;;;;;;;;;;; +;;2;;;;;;2;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave14.map b/bin/Data/Maps/cave14.map new file mode 100644 index 0000000..643bcfd --- /dev/null +++ b/bin/Data/Maps/cave14.map @@ -0,0 +1,600 @@ +3 +1 +0 +cave.png +22 +6 +3 +,,,,,,,,,,,,,,,,,,,,,, +,,39,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,37,, +,39,67,63,14,63,63,63,63,70,27,63,63,63,27,63,70,63,63,63,44,, +,45,63,70,63,70,63,27,63,63,70,70,63,70,63,63,63,14,70,69,38,, +,36,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,38,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,,,,,,,,,,,,,,,,,,4,0, +0,3,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,2,0, +0,1,,,,,,,,,,,,,,,,,,2,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +50 +0;16;48;;; +0;32;32;;; +0;32;64;;; +0;48;16;;; +0;48;64;;; +0;64;16;;; +0;64;64;;; +0;80;16;;; +0;80;64;;; +0;96;16;;; +0;96;64;;; +0;112;16;;; +0;112;64;;; +0;128;16;;; +0;128;64;;; +0;144;16;;; +0;144;64;;; +0;160;16;;; +0;160;64;;; +0;176;16;;; +0;176;64;;; +0;192;16;;; +0;192;64;;; +0;208;16;;; +0;208;64;;; +0;224;16;;; +0;224;64;;; +0;240;16;;; +0;240;64;;; +0;256;16;;; +0;256;64;;; +0;272;16;;; +0;272;64;;; +0;288;16;;; +0;288;64;;; +0;304;16;;; +0;304;48;;; +0;320;32;;; +286;16;128;;;; +298;64;32;;;;;; +298;272;48;;;;;; +153;64;32;;;cave_14_left;cave13.map;cave_13_right;;1; +153;272;48;;;cave_14_right;cave15.map;cave_15_middle;;1; +426;112;16 +426;128;16 +426;208;16 +426;240;16 +423;112;48;; +423;224;32;; +287;48;128;37 diff --git a/bin/Data/Maps/cave14.map.data b/bin/Data/Maps/cave14.map.data new file mode 100644 index 0000000..9d59ada --- /dev/null +++ b/bin/Data/Maps/cave14.map.data @@ -0,0 +1,8 @@ +22 +6 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;2;;;;;;;2;;;;;; +;;;2;;2;;;;;2;2;;2;;;;;2;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave15.map b/bin/Data/Maps/cave15.map new file mode 100644 index 0000000..09e50b0 --- /dev/null +++ b/bin/Data/Maps/cave15.map @@ -0,0 +1,711 @@ +3 +1 +1 +cave.png +32 +10 +3 +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,39,47,47,37,,,39,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,37,,, +,39,67,27,70,68,37,39,67,27,70,63,63,70,89,89,89,89,70,63,63,63,86,86,63,89,89,63,86,44,,, +,45,70,70,70,70,44,45,70,70,70,63,63,70,89,89,89,88,63,70,70,63,63,63,63,89,89,86,86,68,37,, +,67,70,70,70,70,44,45,70,17,70,27,70,70,88,89,89,63,27,63,63,63,63,63,87,89,88,63,86,63,44,, +,63,70,70,70,70,44,45,70,70,70,63,70,70,70,89,89,87,63,63,87,87,87,87,89,89,27,63,63,86,44,, +,71,70,70,27,70,44,36,71,70,70,63,63,63,70,88,88,88,86,86,88,88,88,88,88,88,70,86,63,86,44,, +,45,70,70,70,69,38,,36,46,46,46,46,71,63,70,70,63,63,63,63,63,63,63,63,86,86,63,70,27,44,, +,36,46,46,46,38,,,,,,,,36,46,16,15,46,46,46,46,46,46,16,15,46,46,46,46,46,38,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,, +0,0,3,,,4,0,0,3,,,,,,,,,,,,,,,,,,,,,4,0,, +0,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,2,0,1,,,,,,,,,,,,,,,,,,,,,,,0, +0,1,,,,2,0,0,0,0,0,0,0,1,,,,,,,,,,,,,,,,,2,0, +0,0,0,0,0,0,0,,,,,,0,0,0,,,0,0,0,0,0,0,,,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +149 +0;16;48;;; +0;16;64;;; +0;16;96;;; +0;16;112;;; +0;32;32;;; +0;32;128;;; +0;48;16;;; +0;48;128;;; +0;64;16;;; +0;64;128;;; +0;80;32;;; +0;80;112;;; +0;96;48;;; +0;96;64;;; +0;96;80;;; +0;96;96;;; +0;112;48;;; +0;112;64;;; +0;112;80;;; +0;128;32;;; +0;128;96;;; +0;144;16;;; +0;144;112;;; +0;160;16;;; +0;160;112;;; +0;176;16;;; +0;176;112;;; +0;192;16;;; +0;192;112;;; +0;208;16;;; +0;208;112;;; +0;224;16;;; +0;224;128;;; +0;240;16;;; +0;248;144;;; +0;256;16;;; +0;272;16;;; +0;272;128;;; +0;288;16;;; +0;288;128;;; +0;304;16;;; +0;304;128;;; +0;320;16;;; +0;320;128;;; +0;336;16;;; +0;336;128;;; +0;352;16;;; +0;352;128;;; +0;368;16;;; +0;376;144;;; +0;384;16;;; +0;400;16;;; +0;400;128;;; +0;416;16;;; +0;416;128;;; +0;432;16;;; +0;432;128;;; +0;448;16;;; +0;448;128;;; +0;464;32;;; +0;464;48;;; +0;464;128;;; +0;480;64;;; +0;480;80;;; +0;480;96;;; +0;480;112;;; +3;240;128;;; +3;368;128;;; +4;256;128;;; +4;384;128;;; +275;352;32; +275;368;32; +275;400;112; +275;416;112; +275;432;48; +275;432;96; +275;448;32; +275;448;48; +275;448;64; +275;464;80; +275;464;96; +298;144;64;;;;;; +298;248;128;;;;;; +298;376;128;;;;;; +199;304;48;ruby50;;c15_ruby50;; +153;8;80;;;cave_15_0;cave24.map;cave_15_0;2;; +153;144;64;;;cave_15_middle;cave14.map;cave_14_right;2;1; +153;248;136;;;cave_15_1;overworld.map;cave_15_1;1;; +153;376;136;;;cave_15_2;overworld.map;cave_15_2;1;; +423;208;80;; +423;288;64;; +423;416;80;; +423;448;64;; +423;464;112;; +341;224;32;;;;;; +341;224;48;;;;;; +341;224;64;;;;;; +341;240;32;;;;;; +341;240;48;;;;;; +341;240;64;;;;;; +341;240;80;;;;;; +341;240;96;;;;;; +341;256;32;;;;;; +341;256;48;;;;;; +341;256;64;;;;;; +341;256;80;;;;;; +341;256;96;;;;;; +341;272;32;;;;;; +341;272;48;;;;;; +341;272;80;;;;;; +341;272;96;;;;;; +341;288;96;;;;;; +341;304;96;;;;;; +341;320;80;;;;;; +341;320;96;;;;;; +341;336;80;;;;;; +341;336;96;;;;;; +341;352;80;;;;;; +341;352;96;;;;;; +341;368;80;;;;;; +341;368;96;;;;;; +341;384;64;;;;;; +341;384;80;;;;;; +341;384;96;;;;;; +341;400;32;;;;;; +341;400;48;;;;;; +341;400;64;;;;;; +341;400;80;;;;;; +341;400;96;;;;;; +341;416;32;;;;;; +341;416;48;;;;;; +341;416;64;;;;;; +274;192;96;;;; +274;272;112;;;; +274;288;112;;;; +274;352;112;;;; +285;16;160;;;; +200;64;64;;cave15_heartMeter;heartMeter;; +224;272;64;;;;;;;; +224;288;80;;;;;;;; +224;304;80;;;;;;;; +224;320;64;;;;;;;; +224;336;64;;;;;;;; +224;352;64;;;;;;;; +224;368;64;;;;;;;; +224;384;32;;;;;;;; +224;384;48;;;;;;;; +287;48;160;37 +230;192;48;;;;;; diff --git a/bin/Data/Maps/cave15.map.data b/bin/Data/Maps/cave15.map.data new file mode 100644 index 0000000..917121b --- /dev/null +++ b/bin/Data/Maps/cave15.map.data @@ -0,0 +1,12 @@ +32 +10 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;2;;;;;;2;;;2;;;;;2;;;;;;;;;;;;;; +;;2;2;2;2;;;2;2;2;;;2;;;;;;2;2;;;;;;;;;;;; +;;2;2;2;2;;;2;;2;;2;2;;;;;;;;;;;;;;;;;;; +;;2;2;2;2;;;2;2;2;;2;2;2;;;;;;;;;;;;;;;;;; +;;2;2;;2;;;;2;2;;;;2;;;;;;;;;;;;2;;;;;; +;;2;2;2;;;;;;;;;;;2;2;;;;;;;;;;;;2;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave16.map b/bin/Data/Maps/cave16.map new file mode 100644 index 0000000..96f9874 --- /dev/null +++ b/bin/Data/Maps/cave16.map @@ -0,0 +1,693 @@ +3 +0 +1 +cave.png +10 +18 +3 +,,,,,,,,,, +,,,39,47,47,47,37,,, +,,39,67,,,,68,37,, +,,45,,,70,,,44,, +,,45,,70,14,70,,44,, +,,45,,,70,,,44,, +,,36,71,,,,69,38,, +,,,36,71,,69,38,,, +,,,,45,,44,,,, +,,,39,67,,44,,,, +,,,45,,,44,,,, +,,,45,,69,38,,,, +,39,47,67,,44,,,,, +,45,,,,44,,,,, +,45,,,69,38,,,,, +,45,,,44,,,,,, +,36,16,15,38,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,0,0,0,0,0,0,0,, +,0,0,3,,,,4,0,0, +,0,3,,,,,,4,0, +,0,,,,,,,,0, +,0,,,,,,,,0, +,0,,,,,,,,0, +,0,1,,,,,,2,0, +,0,0,1,,,,2,0,0, +,,0,0,,,,0,0,, +,,0,3,,,,0,,, +,,0,,,,,0,,, +0,0,0,,,,2,0,,, +0,3,,,,,0,0,,, +0,,,,,,0,,,, +0,,,,,2,0,,,, +0,,,,,0,0,,,, +0,1,,,2,0,,,,, +0,0,,,0,0,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +107 +0;16;208;;; +0;16;224;;; +0;16;240;;; +0;32;48;;; +0;32;64;;; +0;32;80;;; +0;32;192;;; +0;40;272;;; +0;48;32;;; +0;48;96;;; +0;48;160;;; +0;48;176;;; +0;48;192;;; +0;64;16;;; +0;64;112;;; +0;64;128;;; +0;64;144;;; +0;64;224;;; +0;64;240;;; +0;80;16;;; +0;80;176;;; +0;80;192;;; +0;80;208;;; +0;96;16;;; +0;96;112;;; +0;96;128;;; +0;96;144;;; +0;96;160;;; +0;112;32;;; +0;112;96;;; +0;128;48;;; +0;128;64;;; +0;128;80;;; +3;32;256;;; +4;48;256;;; +286;-16;288;;;; +298;40;256;;;;;; +298;80;64;;;;;50; +153;40;264;;;cave_16;overworld.map;cave_16;1;; +153;80;64;;;cave_17;cave17.map;cave_17;;1; +426;32;192 +423;64;48;; +423;64;80;; +423;64;192;; +423;96;48;; +423;96;80;; +287;16;288;37 +157;32;208; +157;32;224; +157;32;240; +157;48;48; +157;48;64; +157;48;80; +157;48;208; +157;48;224; +157;48;240; +157;64;32; +157;64;48; +157;64;80; +157;64;96; +157;64;160; +157;64;176; +157;64;192; +157;64;208; +157;80;32; +157;80;96; +157;80;112; +157;80;128; +157;80;144; +157;80;160; +157;96;32; +157;96;48; +157;96;80; +157;96;96; +157;112;48; +157;112;64; +157;112;80; +108;32;208;;;;;; +108;32;224;;;;;; +108;32;240;;;;;; +108;48;48;;;;;; +108;48;64;;;;;; +108;48;80;;;;;; +108;48;208;;;;;; +108;48;224;;;;;; +108;48;240;;;;;; +108;64;32;;;;;; +108;64;48;;;;;; +108;64;80;;;;;; +108;64;96;;;;;; +108;64;160;;;;;; +108;64;176;;;;;; +108;64;192;;;;;; +108;64;208;;;;;; +108;80;32;;;;;; +108;80;96;;;;;; +108;80;112;;;;;; +108;80;128;;;;;; +108;80;144;;;;;; +108;80;160;;;;;; +108;96;32;;;;;; +108;96;48;;;;;; +108;96;80;;;;;; +108;96;96;;;;;; +108;112;48;;;;;; +108;112;64;;;;;; +108;112;80;;;;;; diff --git a/bin/Data/Maps/cave16.map.data b/bin/Data/Maps/cave16.map.data new file mode 100644 index 0000000..9150d83 --- /dev/null +++ b/bin/Data/Maps/cave16.map.data @@ -0,0 +1,20 @@ +10 +18 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;2;;;;; +;;;;2;;2;;;; +;;;;;2;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/cave17.map b/bin/Data/Maps/cave17.map new file mode 100644 index 0000000..9a9bd93 --- /dev/null +++ b/bin/Data/Maps/cave17.map @@ -0,0 +1,620 @@ +3 +0 +0 +cave.png +10 +16 +3 +,,,,,,,,,, +,,,39,47,47,37,,,, +,,39,67,70,70,68,37,,, +,39,67,70,70,70,70,68,37,, +,45,70,70,70,70,17,70,44,, +,36,71,70,70,70,70,69,38,, +,,36,71,70,70,69,38,,, +,,,45,70,70,44,,,, +,,,45,70,70,44,,,, +,,,45,70,70,44,,,, +,,,45,70,70,44,,,, +,,,45,70,70,44,,,, +,,,45,70,70,44,,,, +,,,45,70,70,44,,,, +,,,36,16,15,38,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,0,0,0,0,0,0,,, +,0,0,3,,,4,0,0,, +0,0,3,,,,,4,0,0, +0,3,,,,,,,4,0, +0,,,,,,,,,0, +0,1,,,,,,,2,0, +0,0,1,,,,,2,0,0, +,0,0,,,,,0,0,, +,,0,,,,,0,,, +,,0,,,,,0,,, +,,0,,,,,0,,, +,,0,,,,,0,,, +,,0,,,,,0,,, +,,0,,,,,0,,, +,,0,1,,,2,0,,, +,,0,0,,,0,0,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +40 +0;16;64;;; +0;32;48;;; +0;32;80;;; +0;48;32;;; +0;48;96;;; +0;48;112;;; +0;48;128;;; +0;48;144;;; +0;48;160;;; +0;48;176;;; +0;48;192;;; +0;48;208;;; +0;64;16;;; +0;72;240;;; +0;80;16;;; +0;96;32;;; +0;96;96;;; +0;96;112;;; +0;96;128;;; +0;96;144;;; +0;96;160;;; +0;96;176;;; +0;96;192;;; +0;96;208;;; +0;112;48;;; +0;112;80;;; +0;128;64;;; +3;64;224;;; +4;80;224;;; +286;0;256;;;; +298;72;224;;;;;; +298;96;64;;;;;50; +199;48;64;greenZol;;cave17_chest;; +153;72;232;;;cave_17_ow;overworld.map;cave_17_ow;1;; +153;96;64;;;cave_17;cave16.map;cave_17;;1; +426;48;144 +426;48;176 +426;96;144 +426;96;176 +287;32;256;37 diff --git a/bin/Data/Maps/cave17.map.data b/bin/Data/Maps/cave17.map.data new file mode 100644 index 0000000..05cac3c --- /dev/null +++ b/bin/Data/Maps/cave17.map.data @@ -0,0 +1,18 @@ +10 +16 +;;;;;;;;;; +;;;;;;;;;; +;;;;2;2;;;;; +;;;2;2;2;2;;;; +;;2;2;2;2;;2;;; +;;;2;2;2;2;;;; +;;;;2;2;;;;; +;;;;2;2;;;;; +;;;;2;2;;;;; +;;;;2;2;;;;; +;;;;2;2;;;;; +;;;;2;2;;;;; +;;;;2;2;;;;; +;;;;2;2;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/cave18.map b/bin/Data/Maps/cave18.map new file mode 100644 index 0000000..09b011a --- /dev/null +++ b/bin/Data/Maps/cave18.map @@ -0,0 +1,644 @@ +3 +1 +1 +cave.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,39,47,47,37,,,,,,,,,,,,,,,,,, +,45,63,14,44,,,,,,,,,,,,,,,,,, +,45,,63,44,,,,,,,,,,,,,,,,,, +,45,,,68,47,47,47,47,47,47,47,47,47,47,47,47,47,47,37,,, +,36,71,,,,,,,,,,,,,63,86,63,63,68,37,, +,,36,46,46,46,46,46,46,46,46,46,46,46,46,46,46,71,63,63,44,, +,,,,,,,,,,,,,,,,,45,63,14,44,, +,,,,,,,,,,,,,,,,,36,46,46,38,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,0,0,0,0,,,,,,,,,,,,,,,,, +0,3,,,4,0,,,,,,,,,,,,,,,,, +0,,,,,0,,,,,,,,,,,,,,,,, +0,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,, +0,,,,,,,,,,,,,,,,,,,4,0,0, +0,1,,,,,,,,,,,,,,,,,,,4,0, +0,0,1,,,,,,,,,,,,,,,,,,,0, +,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,0, +,,,,,,,,,,,,,,,,0,1,,,2,0, +,,,,,,,,,,,,,,,,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +82 +0;16;32;;; +0;16;48;;; +0;16;64;;; +0;32;16;;; +0;32;80;;; +0;48;16;;; +0;48;96;;; +0;64;32;;; +0;64;48;;; +0;64;64;;; +0;64;96;;; +0;80;64;;; +0;80;96;;; +0;96;64;;; +0;96;96;;; +0;112;64;;; +0;112;96;;; +0;128;64;;; +0;128;96;;; +0;144;64;;; +0;144;96;;; +0;160;64;;; +0;160;96;;; +0;176;64;;; +0;176;96;;; +0;192;64;;; +0;192;96;;; +0;208;64;;; +0;208;96;;; +0;224;64;;; +0;224;96;;; +0;240;64;;; +0;240;96;;; +0;256;64;;; +0;256;96;;; +0;272;64;;; +0;272;96;;; +0;272;112;;; +0;288;64;;; +0;288;128;;; +0;304;80;;; +0;304;128;;; +0;320;96;;; +0;320;112;;; +286;16;160;;;; +298;48;32;;;;;; +298;304;112;;;;;; +153;48;32;;;cave_18_left;overworld.map;cave_18_left;;1; +153;304;112;;;cave_18_right;overworld.map;cave_18_right;;1; +341;256;80;;;;;; +287;48;160;37 +164;240;80;cave18_stone;;moveStoneCave;15.cave18_stone.....;False +157;32;48; +157;32;64; +157;48;64; +157;48;80; +157;64;80; +157;80;80; +157;96;80; +157;112;80; +157;128;80; +157;144;80; +157;160;80; +157;176;80; +157;192;80; +157;208;80; +157;224;80; +108;32;48;;;;;; +108;32;64;;;;;; +108;48;64;;;;;; +108;48;80;;;;;; +108;64;80;;;;;; +108;80;80;;;;;; +108;96;80;;;;;; +108;112;80;;;;;; +108;128;80;;;;;; +108;144;80;;;;;; +108;160;80;;;;;; +108;176;80;;;;;; +108;192;80;;;;;; +108;208;80;;;;;; +108;224;80;;;;;; diff --git a/bin/Data/Maps/cave18.map.data b/bin/Data/Maps/cave18.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/cave18.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave19.map b/bin/Data/Maps/cave19.map new file mode 100644 index 0000000..d357b9b --- /dev/null +++ b/bin/Data/Maps/cave19.map @@ -0,0 +1,669 @@ +3 +1 +1 +cave.png +28 +12 +3 +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,44,,,,,,,,,,,,,, +,,,,,,,,,36,71,89,89,89,68,37,,,,,,,,39,47,37,,, +,,,,,,,,,,45,89,89,89,87,44,,,39,47,47,47,47,67,70,68,37,, +,,,,,39,47,47,47,47,67,89,89,89,89,68,47,47,67,70,70,70,70,70,14,70,44,, +,,,39,47,74,70,70,70,70,70,89,89,89,89,70,70,70,70,70,69,46,46,71,70,69,38,, +,39,47,67,70,70,70,70,70,70,70,89,89,89,89,70,70,70,70,70,44,,,36,46,38,,, +,45,70,70,70,70,69,46,46,46,71,89,89,89,89,69,46,46,46,46,38,,,,,,,, +,45,70,70,69,46,38,,,,45,88,89,89,89,68,37,,,,,,,,,,,, +,36,16,15,38,,,,,,36,71,89,89,89,87,44,,,,,,,,,,,, +,,,,,,,,,,,45,,,,,44,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,45,45,45,45,0,0,0,,,,,,,,,,,,, +,,,,,,,,0,0,0,0,0,0,0,0,0,,,,,,0,0,0,0,0,, +,,,,,,,,0,0,,,,,,4,0,0,0,0,0,0,0,3,,4,0,0, +,,,,0,0,0,0,0,0,,,,,,,0,0,3,,,,,,,,4,0, +,,0,0,0,3,,,,,,,,,,,,,,,,,,,,,,0, +0,0,0,3,,,,,,,,,,,,,,,,,,,,,,,2,0, +0,3,,,,,,,,,,,,,,,,,,,,0,0,1,,2,0,0, +0,,,,,,,,,,,,,,,,,,,,2,0,0,0,0,0,0,, +0,,,,,,2,0,0,0,,,,,,,,0,0,0,0,0,,,,,,, +0,1,,,2,0,0,0,,0,1,,,,,,2,0,,,,,,,,,,, +0,0,,,0,0,,,,0,0,0,0,0,0,0,0,0,,,,,,,,,,, +,,,,,,,,,,0,0,0,45,45,0,0,0,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +101 +0;16;112;;; +0;16;128;;; +0;32;96;;; +0;40;160;;; +0;48;96;;; +0;64;80;;; +0;64;128;;; +0;80;80;;; +0;80;128;;; +0;96;64;;; +0;96;112;;; +0;112;64;;; +0;112;112;;; +0;128;64;;; +0;128;112;;; +0;144;64;;; +0;144;112;;; +0;160;32;;; +0;160;48;;; +0;160;64;;; +0;160;112;;; +0;160;128;;; +0;176;16;;; +0;176;144;;; +0;192;16;;; +0;192;160;;; +0;208;16;;; +0;208;160;;; +0;224;32;;; +0;224;160;;; +0;240;48;;; +0;240;64;;; +0;240;112;;; +0;240;128;;; +0;240;160;;; +0;256;64;;; +0;256;112;;; +0;256;144;;; +0;272;64;;; +0;272;112;;; +0;288;48;;; +0;288;64;;; +0;288;112;;; +0;304;48;;; +0;304;112;;; +0;320;48;;; +0;320;80;;; +0;320;96;;; +0;336;48;;; +0;336;80;;; +0;352;48;;; +0;352;80;;; +0;368;48;;; +0;368;80;;; +0;384;32;;; +0;384;96;;; +0;400;48;;; +0;400;80;;; +0;416;64;;; +3;32;144;;; +4;48;144;;; +286;-32;176;;;; +298;40;144;;;;;; +153;40;152;;;cave_19_left;overworld.map;cave_19_left;1;; +153;384;64;;;cave_24_left;cave24.map;cave_24_left;;1; +426;32;96 +426;64;80 +341;176;32;;;;;; +341;176;48;;;;;; +341;176;64;;;;;; +341;176;80;;;;;; +341;176;96;;;;;; +341;176;112;;;;;; +341;176;128;;;;;; +341;192;32;;;;;; +341;192;48;;;;;; +341;192;64;;;;;; +341;192;80;;;;;; +341;192;96;;;;;; +341;192;112;;;;;; +341;192;128;;;;;; +341;192;144;;;;;; +341;208;32;;;;;; +341;208;48;;;;;; +341;208;64;;;;;; +341;208;80;;;;;; +341;208;96;;;;;; +341;208;112;;;;;; +341;208;128;;;;;; +341;208;144;;;;;; +341;224;48;;;;;; +341;224;64;;;;;; +341;224;80;;;;;; +341;224;96;;;;;; +341;224;112;;;;;; +341;224;128;;;;;; +341;224;144;;;;;; +341;240;144;;;;;; +224;144;96;;;;;;;; +224;256;80;;;;;;;; +287;-8;176;37 diff --git a/bin/Data/Maps/cave19.map.data b/bin/Data/Maps/cave19.map.data new file mode 100644 index 0000000..6299f0e --- /dev/null +++ b/bin/Data/Maps/cave19.map.data @@ -0,0 +1,14 @@ +28 +12 +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;2;;;; +;;;;;;;;;;;;;;;;;;;2;2;2;2;2;;2;;; +;;;;;;2;2;2;2;2;;;;;2;2;2;2;2;;;;;2;;;; +;;;;2;2;2;2;2;2;2;;;;;2;2;2;2;2;;;;;;;;; +;;2;2;2;2;;;;;;;;;;;;;;;;;;;;;;; +;;2;2;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave2.map b/bin/Data/Maps/cave2.map new file mode 100644 index 0000000..251f480 --- /dev/null +++ b/bin/Data/Maps/cave2.map @@ -0,0 +1,738 @@ +3 +1 +1 +cave.png +32 +18 +3 +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,33,41,41,41,41,41,41,34,,,33,41,41,41,41,41,41,34,,,,,,,33,41,41,34,,, +,33,76,85,66,66,66,66,66,75,34,33,76,66,66,66,66,66,66,75,34,,,,,33,76,66,66,75,34,, +,43,66,66,66,66,66,66,66,66,40,43,66,66,66,66,66,66,66,66,40,33,41,41,41,76,66,66,66,66,40,, +,43,85,66,66,66,66,66,66,66,56,55,66,66,66,66,66,66,66,66,56,55,66,66,66,66,66,66,66,66,40,, +,43,85,66,66,66,66,66,66,66,61,60,66,66,66,66,66,66,66,66,61,60,66,66,66,66,66,66,66,66,40,, +,43,66,66,66,66,66,66,66,66,40,43,66,66,66,66,66,66,66,66,40,32,42,42,42,78,66,66,66,66,40,, +,43,66,66,66,66,66,66,66,66,40,32,78,66,66,66,66,66,66,77,31,,,,,32,78,66,66,77,31,, +,32,54,59,42,42,42,42,42,42,31,,32,42,42,42,42,42,42,31,,,,,,,32,42,42,31,,, +,33,57,58,34,19,19,33,41,41,34,,,,,,,,,,,,,,,,,,,,,, +,43,48,48,75,41,41,76,66,66,40,,,,,,,,,,,,,,,,,,,,,, +,43,48,66,66,48,66,48,66,48,40,,,,,,,,,,,,,,,,,,,,,, +,43,66,66,66,48,48,48,48,85,40,,,,,,,,,,,,,,,,,,,,,, +,43,66,48,48,48,48,66,48,85,40,,,,,,,,,,,,,,,,,,,,,, +,43,66,66,48,48,66,48,48,85,40,,,,,,,,,,,,,,,,,,,,,, +,32,78,66,85,48,48,48,85,77,31,,,,,,,,,,,,,,,,,,,,,, +,,32,42,42,12,11,42,42,31,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,0,0,0,0,0,0,, +0,0,3,,,,,,,4,0,0,3,,,,,,,4,0,0,,,0,0,3,,,4,0,0, +0,3,,,,,,,,,,,,,,,,,,,4,0,0,0,0,3,,,,,4,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,2,0,0,0,0,1,,,,,2,0, +0,,,,,,,,,,,0,1,,,,,,,2,0,0,,,0,0,1,,,2,0,0, +0,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,,,,,0,0,0,0,0,0,, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +0,1,,,,,,,,,2,0,,,,,,,,,,,,,,,,,,,,, +0,0,1,,,,,,,2,0,0,,,,,,,,,,,,,,,,,,,,, +,0,0,0,0,,,0,0,0,0,,,,,,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +152 +382;16;320; +382;464;72;cave +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;16;160;;; +0;16;176;;; +0;16;192;;; +0;16;208;;; +0;16;224;;; +0;32;32;;; +0;32;240;;; +0;48;16;;; +0;48;256;;; +0;64;16;;; +0;64;128;;; +0;64;160;;; +0;64;256;;; +0;80;16;;; +0;80;128;;; +0;80;160;;; +0;88;272;;; +0;96;16;;; +0;96;128;;; +0;96;160;;; +0;112;16;;; +0;112;128;;; +0;112;160;;; +0;112;256;;; +0;128;16;;; +0;128;128;;; +0;128;144;;; +0;128;256;;; +0;144;32;;; +0;144;128;;; +0;144;144;;; +0;144;240;;; +0;160;48;;; +0;160;96;;; +0;160;112;;; +0;160;160;;; +0;160;176;;; +0;160;192;;; +0;160;208;;; +0;160;224;;; +0;176;48;;; +0;176;96;;; +0;192;32;;; +0;192;112;;; +0;208;16;;; +0;208;128;;; +0;224;16;;; +0;224;128;;; +0;240;16;;; +0;240;128;;; +0;256;16;;; +0;256;128;;; +0;272;16;;; +0;272;128;;; +0;288;16;;; +0;288;128;;; +0;304;32;;; +0;304;112;;; +0;320;48;;; +0;320;96;;; +0;352;48;;; +0;352;96;;; +0;368;48;;; +0;368;96;;; +0;384;48;;; +0;384;96;;; +0;400;48;;; +0;400;96;;; +0;416;32;;; +0;416;112;;; +0;432;16;;; +0;432;128;;; +0;448;16;;; +0;448;128;;; +0;464;32;;; +0;464;112;;; +0;480;48;;; +0;480;64;;; +0;480;80;;; +0;480;96;;; +1;160;80;;; +1;176;80;;; +1;320;80;;; +1;336;80;;; +3;32;128;;; +3;32;144;;; +3;80;256;;; +4;48;128;;; +4;48;144;;; +4;96;256;;; +2;160;64;;; +2;176;64;;; +2;320;64;;; +2;336;64;;; +286;16;288;;;; +276;32;64; +276;32;80; +276;48;32; +276;64;240; +276;128;240; +276;144;192; +276;144;208; +276;144;224; +298;88;256;;;;;; +261;40;128;;mc_door_1;1; +261;40;144;;mc_door_1;3; +261;160;72;;mc_door_2;; +261;176;72;;mc_door_2;2; +261;320;72;;mc_door_3;; +261;336;72;;mc_door_3;2; +174;48;288;mc_entry +153;88;264;;;cave2;overworld.map;cave2;1;; +252;64;80;mc_room_2_et +252;88;192;mc_room_1 +342;40;112; +168;-8;136;mc_door_1;(mc_room_1&!mc_room_2_enter|mc_room_2_et|mc_boss)|mc_enemies!=1; +168;168;-8;mc_door_2;(mc_room_2_et&!mc_room_3_enter|mc_boss)|mc_enemies!=1; +168;328;-8;mc_door_3;(!mc_room_3_enter|mc_boss)|mc_enemies!=1; +167;-32;136;mc_room_2_enter;0 +167;-8;80;mc_room_2_et;0 +167;-8;192;mc_room_1;0 +167;168;-32;mc_room_3_enter;0 +302;80;144;;;;; +302;96;144;;;;; +307;64;16;;;;; +307;112;16;;;;; +307;224;16;;;;; +307;272;16;;;;; +307;368;48;;;;; +309;224;128;;;;; +309;272;128;;;;; +309;368;96;;;;; +170;40;128;mc_room_2_enter;1;;; +170;176;72;mc_room_3_enter;2;;; +224;464;72;1;;;;;;; +287;-16;48;37 +164;-32;80;mc_room_2_et;1;dialogBox;sound_secrete; +164;-32;192;mc_room_1;1;dialogBox;sound_secrete; +164;48;48;mc_enemies;1;e5;;False +164;80;32;mc_enemies;1;e5;;False +164;112;48;mc_enemies;1;e5;;False +164;112;192;mc_enemies;1;moblinSword;;False +164;144;80;mc_enemies;1;e5;;False +164;272;72;mc_enemies;1;mb_king_moblin;mc_room_3_enter.mc_boss;False +206;464;72;mc_bow_wow;; diff --git a/bin/Data/Maps/cave2.map.data b/bin/Data/Maps/cave2.map.data new file mode 100644 index 0000000..13a9639 --- /dev/null +++ b/bin/Data/Maps/cave2.map.data @@ -0,0 +1,20 @@ +32 +18 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;4;4;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;4;;;4;;4;;4;;;;;;;;;;;;;;;;;;;;;;; +;;;;;4;4;4;4;;;;;;;;;;;;;;;;;;;;;;;; +;;;4;4;4;4;;4;;;;;;;;;;;;;;;;;;;;;;;; +;;;;4;4;;4;4;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;4;4;4;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave20.map b/bin/Data/Maps/cave20.map new file mode 100644 index 0000000..8ae54c5 --- /dev/null +++ b/bin/Data/Maps/cave20.map @@ -0,0 +1,646 @@ +3 +1 +1 +cave.png +12 +18 +3 +,,,,,,,,,,,, +,,,,,39,47,47,47,47,37,, +,,,,39,67,63,63,63,63,44,, +,39,47,47,67,63,63,63,63,63,44,, +,45,14,63,63,63,69,46,71,63,44,, +,45,63,63,63,63,44,,45,63,44,, +,45,63,63,63,69,38,,45,63,44,, +,36,46,46,46,38,,,45,63,44,, +,,,,,,,,45,63,44,, +,,,,,,,,45,63,44,, +,,,,,,,,45,63,44,, +,,,,,,,,45,86,44,, +,,,,,,,,45,86,44,, +,,,,,,39,47,67,86,44,, +,,,,,,45,63,86,86,44,, +,,,,,,45,63,63,69,38,, +,,,,,,36,16,15,38,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,0,0,0,0,0,0,0,0, +,,,0,0,3,,,,,4,0, +0,0,0,0,3,,,,,,,0, +0,3,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,0,,,,0, +0,,,,,,2,0,,,,0, +0,1,,,,2,0,0,,,,0, +0,0,0,0,0,0,0,0,,,,0, +,,,,,,,0,,,,0, +,,,,,,,0,,,,0, +,,,,,,,0,,,,0, +,,,,,0,0,0,,,,0, +,,,,,0,3,,,,,0, +,,,,,0,,,,,,0, +,,,,,0,,,,,2,0, +,,,,,0,1,,,2,0,0, +,,,,,0,0,,,0,0,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +60 +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;32;48;;; +0;32;112;;; +0;48;48;;; +0;48;112;;; +0;64;48;;; +0;64;112;;; +0;80;32;;; +0;80;96;;; +0;96;16;;; +0;96;64;;; +0;96;80;;; +0;96;224;;; +0;96;240;;; +0;112;16;;; +0;112;64;;; +0;112;208;;; +0;120;272;;; +0;128;16;;; +0;128;64;;; +0;128;80;;; +0;128;96;;; +0;128;112;;; +0;128;128;;; +0;128;144;;; +0;128;160;;; +0;128;176;;; +0;128;192;;; +0;128;208;;; +0;144;16;;; +0;144;240;;; +0;160;32;;; +0;160;48;;; +0;160;64;;; +0;160;80;;; +0;160;96;;; +0;160;112;;; +0;160;128;;; +0;160;144;;; +0;160;160;;; +0;160;176;;; +0;160;192;;; +0;160;208;;; +0;160;224;;; +3;112;256;;; +4;128;256;;; +286;16;280;;;; +275;128;224; +275;144;176; +275;144;192; +275;144;208; +275;144;224; +298;32;64;;;;;; +298;120;256;;;;;; +153;32;64;;;cave_20_top;overworld.map;cave_20_top;2;1; +153;120;264;;;cave_20;overworld.map;cave_20;1;; +478;144;16 +287;40;280;37 diff --git a/bin/Data/Maps/cave20.map.data b/bin/Data/Maps/cave20.map.data new file mode 100644 index 0000000..8f7cae4 --- /dev/null +++ b/bin/Data/Maps/cave20.map.data @@ -0,0 +1,20 @@ +12 +18 +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave21.map b/bin/Data/Maps/cave21.map new file mode 100644 index 0000000..b3d617d --- /dev/null +++ b/bin/Data/Maps/cave21.map @@ -0,0 +1,678 @@ +3 +1 +1 +cave.png +31 +10 +3 +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,39,47,47,47,47,47,47,47,47,47,51,47,47,47,47,47,47,47,47,47,47,37,,,,, +,,,39,47,67,70,70,70,70,70,70,70,70,70,70,70,70,86,86,70,70,86,86,86,70,68,47,37,,, +,,39,67,70,70,70,69,53,46,46,46,46,46,46,46,46,46,46,46,49,46,46,46,79,86,70,70,44,,, +,,45,70,70,69,46,38,,,,,,,,,,,,,,,,,36,71,86,70,68,37,, +,39,67,70,69,38,,,39,47,47,47,47,47,47,47,37,,,,,,,,,52,86,70,70,44,, +,45,70,70,44,,,39,67,70,70,70,70,70,70,70,68,37,,,,,,,,36,71,70,70,44,, +,45,70,70,44,,,45,70,70,70,70,70,70,70,17,70,44,,,,,,,,,45,70,70,44,, +,36,16,15,38,,,36,16,15,46,46,46,46,46,46,46,38,,,,,,,,,36,16,15,38,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,, +,,0,0,0,3,,,,,,,,,,,,,,,,,,,,,4,0,0,0,, +,0,0,3,,,,,,,,,,,,,,,,,,,,,,,,,4,0,, +,0,3,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0, +0,0,,,,,,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,,,,,4,0, +0,3,,,,2,0,0,3,,,,,,,,4,0,0,,,,,0,0,,,,,,0, +0,,,,,0,0,3,,,,,,,,,,4,0,,,,,,0,1,,,,,0, +0,,,,,0,0,,,,,,,,,,,,0,,,,,,0,0,,,,,0, +0,1,,,2,0,0,1,,,,,,,,,,2,0,,,,,,,0,1,,,2,0, +0,0,,,0,0,0,0,,,0,0,0,0,0,0,0,0,0,,,,,,,0,0,,,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +116 +0;16;96;;; +0;16;112;;; +0;32;64;;; +0;32;80;;; +0;40;144;;; +0;48;48;;; +0;64;32;;; +0;64;80;;; +0;64;96;;; +0;64;112;;; +0;80;32;;; +0;80;64;;; +0;96;16;;; +0;96;64;;; +0;112;16;;; +0;112;48;;; +0;112;112;;; +0;128;16;;; +0;128;48;;; +0;128;96;;; +0;136;144;;; +0;144;16;;; +0;144;48;;; +0;144;80;;; +0;160;16;;; +0;160;48;;; +0;160;80;;; +0;160;128;;; +0;176;16;;; +0;176;48;;; +0;176;80;;; +0;176;128;;; +0;192;16;;; +0;192;48;;; +0;192;80;;; +0;192;128;;; +0;208;16;;; +0;208;48;;; +0;208;80;;; +0;208;128;;; +0;224;16;;; +0;224;48;;; +0;224;80;;; +0;224;128;;; +0;240;16;;; +0;240;48;;; +0;240;80;;; +0;240;128;;; +0;256;16;;; +0;256;48;;; +0;256;96;;; +0;256;128;;; +0;272;16;;; +0;272;48;;; +0;272;112;;; +0;288;16;;; +0;288;48;;; +0;304;16;;; +0;304;48;;; +0;320;16;;; +0;320;48;;; +0;336;16;;; +0;336;48;;; +0;352;16;;; +0;352;48;;; +0;368;16;;; +0;368;48;;; +0;384;16;;; +0;384;48;;; +0;400;16;;; +0;400;64;;; +0;400;80;;; +0;416;32;;; +0;416;96;;; +0;416;112;;; +0;432;32;;; +0;440;144;;; +0;448;48;;; +0;448;64;;; +0;464;80;;; +0;464;96;;; +0;464;112;;; +3;32;128;;; +3;128;128;;; +3;432;128;;; +4;48;128;;; +4;144;128;;; +4;448;128;;; +286;16;160;;;; +275;288;32; +275;304;32; +275;352;32; +275;368;32; +275;384;32; +275;400;48; +275;416;64; +275;416;80; +298;40;128;;;;;; +298;136;128;;;;;; +298;440;128;;;;;; +153;40;136;;;cave_21_0;overworld.map;cave_21_0;1;; +153;136;136;;;cave_21_1;overworld.map;cave_21_1;1;; +153;240;112;;;cave_22;cave22.map;cave_22;2;1; +153;440;136;;;cave_21_2;overworld.map;cave_21_2;1;; +426;48;48 +426;64;32 +426;80;64 +426;96;16 +426;400;16 +426;400;64 +426;432;32 +426;448;64 +423;224;32;; +423;240;32;; +423;256;32;; +287;48;160;37 diff --git a/bin/Data/Maps/cave21.map.data b/bin/Data/Maps/cave21.map.data new file mode 100644 index 0000000..beecae1 --- /dev/null +++ b/bin/Data/Maps/cave21.map.data @@ -0,0 +1,12 @@ +31 +10 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;2;2;2;2;2;2;2;2;2;2;2;2;;;2;2;;;;2;;;;;; +;;;;2;2;2;;;;;;;;;;;;;;;;;;;;2;2;;;; +;;;2;2;;;;;;;;;;;;;;;;;;;;;;;2;;;; +;;;2;;;;;;;;;;;;;;;;;;;;;;;;2;2;;; +;;2;2;;;;;;2;2;2;2;2;2;2;;;;;;;;;;;;2;2;;; +;;2;2;;;;;2;2;2;2;2;2;2;;2;;;;;;;;;;;2;2;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave22.map b/bin/Data/Maps/cave22.map new file mode 100644 index 0000000..f35935e --- /dev/null +++ b/bin/Data/Maps/cave22.map @@ -0,0 +1,777 @@ +3 +1 +2 +cave.png +23 +19 +3 +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,44,,,,,,,,,,,,,,, +,,,,,39,47,37,68,47,47,47,47,47,37,,39,47,37,,,,, +,,,39,47,67,87,68,37,70,70,70,70,70,68,47,67,70,68,37,,,, +,,39,67,86,70,88,87,68,20,47,47,37,70,70,70,70,70,70,68,37,,, +,39,67,87,70,14,70,89,70,70,70,70,68,47,37,70,70,70,70,70,44,,, +,45,70,88,87,70,87,88,70,70,70,70,70,70,68,47,47,37,70,70,44,,, +,45,70,70,88,86,88,70,70,70,70,70,70,70,70,87,87,68,37,70,44,,, +,36,71,70,70,70,70,69,46,46,46,71,70,70,87,89,89,87,44,70,44,,, +,,36,46,46,46,46,38,,,,36,46,71,89,89,89,89,44,70,44,,, +,,,,,,,,,,46,71,70,36,71,89,89,69,38,70,44,,, +,,,,,,,,,,,45,70,70,45,89,89,44,70,70,44,,, +,,,,,,,,,,,45,70,70,45,89,89,44,70,70,68,47,, +,,,,,,,,,,,45,70,39,67,89,89,68,47,47,37,,, +,,,,,,,,,,,45,70,45,86,88,89,87,87,87,44,,, +,,,,,,,,,,,45,70,45,70,70,88,88,88,88,44,,, +,,,,,,,,,,,45,70,36,71,70,70,70,70,69,38,,, +,,,,,,,,,,,36,71,84,36,46,16,15,46,38,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,0,0,0,,,,,,,,,,,,,, +,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,, +,,0,0,0,3,,,,,,,,,4,0,3,,4,0,0,,, +,0,0,3,,,,,,,,,,,,,,,,4,0,0,, +0,0,3,,,,,,,,,,,,,,,,,,4,0,, +0,3,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,0,, +0,1,,,,,,,,,,,,,,,,,,,,0,, +0,0,1,,,,,2,0,0,0,,,,,,,,,,,0,, +,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,0,, +,,,,,,,,,0,0,,,,,,,,,,,0,0, +,,,,,,,,,,0,,,,,,,,,,,0,0, +,,,,,,,,,,0,,,,,,,,,,,0,0, +,,,,,,,,,,0,,,,,,,,,,,0,, +,,,,,,,,,,0,,,,,,,,,,,0,, +,,,,,,,,,,0,,,,,,,,,,2,0,, +,,,,,,,,,,0,1,,,,,,,,2,0,0,, +,,,,,,,,,,0,0,0,0,0,0,,,0,0,0,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +188 +0;16;96;;; +0;16;112;;; +0;32;80;;; +0;32;128;;; +0;48;64;;; +0;48;144;;; +0;64;48;;; +0;64;144;;; +0;80;48;;; +0;80;144;;; +0;96;32;;; +0;96;144;;; +0;112;128;;; +0;128;128;;; +0;144;32;;; +0;144;128;;; +0;160;32;;; +0;160;128;;; +0;176;32;;; +0;176;128;;; +0;176;160;;; +0;176;176;;; +0;176;192;;; +0;176;208;;; +0;176;224;;; +0;176;240;;; +0;176;256;;; +0;192;32;;; +0;192;272;;; +0;208;32;;; +0;224;48;;; +0;240;48;;; +0;240;272;;; +0;256;48;;; +0;264;288;;; +0;272;32;;; +0;288;48;;; +0;288;272;;; +0;304;64;;; +0;304;256;;; +0;320;80;;; +0;320;96;;; +0;320;112;;; +0;320;128;;; +0;320;144;;; +0;320;160;;; +0;320;176;;; +0;320;192;;; +0;320;224;;; +0;320;240;;; +3;256;272;;; +4;272;272;;; +286;16;304;;;; +298;264;272;;;;;; +153;80;80;;;cave_22;cave21.map;cave_22;;1; +153;264;280;;;cave_22_exit;overworld.map;cave_22_exit;1;; +422;208;96 +422;272;80 +423;144;96;; +423;192;224;; +423;192;240;; +423;240;80;; +423;288;96;; +341;48;80;;;;;; +341;48;96;;;;;; +341;64;64;;;;;; +341;64;96;;;;;; +341;64;112;;;;;; +341;80;112;;;;;; +341;96;48;;;;;; +341;96;64;;;;;; +341;96;96;;;;;; +341;96;112;;;;;; +341;112;64;;;;;; +341;112;80;;;;;; +341;112;96;;;;;; +341;224;128;;;;;; +341;224;144;;;;;; +341;224;224;;;;;; +341;240;112;;;;;; +341;240;128;;;;;; +341;240;144;;;;;; +341;240;160;;;;;; +341;240;176;;;;;; +341;240;192;;;;;; +341;240;208;;;;;; +341;240;224;;;;;; +341;256;112;;;;;; +341;256;128;;;;;; +341;256;144;;;;;; +341;256;160;;;;;; +341;256;176;;;;;; +341;256;192;;;;;; +341;256;208;;;;;; +341;256;224;;;;;; +341;256;240;;;;;; +341;272;128;;;;;; +341;272;144;;;;;; +341;272;224;;;;;; +341;272;240;;;;;; +341;288;224;;;;;; +341;288;240;;;;;; +341;304;224;;;;;; +341;304;240;;;;;; +162;160;64;;18;32;8;;;;; +162;192;152;;-18;;8;;;;; +162;208;80;;18;;8;;;;; +162;208;224;18;;8;32;;;;; +162;224;176;18;;8;32;;;;; +162;240;96;;18;32;8;;;;; +162;280;176;-18;;8;32;;;;; +162;288;208;;18;;8;;;;; +162;296;128;-18;;8;32;;;;; +25;112;48;;;; +25;128;48;;;; +25;128;64;;;; +25;160;64;;;; +25;176;64;;;; +25;192;64;;;; +25;192;80;;;; +25;192;144;;;; +25;208;80;;;; +25;208;144;;;; +25;208;160;;;; +25;208;208;;;; +25;208;224;;;; +25;208;240;;;; +25;208;256;;;; +25;224;80;;;; +25;224;96;;;; +25;224;160;;;; +25;224;176;;;; +25;224;192;;;; +25;224;208;;;; +25;224;256;;;; +25;240;96;;;; +25;256;96;;;; +25;272;96;;;; +25;272;112;;;; +25;272;160;;;; +25;272;176;;;; +25;272;192;;;; +25;272;208;;;; +25;288;112;;;; +25;288;128;;;; +25;288;144;;;; +25;288;160;;;; +25;288;208;;;; +25;304;208;;;; +224;192;176;;;;;;;; +224;304;192;;;;;;;; +287;48;304;37 +160;144;64; +246;144;48; +246;144;64; +246;160;48; +246;176;48; +246;192;48; +246;192;160; +246;192;192; +246;192;208; +246;192;224; +246;192;240; +246;192;256; +246;208;48; +246;208;64; +246;208;176; +246;208;192; +246;224;64; +246;240;64; +246;240;80; +246;256;64; +246;256;80; +246;272;48; +246;272;64; +246;272;80; +246;288;64; +246;288;80; +246;288;96; +246;288;176; +246;288;192; +246;304;80; +246;304;96; +246;304;112; +246;304;128; +246;304;144; +246;304;160; +246;304;176; diff --git a/bin/Data/Maps/cave22.map.data b/bin/Data/Maps/cave22.map.data new file mode 100644 index 0000000..a0f06f0 --- /dev/null +++ b/bin/Data/Maps/cave22.map.data @@ -0,0 +1,21 @@ +23 +19 +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;2;2;2;2;2;;;;2;;;;;; +;;;;;2;;;;;;;;2;2;2;2;2;2;;;;; +;;;;2;;2;;2;2;2;2;;;;2;2;2;2;2;;;; +;;2;;;2;;;2;2;2;2;2;2;;;;;2;2;;;; +;;2;2;;;;2;2;2;2;2;2;2;2;;;;;2;;;; +;;;2;2;2;2;;;;;;2;2;;;;;;2;;;; +;;;;;;;;;;;;;;;;;;;2;;;; +;;;;;;;;;;;;2;;;;;;;2;;;; +;;;;;;;;;;;;2;2;;;;;2;2;;;; +;;;;;;;;;;;;2;2;;;;;2;2;;;; +;;;;;;;;;;;;2;;;;;;;;;;; +;;;;;;;;;;;;2;;;;;;;;;;; +;;;;;;;;;;;;2;;2;2;;;;;;;; +;;;;;;;;;;;;2;;;2;2;2;2;;;;; +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave23.map b/bin/Data/Maps/cave23.map new file mode 100644 index 0000000..b463094 --- /dev/null +++ b/bin/Data/Maps/cave23.map @@ -0,0 +1,792 @@ +3 +2 +2 +cave.png +22 +19 +3 +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,45,,,,,,,,,,,,,,, +,,,,39,47,47,67,39,47,47,37,,,,,,,,,,, +,,,39,67,70,70,70,45,,,44,,,,,,,,,,, +,,39,67,70,14,39,20,67,,,44,,,,,,,,,,, +,,45,70,70,39,67,,,,,44,,,,,,,,,,, +,,45,70,70,45,,,,,,44,,,,,,,,,,, +,,45,39,47,67,,,,,,44,,,,,,,,,,, +,47,67,45,,,,,,,,44,,,,,,,,,,, +,,,36,46,46,46,46,46,46,83,38,,,,,,,,,,, +,,,,,,39,47,47,47,83,47,47,47,47,47,47,37,,,,, +,,,,39,47,67,,,,70,,70,70,70,70,70,68,47,37,,, +,,,39,67,,,,,,,,,,,70,70,70,70,44,,, +,,,45,,,,69,46,46,46,46,46,46,46,71,70,70,70,68,37,, +,,39,67,,,69,38,,,,,,,,36,71,70,70,70,44,, +,,45,,,69,38,,,,,,,,,,36,71,70,70,44,, +,,45,,,44,,,,,,,,,,,,45,70,70,44,, +,,36,16,15,38,,,,,,,,,,,,45,16,15,44,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,0,0,0,,,,,,,,,,,,,, +,,,0,0,0,0,0,0,0,0,0,0,,,,,,,,,, +,,0,0,3,,,,,,,4,0,,,,,,,,,, +,0,0,3,,,,,,,,,0,,,,,,,,,, +,0,3,,,,,,,,,,0,,,,,,,,,, +,0,,,,,,,,,,,0,,,,,,,,,, +,0,,,,,,,,,,,0,,,,,,,,,, +0,0,,,,,,,,,,,0,,,,,,,,,, +0,0,,,,,,,,,,,0,,,,,,,,,, +0,0,0,1,,,,,,,,,0,0,0,0,0,0,0,,,, +,,0,0,0,0,,,,,,,,,,,,4,0,0,0,, +,,0,0,3,,,,,,,,,,,,,,,4,0,, +,,0,3,,,,,,,,,,,,,,,,,0,0, +,0,0,,,,,,,,,,,,,,,,,,4,0, +,0,3,,,,,2,0,0,0,0,0,0,0,1,,,,,,0, +,0,,,,,2,0,0,,,,,,0,0,1,,,,,0, +,0,,,,,0,0,,,,,,,,0,0,,,,,0, +,0,1,,,2,0,,,,,,,,,,0,1,,,2,0, +,0,0,,,0,0,,,,,,,,,,0,0,,,0,0, +524 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +waterfallSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +202 +0;32;80;;; +0;32;96;;; +0;32;240;;; +0;32;256;;; +0;48;64;;; +0;48;144;;; +0;48;208;;; +0;48;224;;; +0;56;288;;; +0;64;48;;; +0;64;144;;; +0;64;192;;; +0;80;32;;; +0;80;144;;; +0;80;176;;; +0;80;240;;; +0;80;256;;; +0;96;32;;; +0;96;144;;; +0;96;176;;; +0;96;224;;; +0;112;32;;; +0;112;144;;; +0;112;160;;; +0;112;208;;; +0;128;144;;; +0;128;160;;; +0;128;208;;; +0;144;32;;; +0;144;144;;; +0;144;160;;; +0;144;208;;; +0;160;32;;; +0;160;208;;; +0;176;48;;; +0;176;64;;; +0;176;80;;; +0;176;96;;; +0;176;112;;; +0;176;128;;; +0;176;144;;; +0;176;160;;; +0;176;208;;; +0;192;160;;; +0;192;208;;; +0;208;160;;; +0;208;208;;; +0;224;160;;; +0;224;208;;; +0;240;160;;; +0;240;208;;; +0;256;160;;; +0;256;224;;; +0;272;176;;; +0;272;240;;; +0;272;256;;; +0;288;176;;; +0;296;288;;; +0;304;192;;; +0;304;208;;; +0;320;224;;; +0;320;240;;; +0;320;256;;; +3;48;272;;; +3;288;272;;; +4;64;272;;; +4;304;272;;; +286;8;184;;;; +299;56;272;;;;;; +299;296;272;;;;;; +268;160;144;;cave23_wall;1;; +268;160;160;;cave23_wall;3;; +153;56;280;;;cave_23_left;overworld.map;cave_23_left;1;; +153;80;64;;;cave_27;cave27.map;cave_27;;1; +153;296;280;;;cave_23_right;overworld.map;cave_23_right;1;; +248;32;32;cave23_wall;; +458;112;192 +435;272;192;3 +427;64;192 +427;256;224 +427;288;176 +22;240;192;;;; +162;64;112;;18;;8;;;;; +162;80;96;18;;8;;;;;; +162;128;48;18;;8;;;;;; +25;48;112;;;; +25;48;128;;;; +25;64;112;;;; +25;80;80;;;; +25;80;96;;;; +25;80;112;;;; +25;96;64;;;; +25;96;80;;;; +25;128;48;;;; +25;128;64;;;; +287;8;160;37 +246;48;80; +246;48;96; +246;64;64; +246;64;80; +246;64;96; +246;80;48; +246;80;64; +246;96;48; +246;112;48; +246;112;64; +157;48;240; +157;48;256; +157;64;128; +157;64;208; +157;64;224; +157;64;240; +157;64;256; +157;80;128; +157;80;192; +157;80;208; +157;80;224; +157;96;96; +157;96;112; +157;96;128; +157;96;192; +157;96;208; +157;112;80; +157;112;96; +157;112;112; +157;112;128; +157;112;176; +157;112;192; +157;128;80; +157;128;96; +157;128;112; +157;128;128; +157;128;176; +157;128;192; +157;144;48; +157;144;64; +157;144;80; +157;144;96; +157;144;112; +157;144;128; +157;144;176; +157;144;192; +157;160;48; +157;160;64; +157;160;80; +157;160;96; +157;160;112; +157;160;128; +157;160;192; +157;176;176; +157;176;192; +157;192;192; +157;208;192; +157;224;192; +108;48;240;;;;;; +108;48;256;;;;;; +108;64;128;;;;;; +108;64;208;;;;;; +108;64;224;;;;;; +108;64;240;;;;;; +108;64;256;;;;;; +108;80;128;;;;;; +108;80;192;;;;;; +108;80;208;;;;;; +108;80;224;;;;;; +108;96;96;;;;;; +108;96;112;;;;;; +108;96;128;;;;;; +108;96;192;;;;;; +108;96;208;;;;;; +108;112;80;;;;;; +108;112;96;;;;;; +108;112;112;;;;;; +108;112;128;;;;;; +108;112;176;;;;;; +108;112;192;;;;;; +108;128;80;;;;;; +108;128;96;;;;;; +108;128;112;;;;;; +108;128;128;;;;;; +108;128;176;;;;;; +108;128;192;;;;;; +108;144;48;;;;;; +108;144;64;;;;;; +108;144;80;;;;;; +108;144;96;;;;;; +108;144;112;;;;;; +108;144;128;;;;;; +108;144;176;;;;;; +108;144;192;;;;;; +108;160;48;;;;;; +108;160;64;;;;;; +108;160;80;;;;;; +108;160;96;;;;;; +108;160;112;;;;;; +108;160;128;;;;;; +108;160;192;;;;;; +108;176;176;;;;;; +108;176;192;;;;;; +108;192;192;;;;;; +108;208;192;;;;;; +108;224;192;;;;;; diff --git a/bin/Data/Maps/cave23.map.data b/bin/Data/Maps/cave23.map.data new file mode 100644 index 0000000..a0788cf --- /dev/null +++ b/bin/Data/Maps/cave23.map.data @@ -0,0 +1,21 @@ +22 +19 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;2;2;2;;;;;;;;;;;;;;; +;;;;2;;;;;;;;;;;;;;;;;; +;;;2;2;;;;;;;;;;;;;;;;;; +;;;2;2;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;2;;2;2;2;2;2;;;;;; +;;;;;;;;;;;;;;;2;2;2;2;;;; +;;;;;;;;;;;;;;;;2;2;2;;;; +;;;;;;;;;;;;;;;;;2;2;2;;; +;;;;;;;;;;;;;;;;;;2;2;;; +;;;;;;;;;;;;;;;;;;2;2;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave24.map b/bin/Data/Maps/cave24.map new file mode 100644 index 0000000..1f8db2f --- /dev/null +++ b/bin/Data/Maps/cave24.map @@ -0,0 +1,703 @@ +3 +0 +2 +cave.png +22 +19 +3 +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,44,,,,,,, +,,39,47,47,47,47,47,47,37,,39,47,47,37,68,47,37,,,,, +,39,67,39,47,37,70,70,70,68,47,80,70,70,68,37,70,68,37,,,, +,45,39,67,70,68,47,37,70,70,70,70,70,70,70,44,70,14,68,37,,, +,45,45,70,17,70,70,44,70,70,70,70,70,70,70,44,70,70,70,44,,, +,45,36,71,70,69,46,38,69,46,46,73,70,70,70,68,47,20,37,68,47,, +,36,71,36,46,38,69,46,38,,,45,70,70,70,70,70,70,44,,,, +,,36,46,46,46,38,,,,,36,71,70,69,46,46,46,38,,,, +,,,,,,,,,,,,45,70,44,,,,,,,, +,,,,,,,,,,,,45,70,44,,,,,,,, +,,,,,,,,,,,39,67,70,68,47,47,37,,,,, +,,,,,,,,,,39,67,70,70,70,70,70,68,47,37,,, +,,,,,,,,,,45,70,70,70,70,70,70,70,70,68,,, +,,,,,,,,,,45,70,70,70,70,70,70,70,70,70,,, +,,,,,,,,,,36,71,70,70,70,70,70,70,69,46,,, +,,,,,,,,,,,36,46,71,70,70,70,69,38,,,, +,,,,,,,,,,,,,36,46,46,46,38,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,0,0,0,,,,,, +,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,, +0,0,3,,,,,,,4,0,3,,,,,,4,0,0,,, +0,3,,,,,,,,,,,,,,,,,4,0,0,, +0,,,,,,,,,,,,,,,,,,,4,0,, +0,,,,,,,,,,,,,,,,,,,,0,0, +0,,,,,,,,,,,,,,,,,,,2,0,0, +0,1,,,,,,,2,0,0,,,,,,,,,0,0,0, +0,0,1,,,,2,0,0,0,0,1,,,,,,,2,0,,, +,0,0,0,0,0,0,0,,,0,0,,,,0,0,0,0,0,,, +,,,,,,,,,,0,0,,,,0,0,0,0,,,, +,,,,,,,,,0,0,3,,,,,,4,0,0,0,, +,,,,,,,,,0,3,,,,,,,,,4,0,, +,,,,,,,,,0,,,,,,,,,,,0,, +,,,,,,,,,0,,,,,,,,,,,,, +,,,,,,,,,0,1,,,,,,,,,2,0,, +,,,,,,,,,0,0,1,,,,,,,2,0,0,, +,,,,,,,,,,0,0,0,1,,,,2,0,0,,, +,,,,,,,,,,,,0,0,0,0,0,0,0,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +114 +0;32;80;;; +0;48;48;;; +0;48;64;;; +0;48;96;;; +0;64;112;;; +0;80;96;;; +0;96;32;;; +0;96;96;;; +0;112;32;;; +0;112;96;;; +0;128;32;;; +0;128;96;;; +0;144;48;;; +0;144;96;;; +0;160;48;;; +0;160;96;;; +0;160;208;;; +0;160;224;;; +0;176;48;;; +0;176;96;;; +0;176;112;;; +0;176;192;;; +0;176;240;;; +0;192;32;;; +0;192;128;;; +0;192;144;;; +0;192;160;;; +0;192;176;;; +0;192;256;;; +0;208;32;;; +0;208;256;;; +0;224;128;;; +0;224;144;;; +0;224;160;;; +0;224;176;;; +0;224;272;;; +0;240;128;;; +0;240;176;;; +0;240;272;;; +0;256;32;;; +0;256;128;;; +0;256;176;;; +0;256;272;;; +0;272;48;;; +0;272;128;;; +0;272;192;;; +0;272;256;;; +0;288;64;;; +0;288;128;;; +0;288;192;;; +0;288;240;;; +0;304;80;;; +0;304;208;;; +0;304;240;;; +0;320;208;;; +0;320;224;;; +0;320;240;;; +286;328;32;;;; +298;272;64;;;;;; +329;192;144;;cave24_wall;;; +28;224;48;;;; +28;240;48;;;; +28;240;64;;;; +28;240;80;;;; +28;240;96;;;; +28;256;96;;;; +28;288;96;;;; +28;288;112;;;; +153;64;80;;;cave_24_left;cave19.map;cave_24_left;2;1; +153;272;64;;;cave_24_right;overworld.map;cave_24_right;;1; +153;312;224;;;cave_15_0;cave15.map;cave_15_0;;; +248;160;160;cave24_wall;168; +434;176;208;2 +434;208;48;2 +434;240;240;2 +426;192;96 +426;240;112 +423;208;240;; +423;240;208;; +162;96;64;;18;;8;;;;; +162;120;80;-18;;8;;;;;; +162;248;64;-18;;8;32;;;;; +162;256;96;;18;;8;;;;; +25;64;48;;;; +25;80;48;;;; +25;80;64;;;; +25;96;64;;;; +25;112;64;;;; +25;112;80;;;; +287;328;56;37 +160;272;96; +246;96;48; +246;112;48; +246;128;48; +246;128;64; +246;128;80; +246;144;64; +246;144;80; +246;160;64; +246;160;80; +246;176;64; +246;176;80; +246;192;64; +246;192;80; +246;208;64; +246;208;80; +246;224;64; +246;224;80; +247;256;48; +247;256;64; +247;256;80; +247;272;64; +247;272;80; +247;288;80; diff --git a/bin/Data/Maps/cave24.map.data b/bin/Data/Maps/cave24.map.data new file mode 100644 index 0000000..640c252 --- /dev/null +++ b/bin/Data/Maps/cave24.map.data @@ -0,0 +1,21 @@ +22 +19 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;2;2;2;;;;2;2;;;2;;;;;; +;;;;2;;;;2;2;2;2;2;2;2;;2;;;;;; +;;;2;;2;2;;2;2;2;2;2;2;2;;2;2;2;;;; +;;;;2;;;;;;;;2;2;2;;;;;;;; +;;;;;;;;;;;;2;2;2;2;2;2;;;;; +;;;;;;;;;;;;;2;;;;;;;;; +;;;;;;;;;;;;;2;;;;;;;;; +;;;;;;;;;;;;;2;;;;;;;;; +;;;;;;;;;;;;;2;;;;;;;;; +;;;;;;;;;;;;2;2;2;2;2;;;;;; +;;;;;;;;;;;2;2;2;2;2;2;2;2;;;; +;;;;;;;;;;;2;2;2;2;2;2;2;2;2;;; +;;;;;;;;;;;;2;2;2;2;2;2;;;;; +;;;;;;;;;;;;;;2;2;2;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave25.map b/bin/Data/Maps/cave25.map new file mode 100644 index 0000000..5debdc5 --- /dev/null +++ b/bin/Data/Maps/cave25.map @@ -0,0 +1,823 @@ +3 +2 +1 +cave.png +31 +18 +3 +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,39,47,47,47,47,47,47,47,47,37,,39,47,47,47,47,47,47,37,,,,,,,,,,, +,47,67,70,70,70,70,70,70,70,70,68,39,67,87,87,87,87,87,87,68,37,,,,,,,,,, +,,70,39,47,37,70,70,39,47,37,70,45,87,89,89,89,89,89,89,87,44,,,,,,,,,, +,,39,67,89,44,70,70,45,88,68,47,67,88,89,89,69,71,89,89,89,44,,,,,,,,,, +,,45,88,88,68,20,20,67,70,70,70,70,70,89,89,44,45,89,89,89,44,,,,,,,,,, +,,45,69,46,71,70,70,70,86,70,70,70,70,89,89,44,45,88,88,88,44,,,,,,,,,, +,,45,68,37,36,46,71,70,70,86,69,46,71,88,88,44,45,70,70,69,38,,,,,,,,,, +,,45,70,44,70,84,36,46,46,46,38,84,36,46,46,38,45,70,69,38,,,,,,,,,,, +,,45,70,68,37,84,84,63,63,81,84,39,47,47,47,47,67,70,68,47,37,,,,,,,,,, +,,45,70,70,68,47,37,84,84,63,63,45,87,70,86,87,70,70,63,63,44,,39,47,47,47,47,37,,, +,,36,71,70,70,86,68,47,37,84,84,45,89,63,63,88,63,63,70,63,44,39,67,70,70,70,70,68,37,, +,,,36,71,70,70,86,87,68,47,37,45,88,87,63,63,86,86,63,70,44,45,70,70,70,70,70,70,44,, +,,,,36,71,70,70,88,86,86,68,67,70,88,86,63,63,63,86,70,68,67,70,69,46,71,70,70,44,, +,,,,,36,46,71,70,70,70,70,70,70,63,63,63,70,86,70,70,70,70,70,44,,45,70,70,44,, +,,,,,,,36,46,46,46,46,71,70,70,70,70,70,70,70,69,46,46,46,38,,45,70,70,44,, +,,,,,,,,,,,,36,46,46,46,46,46,46,46,38,,,,,,36,16,15,38,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,, +0,0,3,,,,,,,,,4,0,3,,,,,,,4,0,0,,,,,,,,, +0,0,,,,,,,,,,,,,,,,,,,,4,0,,,,,,,,, +0,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,, +,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,, +,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,, +,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,, +,0,,,,,,,,,,,,,,,,,,,,2,0,,,,,,,,, +,0,,,,,,,,,,,,,,,,,,,,0,0,,,,,,,,, +,0,,,,,,,,,,,,,,,,,,,,4,0,0,0,0,0,0,0,0,, +,0,,,,,,,,,,,,,,,,,,,,,0,3,,,,,4,0,0, +,0,1,,,,,,,,,,,,,,,,,,,,,,,,,,,4,0, +,0,0,1,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,0,0,1,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,,0,0,1,,,,,,,,,,,,,,,,,,,,0,,,,,0, +,,,,0,0,0,1,,,,,,,,,,,,,,,,,2,0,,,,,0, +,,,,,,0,0,0,0,0,0,1,,,,,,,,2,0,0,0,0,0,1,,,2,0, +,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,,,,0,0,,,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +237 +0;32;80;;; +0;32;128;;; +0;32;144;;; +0;32;160;;; +0;48;64;;; +0;48;96;;; +0;48;112;;; +0;48;176;;; +0;64;16;;; +0;64;96;;; +0;64;128;;; +0;64;144;;; +0;64;192;;; +0;80;16;;; +0;80;96;;; +0;80;160;;; +0;80;208;;; +0;96;16;;; +0;96;112;;; +0;96;160;;; +0;96;224;;; +0;112;16;;; +0;112;112;;; +0;112;176;;; +0;112;224;;; +0;128;16;;; +0;128;128;;; +0;128;176;;; +0;128;240;;; +0;144;16;;; +0;144;128;;; +0;144;192;;; +0;144;240;;; +0;160;48;;; +0;160;64;;; +0;160;128;;; +0;160;192;;; +0;160;240;;; +0;176;64;;; +0;176;112;;; +0;176;208;;; +0;176;240;;; +0;192;32;;; +0;192;48;;; +0;192;64;;; +0;192;112;;; +0;192;160;;; +0;192;176;;; +0;192;192;;; +0;192;208;;; +0;192;240;;; +0;208;32;;; +0;208;112;;; +0;208;144;;; +0;208;256;;; +0;224;16;;; +0;224;128;;; +0;224;144;;; +0;224;256;;; +0;240;16;;; +0;240;128;;; +0;240;144;;; +0;240;256;;; +0;256;16;;; +0;256;64;;; +0;256;80;;; +0;256;96;;; +0;256;112;;; +0;256;128;;; +0;256;144;;; +0;256;256;;; +0;272;16;;; +0;272;64;;; +0;272;80;;; +0;272;96;;; +0;272;112;;; +0;272;128;;; +0;272;144;;; +0;272;256;;; +0;288;16;;; +0;288;256;;; +0;304;16;;; +0;304;128;;; +0;304;144;;; +0;304;256;;; +0;320;32;;; +0;320;112;;; +0;320;144;;; +0;320;240;;; +0;336;48;;; +0;336;64;;; +0;336;80;;; +0;336;96;;; +0;336;160;;; +0;336;176;;; +0;336;192;;; +0;336;208;;; +0;336;240;;; +0;352;192;;; +0;352;208;;; +0;352;240;;; +0;368;176;;; +0;368;240;;; +0;384;160;;; +0;384;208;;; +0;384;224;;; +0;400;160;;; +0;400;208;;; +0;416;160;;; +0;416;208;;; +0;416;224;;; +0;416;240;;; +0;432;160;;; +0;448;176;;; +0;464;192;;; +0;464;208;;; +0;464;224;;; +0;464;240;;; +3;432;256;;; +4;448;256;;; +286;32;288;;;; +298;440;256;;;;;; +153;440;264;;;cave_25;overworld.map;cave_25;1;; +341;48;80;;;;;; +341;64;64;;;;;; +341;64;80;;;;;; +341;96;176;;;;;; +341;112;192;;;;;; +341;128;192;;;;;; +341;128;208;;;;;; +341;144;64;;;;;; +341;144;96;;;;;; +341;144;208;;;;;; +341;160;112;;;;;; +341;160;208;;;;;; +341;208;48;;;;;; +341;208;64;;;;;; +341;208;160;;;;;; +341;208;176;;;;;; +341;208;192;;;;;; +341;224;32;;;;;; +341;224;48;;;;;; +341;224;64;;;;;; +341;224;80;;;;;; +341;224;96;;;;;; +341;224;112;;;;;; +341;224;192;;;;;; +341;224;208;;;;;; +341;240;32;;;;;; +341;240;48;;;;;; +341;240;64;;;;;; +341;240;80;;;;;; +341;240;96;;;;;; +341;240;112;;;;;; +341;240;160;;;;;; +341;240;208;;;;;; +341;256;32;;;;;; +341;256;48;;;;;; +341;256;160;;;;;; +341;256;176;;;;;; +341;272;32;;;;;; +341;272;48;;;;;; +341;272;192;;;;;; +341;288;32;;;;;; +341;288;48;;;;;; +341;288;64;;;;;; +341;288;80;;;;;; +341;288;96;;;;;; +341;288;192;;;;;; +341;288;224;;;;;; +341;304;32;;;;;; +341;304;48;;;;;; +341;304;64;;;;;; +341;304;80;;;;;; +341;304;96;;;;;; +341;304;208;;;;;; +341;320;48;;;;;; +341;320;64;;;;;; +341;320;80;;;;;; +341;320;96;;;;;; +200;104;56;;dkey5Collected;dkey5;; +162;64;48;;18;;;;;;; +162;80;64;-18;;;;;;;; +162;128;64;18;;;;;;;; +162;144;48;;18;;;;;;; +302;32;48;;;;; +302;48;32;;;;; +302;160;32;;;;; +302;176;48;;;;; +307;224;144;;;;; +307;240;16;;;;; +307;288;16;;;;; +307;320;144;;;;; +309;144;240;;;;; +309;224;256;;;;; +309;304;256;;;;; +310;32;160;;;;; +25;48;48;;;; +25;64;48;;;; +25;80;48;;;; +25;80;64;;;; +25;80;80;;;; +25;128;48;;;; +25;128;64;;;; +25;128;80;;;; +25;144;48;;;; +224;224;176;;;;;;;; +224;224;224;;;;;;;; +224;240;176;;;;;;;; +224;240;192;;;;;;;; +224;240;224;;;;;;;; +224;256;192;;;;;;;; +224;256;208;;;;;;;; +224;256;224;;;;;;;; +224;272;176;;;;;;;; +224;272;208;;;;;;;; +224;288;176;;;;;;;; +224;288;208;;;;;;;; +224;304;160;;;;;;;; +224;304;192;;;;;;;; +224;320;160;;;;;;;; +224;320;176;;;;;;;; +287;64;288;37 +160;96;80; +160;112;80; +246;64;32; +246;80;32; +246;96;32; +246;96;48; +246;96;64; +246;96;80; +246;112;32; +246;112;48; +246;112;64; +246;112;80; +246;128;32; +246;144;32; diff --git a/bin/Data/Maps/cave25.map.data b/bin/Data/Maps/cave25.map.data new file mode 100644 index 0000000..a82ab37 --- /dev/null +++ b/bin/Data/Maps/cave25.map.data @@ -0,0 +1,20 @@ +31 +18 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;2;2;2;2;2;2;2;2;;;;;;;;;;;;;;;;;;;;; +;;;;;;2;2;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;2;2;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;2;2;2;2;2;;;;;;;;;;;;;;;;;; +;;;;;;2;2;2;;2;2;2;2;;;;;;;;;;;;;;;;;; +;;;;;;;;2;2;;;;;;;;;2;2;;;;;;;;;;;; +;;;2;;;;;;;;;;;;;;;2;;;;;;;;;;;;; +;;;2;;;;;;;;;;;;;;;2;;;;;;;;;;;;; +;;;2;2;;;;;;;;;;2;;;2;2;;;;;;;;;;;;; +;;;;2;2;;;;;;;;;;;;;;2;;;;;2;2;2;2;;;; +;;;;;2;2;;;;;;;;;;;;;;2;;;2;2;2;2;2;2;;; +;;;;;;2;2;;;;;;2;;;;;;;2;;;2;;;;2;2;;; +;;;;;;;;2;2;2;2;2;2;;;;2;;2;2;2;2;2;;;;2;2;;; +;;;;;;;;;;;;;2;2;2;2;2;2;2;;;;;;;;2;2;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave26.map b/bin/Data/Maps/cave26.map new file mode 100644 index 0000000..42bc7cd --- /dev/null +++ b/bin/Data/Maps/cave26.map @@ -0,0 +1,610 @@ +3 +0 +0 +cave.png +8 +15 +3 +,,,,,,,, +,,39,47,37,,,, +,39,67,70,68,37,,, +,45,70,14,70,44,,, +,45,70,70,70,44,,, +,36,71,70,72,38,,, +,,45,70,44,,,, +,,45,70,44,,,, +,,45,70,44,,,, +,,45,70,68,37,,, +,,45,70,70,44,,, +,,36,71,70,68,37,, +,,,45,70,70,44,, +,,,36,16,15,38,, +,,,,,,,, +,,,,,,,, +,,,,,,,, +,,,,,,,, +,,,,,,,, +,,,,,,,, +,,,,,,,, +,,,,,,,, +,,,,,,,, +,,,,,,,, +,,,,,,,, +,,,,,,,, +,,,,,,,, +,,,,,,,, +,,,,,,,, +,,,,,,,, +,0,0,0,0,0,,, +0,0,3,,4,0,0,, +0,3,,,,4,0,, +0,,,,,,0,, +0,,,,,,0,, +0,1,,,,2,0,, +0,0,,,,0,0,, +,0,,,,0,,, +,0,,,,0,0,, +,0,,,,4,0,, +,0,,,,,0,0, +,0,1,,,,4,0, +,0,0,,,,,0, +,,0,1,,,2,0, +,,0,0,,,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +33 +0;16;48;;; +0;16;64;;; +0;32;32;;; +0;32;80;;; +0;32;96;;; +0;32;112;;; +0;32;128;;; +0;32;144;;; +0;32;160;;; +0;48;16;;; +0;48;176;;; +0;48;192;;; +0;64;32;;; +0;64;80;;; +0;64;96;;; +0;64;112;;; +0;64;128;;; +0;64;144;;; +0;72;224;;; +0;80;48;;; +0;80;64;;; +0;80;160;;; +0;80;176;;; +0;96;192;;; +3;64;208;;; +4;80;208;;; +286;-16;240;;;; +298;72;208;;;;;; +153;48;48;;;cave_26_up;cave28.map;cave_26_up;;1; +153;72;216;;;cave_26;overworld.map;cave_26;1;; +423;48;160;; +423;64;160;; +287;16;240;37 diff --git a/bin/Data/Maps/cave26.map.data b/bin/Data/Maps/cave26.map.data new file mode 100644 index 0000000..64f3091 --- /dev/null +++ b/bin/Data/Maps/cave26.map.data @@ -0,0 +1,17 @@ +8 +15 +;;;;;;;; +;;;;;;;; +;;;2;;;;; +;;2;;2;;;; +;;2;2;2;;;; +;;;2;;;;; +;;;2;;;;; +;;;2;;;;; +;;;2;;;;; +;;;2;;;;; +;;;2;2;;;; +;;;;2;;;; +;;;;2;2;;; +;;;;;;;; +;;;;;;;; diff --git a/bin/Data/Maps/cave27.map b/bin/Data/Maps/cave27.map new file mode 100644 index 0000000..cfe8f4d --- /dev/null +++ b/bin/Data/Maps/cave27.map @@ -0,0 +1,645 @@ +3 +1 +1 +cave.png +12 +18 +3 +,,,,,,,,,,,, +,,,,,39,47,37,,,,, +,,,,39,67,70,68,37,,,, +,,,,45,70,17,70,44,,,, +,,,,36,71,70,69,38,,,, +,,,,,45,70,44,,,,, +,,,,,45,70,44,,,,, +,,,,,45,70,44,,,,, +,,,,,45,70,44,,,,, +,,39,47,47,67,70,68,47,37,,, +,,45,70,70,70,70,70,70,44,,, +,39,67,70,63,70,70,70,70,68,37,, +,45,70,70,70,63,63,63,70,70,44,, +,45,63,70,63,70,70,63,63,70,44,, +,45,70,63,70,70,70,70,70,63,44,, +,36,71,70,70,70,70,63,70,69,38,, +,,36,46,46,16,15,46,46,38,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,0,0,0,0,0,,,, +,,,0,0,3,,4,0,0,,, +,,,0,3,,,,4,0,,, +,,,0,,,,,,0,,, +,,,0,1,,,,2,0,,, +,,,0,0,,,,0,0,,, +,,,,0,,,,0,,,, +,,,,0,,,,0,,,, +,0,0,0,0,,,,0,0,0,, +,0,3,,,,,,,4,0,, +0,0,,,,,,,,,0,0, +0,3,,,,,,,,,4,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,1,,,,,,,,,2,0, +0,0,1,,,,,,,2,0,0, +,0,0,0,0,,,0,0,0,0,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +59 +0;16;192;;; +0;16;208;;; +0;16;224;;; +0;32;160;;; +0;32;176;;; +0;32;240;;; +0;48;144;;; +0;48;256;;; +0;64;48;;; +0;64;144;;; +0;64;256;;; +0;80;32;;; +0;80;64;;; +0;80;80;;; +0;80;96;;; +0;80;112;;; +0;80;128;;; +0;80;144;;; +0;96;16;;; +0;112;32;;; +0;112;64;;; +0;112;80;;; +0;112;96;;; +0;112;112;;; +0;112;128;;; +0;112;144;;; +0;112;256;;; +0;128;48;;; +0;128;144;;; +0;128;256;;; +0;144;160;;; +0;144;176;;; +0;144;240;;; +0;160;192;;; +0;160;208;;; +0;160;224;;; +3;80;256;;; +4;96;256;;; +286;16;288;;;; +298;88;256;;;;;; +199;48;208;ruby20;;cave27_chest;; +199;64;160;ruby20;;cave27_chest;; +199;80;224;ruby20;;cave27_chest;; +199;112;224;ruby20;;cave27_chest;; +199;144;192;ruby20;;cave27_chest;; +153;88;264;;;cave_27_exit;overworld.map;cave_27_exit;1;; +153;96;48;;;cave_27;cave23.map;cave_27;3;1; +224;32;208;;;;;;;; +224;48;224;;;;;;;; +224;64;176;;;;;;;; +224;64;208;;;;;;;; +224;80;192;;;;;;;; +224;96;192;;;;;;;; +224;112;192;;;;;;;; +224;112;208;;;;;;;; +224;112;240;;;;;;;; +224;128;208;;;;;;;; +224;144;224;;;;;;;; +287;48;288;37 diff --git a/bin/Data/Maps/cave27.map.data b/bin/Data/Maps/cave27.map.data new file mode 100644 index 0000000..ae2b8e8 --- /dev/null +++ b/bin/Data/Maps/cave27.map.data @@ -0,0 +1,20 @@ +12 +18 +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;2;;;;;; +;;;;;2;;2;;;;; +;;;;;;2;;;;;; +;;;;;;2;;;;;; +;;;;;;2;;;;;; +;;;;;;2;;;;;; +;;;;;;2;;;;;; +;;;;;;2;;;;;; +;;;2;;2;2;2;2;;;; +;;;2;;2;2;2;2;;;; +;;2;2;2;;;;2;;;; +;;;;;2;2;;;2;;; +;;2;;2;;2;;2;;;; +;;;2;2;2;2;;2;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave28.map b/bin/Data/Maps/cave28.map new file mode 100644 index 0000000..f17c4f0 --- /dev/null +++ b/bin/Data/Maps/cave28.map @@ -0,0 +1,622 @@ +3 +-1 +1 +cave.png +17 +10 +3 +,,,,,,,,,,,,,,,,, +,,,,39,47,47,47,47,47,47,47,37,,,,, +,,39,47,67,70,70,70,70,70,70,70,68,47,37,,, +,39,67,70,70,87,87,87,70,87,87,87,70,70,68,37,, +,45,70,70,70,89,89,88,70,88,89,89,70,70,17,44,, +,45,70,70,70,88,88,70,70,70,88,88,70,70,70,44,, +,45,70,70,70,70,70,70,86,70,70,70,70,70,70,44,, +,36,46,46,46,71,70,70,70,70,69,46,46,46,46,38,, +,,,,,36,46,16,15,46,38,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,0,0,0,0,0,0,0,0,0,0,0,,,, +,0,0,0,3,,,,,,,,4,0,0,0,, +0,0,3,,,,,,,,,,,,4,0,0, +0,3,,,,,,,,,,,,,,4,0, +0,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,0, +0,1,,,,,,,,,,,,,,2,0, +0,0,0,0,0,1,,,,,2,0,0,0,0,0,0, +,,,,0,0,0,,,0,0,0,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +60 +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;32;48;;; +0;32;112;;; +0;48;32;;; +0;48;112;;; +0;64;32;;; +0;64;112;;; +0;80;16;;; +0;80;112;;; +0;96;16;;; +0;96;128;;; +0;112;16;;; +0;120;144;;; +0;128;16;;; +0;144;16;;; +0;144;128;;; +0;160;16;;; +0;160;112;;; +0;176;16;;; +0;176;112;;; +0;192;32;;; +0;192;112;;; +0;208;32;;; +0;208;112;;; +0;224;48;;; +0;224;112;;; +0;240;64;;; +0;240;80;;; +0;240;96;;; +3;112;128;;; +4;128;128;;; +286;16;160;;;; +298;120;128;;;;;; +153;120;136;;;cave_28;overworld.map;cave_28;1;; +153;224;64;;;cave_26_up;cave26.map;cave_26_up;3;1; +434;128;32;2 +426;112;64 +426;144;64 +422;48;80 +422;192;48 +341;80;48;;;;;; +341;80;64;;;;;; +341;80;80;;;;;; +341;96;48;;;;;; +341;96;64;;;;;; +341;96;80;;;;;; +341;112;48;;;;;; +341;112;64;;;;;; +341;128;96;;;;;; +341;144;48;;;;;; +341;144;64;;;;;; +341;160;48;;;;;; +341;160;64;;;;;; +341;160;80;;;;;; +341;176;48;;;;;; +341;176;64;;;;;; +341;176;80;;;;;; +287;48;160;37 diff --git a/bin/Data/Maps/cave28.map.data b/bin/Data/Maps/cave28.map.data new file mode 100644 index 0000000..03b3fec --- /dev/null +++ b/bin/Data/Maps/cave28.map.data @@ -0,0 +1,12 @@ +17 +10 +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;2;2;2;2;2;2;2;;;;;; +;;;2;2;;;;2;;;;2;2;;;; +;;2;2;2;;;;2;;;;2;2;;;; +;;2;2;2;;;2;2;2;;;2;2;2;;; +;;2;2;2;2;2;2;;2;2;2;2;2;2;;; +;;;;;;2;2;2;2;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave29.map b/bin/Data/Maps/cave29.map new file mode 100644 index 0000000..e72f33f --- /dev/null +++ b/bin/Data/Maps/cave29.map @@ -0,0 +1,682 @@ +3 +0 +0 +cave.png +12 +10 +3 +,,,,,,,,,,,, +,,39,47,47,47,47,47,47,37,,, +,39,67,,,,,,,68,37,, +,45,,,,,,,,,44,, +,45,,,,,,,,,44,, +,45,,,,,,,,,44,, +,45,,,,,,,,,44,, +,36,71,,,,,,,69,38,, +,,36,46,71,,69,46,46,38,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,0,0,0,0,0,0,0,0,0,0,, +0,0,3,,,,,,,4,0,0, +0,3,,,,,,,,,4,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,1,,,,,,,,,2,0, +0,0,1,,,,,,,2,0,0, +,0,0,0,0,,0,0,0,0,0,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +120 +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;32;32;;; +0;32;112;;; +0;48;16;;; +0;48;128;;; +0;64;16;;; +0;64;128;;; +0;80;16;;; +0;96;16;;; +0;96;128;;; +0;112;16;;; +0;112;128;;; +0;128;16;;; +0;128;128;;; +0;144;32;;; +0;144;112;;; +0;160;48;;; +0;160;64;;; +0;160;80;;; +0;160;96;;; +286;-24;0;;;; +153;80;64;;;hole_entry;;;3;2;False +153;80;136;;;cave_29;overworld.map;cave_29;1;; +299;80;136;80;;;;44; +200;88;72;s;cave29_heartMeter;heartMeter;; +287;-24;24;37 +109;32;48;;;;;; +109;32;64;;;;;; +109;32;80;;;;;; +109;32;96;;;;;; +109;48;32;;;;;; +109;48;48;;;;;; +109;48;64;;;;;; +109;48;80;;;;;; +109;48;96;;;;;; +109;48;112;;;;;; +109;64;32;;;;;; +109;64;48;;;;;; +109;64;64;;;;;; +109;64;80;;;;;; +109;64;96;;;;;; +109;64;112;;;;;; +109;80;32;;;;;; +109;80;48;;;;;; +109;80;64;;;;;; +109;80;80;;;;;; +109;80;96;;;;;; +109;80;112;;;;;; +109;80;128;;;;;; +109;96;32;;;;;; +109;96;48;;;;;; +109;96;64;;;;;; +109;96;80;;;;;; +109;96;96;;;;;; +109;96;112;;;;;; +109;112;32;;;;;; +109;112;48;;;;;; +109;112;64;;;;;; +109;112;80;;;;;; +109;112;96;;;;;; +109;112;112;;;;;; +109;128;32;;;;;; +109;128;48;;;;;; +109;128;64;;;;;; +109;128;80;;;;;; +109;128;96;;;;;; +109;128;112;;;;;; +109;144;48;;;;;; +109;144;64;;;;;; +109;144;80;;;;;; +109;144;96;;;;;; +158;32;48 +158;32;64 +158;32;80 +158;32;96 +158;48;32 +158;48;48 +158;48;64 +158;48;80 +158;48;96 +158;48;112 +158;64;32 +158;64;48 +158;64;64 +158;64;80 +158;64;96 +158;64;112 +158;80;32 +158;80;48 +158;80;64 +158;80;80 +158;80;96 +158;80;112 +158;80;128 +158;80;144 +158;96;32 +158;96;48 +158;96;64 +158;96;80 +158;96;96 +158;96;112 +158;112;32 +158;112;48 +158;112;64 +158;112;80 +158;112;96 +158;112;112 +158;128;32 +158;128;48 +158;128;64 +158;128;80 +158;128;96 +158;128;112 +158;144;48 +158;144;64 +158;144;80 +158;144;96 diff --git a/bin/Data/Maps/cave29.map.data b/bin/Data/Maps/cave29.map.data new file mode 100644 index 0000000..966622a --- /dev/null +++ b/bin/Data/Maps/cave29.map.data @@ -0,0 +1,12 @@ +12 +10 +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave3.map b/bin/Data/Maps/cave3.map new file mode 100644 index 0000000..2df582c --- /dev/null +++ b/bin/Data/Maps/cave3.map @@ -0,0 +1,658 @@ +3 +1 +1 +cave.png +12 +18 +3 +,,,,,,,,,,,, +,,39,47,47,37,39,47,47,47,37,, +,39,67,63,63,44,45,63,63,14,44,, +,45,63,63,63,44,45,63,63,69,38,, +,45,63,63,63,44,36,71,63,44,,, +,36,71,63,69,38,81,45,63,44,,, +,,45,86,44,81,39,67,63,44,,, +,,45,63,44,81,45,63,63,44,,, +,,45,63,44,81,45,63,69,38,,, +,,45,63,68,47,67,63,44,,,, +,,45,63,27,63,63,63,68,37,,, +,,36,46,46,46,71,63,63,44,,, +,,,,,,36,71,63,44,,, +,,,,,,,45,63,68,37,, +,,,,,,39,67,63,63,44,, +,,,,,,45,63,63,14,44,, +,,,,,,36,46,46,46,38,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,,,,,,,,4,0, +0,3,,,,,,,,,,0, +0,,,,,,,,,,2,0, +0,,,,,,,,,,0,0, +0,1,,,,,,,,,0,, +0,0,,,,,,,,,0,, +,0,,,,,,,,,0,, +,0,,,,,,,,2,0,, +,0,,,,,,,,0,0,, +,0,,,,,,,,4,0,, +,0,1,,,,,,,,0,, +,0,0,0,0,0,1,,,,0,0, +,,,,,0,0,,,,4,0, +,,,,,0,3,,,,,0, +,,,,,0,,,,,,0, +,,,,,0,1,,,,2,0, +,,,,,0,0,0,0,0,0,0, +524 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +waterfallSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +71 +0;16;48;;; +0;16;64;;; +0;32;32;;; +0;32;80;;; +0;32;96;;; +0;32;112;;; +0;32;128;;; +0;32;144;;; +0;32;160;;; +0;48;16;;; +0;48;176;;; +0;64;16;;; +0;64;80;;; +0;64;96;;; +0;64;112;;; +0;64;128;;; +0;64;144;;; +0;64;176;;; +0;80;32;;; +0;80;48;;; +0;80;64;;; +0;80;144;;; +0;80;176;;; +0;96;32;;; +0;96;48;;; +0;96;112;;; +0;96;128;;; +0;96;144;;; +0;96;176;;; +0;96;240;;; +0;112;16;;; +0;112;64;;; +0;112;80;;; +0;112;96;;; +0;112;192;;; +0;112;208;;; +0;112;224;;; +0;112;256;;; +0;128;16;;; +0;128;128;;; +0;128;144;;; +0;128;160;;; +0;128;256;;; +0;144;16;;; +0;144;48;;; +0;144;64;;; +0;144;80;;; +0;144;96;;; +0;144;112;;; +0;144;176;;; +0;144;192;;; +0;144;208;;; +0;144;256;;; +0;160;32;;; +0;160;224;;; +0;160;240;;; +286;-16;16;;;;100 +299;48;48;;;;;; +299;144;32;;;;;; +299;144;240;;;;;; +153;144;32;;;ce3_2;cave3_2.map;ce3_2;;1; +153;144;240;;;ce3;house7.map;ce3;;1; +424;48;64;; +424;64;160;; +424;112;176;; +424;128;64;; +342;48;96;;;;;; +224;48;112;2;;;;;;; +287;-16;48;37 +164;48;48;shellsFound;;chest;shellChest..shell_8.;False +164;48;48;shellsFound;1;chest;ruby20..shell_8.;False diff --git a/bin/Data/Maps/cave3.map.data b/bin/Data/Maps/cave3.map.data new file mode 100644 index 0000000..8f7cae4 --- /dev/null +++ b/bin/Data/Maps/cave3.map.data @@ -0,0 +1,20 @@ +12 +18 +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave30.map b/bin/Data/Maps/cave30.map new file mode 100644 index 0000000..2997194 --- /dev/null +++ b/bin/Data/Maps/cave30.map @@ -0,0 +1,714 @@ +3 +1 +1 +cave.png +22 +18 +3 +,,,,,,,,,,,,,,,,,,,,,, +,,39,47,47,37,,,,,,,,,,,,,,,,, +,39,67,70,70,44,,,,,,,,,,,,,,,,, +,45,70,14,70,68,37,,,,,,,,,,,,,,,, +,45,70,70,70,70,68,37,,,,,,,,,,,,,,, +,36,71,70,70,70,,68,47,47,47,47,47,47,47,37,,,,,,, +,,36,71,70,,,,,,,,,,,68,37,,,,,, +,,,36,46,71,,,,,,,,,,,68,37,,,,, +,,,,,36,46,46,46,46,46,46,46,71,,,,44,,,,, +,,,,,,,,,,,,,45,,,,68,37,,,, +,,,,,,,,,,,,,36,71,,,,50,,,, +,,,,,,,,,,,,,,36,71,,,68,37,,, +,,,,,,,,,,,,,,,36,71,,,68,37,, +,,,,,,,,,,,,,,,,45,,70,70,44,, +,,,,,,,,,,,,,,,,36,71,70,70,44,, +,,,,,,,,,,,,,,,,,45,70,18,44,, +,,,,,,,,,,,,,,,,,36,46,46,38,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,0,0,0,0,0,0,,,,,,,,,,,,,,,, +0,0,3,,,4,0,,,,,,,,,,,,,,,, +0,3,,,,,0,0,,,,,,,,,,,,,,, +0,,,,,,4,0,0,,,,,,,,,,,,,, +0,,,,,,,4,0,0,0,0,0,0,0,0,0,,,,,, +0,1,,,,,,,,,,,,,,4,0,0,,,,, +0,0,1,,,,,,,,,,,,,,4,0,0,,,, +,0,0,1,,,,,,,,,,,,,,4,0,,,, +,,0,0,0,1,,,,,,,,,,,,,0,0,,, +,,,,0,0,0,0,0,0,0,0,0,,,,,,4,0,,, +,,,,,,,,,,,,0,1,,,,,,0,0,, +,,,,,,,,,,,,0,0,1,,,,,4,0,0, +,,,,,,,,,,,,,0,0,1,,,,,4,0, +,,,,,,,,,,,,,,0,0,,,,,,0, +,,,,,,,,,,,,,,,0,1,,,,,0, +,,,,,,,,,,,,,,,0,0,,,,,0, +,,,,,,,,,,,,,,,,0,1,,,2,0, +,,,,,,,,,,,,,,,,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +128 +0;16;48;;; +0;16;64;;; +0;32;32;;; +0;32;80;;; +0;48;16;;; +0;48;96;;; +0;64;16;;; +0;64;112;;; +0;80;32;;; +0;80;48;;; +0;80;112;;; +0;96;64;;; +0;96;128;;; +0;112;80;;; +0;112;128;;; +0;128;80;;; +0;128;128;;; +0;144;80;;; +0;144;128;;; +0;160;80;;; +0;160;128;;; +0;176;80;;; +0;176;128;;; +0;192;80;;; +0;192;128;;; +0;208;80;;; +0;208;128;;; +0;208;144;;; +0;224;80;;; +0;224;160;;; +0;240;96;;; +0;240;176;;; +0;256;112;;; +0;256;192;;; +0;256;208;;; +0;272;128;;; +0;272;144;;; +0;272;224;;; +0;272;240;;; +0;288;160;;; +0;288;176;;; +0;288;256;;; +0;304;192;;; +0;304;256;;; +0;320;208;;; +0;320;224;;; +0;320;240;;; +286;-32;0;;;; +298;48;48;;;;;; +298;304;240;;;;;; +153;48;48;;;cave30_left;overworld.map;cave30_left;;1; +153;304;240;;;cave30_right;overworld.map;cave30_right;;1; +457;96;96 +457;224;96 +457;256;160 +22;64;96;;;; +22;160;96;;;; +287;-32;32;37 +157;80;96; +157;96;80; +157;96;96; +157;96;112; +157;112;96; +157;112;112; +157;128;96; +157;256;176; +157;272;176; +157;272;192; +157;272;208; +157;288;192; +108;80;96;;;;;; +108;96;80;;;;;; +108;96;96;;;;;; +108;96;112;;;;;; +108;112;96;;;;;; +108;112;112;;;;;; +108;128;96;;;;;; +108;256;176;;;;;; +108;272;176;;;;;; +108;272;192;;;;;; +108;272;208;;;;;; +108;288;192;;;;;; +109;128;112;;;;;; +109;144;96;;;;;; +109;144;112;;;;;; +109;160;96;;;;;; +109;160;112;;;;;; +109;176;96;;;;;; +109;176;112;;;;;; +109;192;96;;;;;; +109;192;112;;;;;; +109;208;96;;;;;; +109;208;112;;;;;; +109;224;96;;;;;; +109;224;112;;;;;; +109;224;128;;;;;; +109;224;144;;;;;; +109;240;112;;;;;; +109;240;128;;;;;; +109;240;144;;;;;; +109;240;160;;;;;; +109;256;128;;;;;; +109;256;144;;;;;; +109;256;160;;;;;; +109;272;160;;;;;; +158;128;112 +158;144;96 +158;144;112 +158;160;96 +158;160;112 +158;176;96 +158;176;112 +158;192;96 +158;192;112 +158;208;96 +158;208;112 +158;224;96 +158;224;112 +158;224;128 +158;224;144 +158;240;112 +158;240;128 +158;240;144 +158;240;160 +158;256;128 +158;256;144 +158;256;160 +158;272;160 diff --git a/bin/Data/Maps/cave30.map.data b/bin/Data/Maps/cave30.map.data new file mode 100644 index 0000000..828dfa7 --- /dev/null +++ b/bin/Data/Maps/cave30.map.data @@ -0,0 +1,20 @@ +22 +18 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;2;2;;;;;;;;;;;;;;;;;; +;;2;;2;;;;;;;;;;;;;;;;;; +;;2;2;2;2;;;;;;;;;;;;;;;;; +;;;2;2;2;;;;;;;;;;;;;;;;; +;;;;2;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;2;2;;; +;;;;;;;;;;;;;;;;;;2;2;;; +;;;;;;;;;;;;;;;;;;2;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave31.map b/bin/Data/Maps/cave31.map new file mode 100644 index 0000000..9acdd7e --- /dev/null +++ b/bin/Data/Maps/cave31.map @@ -0,0 +1,720 @@ +3 +1 +2 +cave.png +12 +19 +3 +,,,,,,,,,,,, +,,,45,,,,,44,,,, +,,39,67,39,13,47,37,68,37,,, +,39,67,39,67,63,63,68,37,44,,, +,45,39,67,63,63,63,63,44,44,,, +,45,45,63,63,63,69,46,38,44,,, +,45,45,63,63,69,38,69,46,38,,, +,45,36,46,46,38,69,38,,,,, +,45,63,63,,69,38,,,,,, +,45,63,,,44,,,,,,, +,45,63,,,44,,,,,,, +,45,,,,44,,,,,,, +,36,71,,,68,37,,,,,, +,,45,,,,68,37,,,,, +,,36,71,,,,68,37,,,, +,,,36,71,,,,68,13,37,, +,,,,36,46,71,,,,44,, +,,,,,,36,46,46,46,38,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,0,0,0,,,0,0,0,,, +,0,0,0,0,0,0,0,0,0,0,, +0,0,3,,,,,,,4,0,, +0,3,,,,,,,,,0,, +0,,,,,,,,,,0,, +0,,,,,,,,,,0,, +0,,,,,,,,,2,0,, +0,,,,,,,2,0,0,0,, +0,,,,,,2,0,0,,,, +0,,,,,,0,0,,,,, +0,,,,,,0,,,,,, +0,,,,,,0,0,,,,, +0,1,,,,,4,0,0,,,, +0,0,,,,,,4,0,0,,, +,0,1,,,,,,4,0,0,0, +,0,0,1,,,,,,,4,0, +,,0,0,1,,,,,,,0, +,,,0,0,0,1,,,,2,0, +,,,,,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +131 +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;16;128;;; +0;16;144;;; +0;16;160;;; +0;16;176;;; +0;32;48;;; +0;32;192;;; +0;32;208;;; +0;48;32;;; +0;48;224;;; +0;64;16;;; +0;64;240;;; +0;80;16;;; +0;80;128;;; +0;80;144;;; +0;80;160;;; +0;80;176;;; +0;80;192;;; +0;80;256;;; +0;96;16;;; +0;96;112;;; +0;96;208;;; +0;96;256;;; +0;112;16;;; +0;112;96;;; +0;112;224;;; +0;112;272;;; +0;128;32;;; +0;128;96;;; +0;128;240;;; +0;128;272;;; +0;144;48;;; +0;144;64;;; +0;144;80;;; +0;144;272;;; +0;160;256;;; +286;16;304;;;; +298;80;32;;;;;; +298;144;240;;;;;; +153;80;32;;;cave31_up;overworld.map;cave31_up;3;; +153;144;240;;;cave31;overworld.map;cave31;3;; +162;48;120;;-18;32;8;;;;; +25;32;64;;;; +25;32;80;;;; +25;32;96;;;; +25;32;112;;;; +25;48;48;;;; +25;48;64;;;; +25;48;112;;;; +25;64;32;;;; +25;64;48;;;; +25;64;112;;;; +25;80;96;;;; +25;80;112;;;; +25;96;32;;;; +25;96;80;;;; +25;96;96;;;; +25;112;32;;;; +25;112;48;;;; +25;112;80;;;; +25;128;48;;;; +25;128;64;;;; +25;128;80;;;; +287;48;304;37 +246;32;128; +246;32;144; +246;32;160; +246;32;176; +246;48;128; +246;48;144; +246;48;160; +246;48;176; +246;48;192; +246;48;208; +246;64;128; +246;64;144; +246;64;160; +246;64;176; +246;64;192; +246;64;208; +246;64;224; +246;80;208; +246;80;224; +246;80;240; +157;32;176; +157;48;144; +157;48;160; +157;48;176; +157;48;192; +157;64;128; +157;64;144; +157;64;160; +157;64;176; +157;144;256; +108;32;176;;;;;; +108;48;144;;;;;; +108;48;160;;;;;; +108;48;176;;;;;; +108;48;192;;;;;; +108;64;128;;;;;; +108;64;144;;;;;; +108;64;160;;;;;; +108;64;176;;;;;; +108;144;256;;;;;; +109;48;208;;;;;; +109;64;192;;;;;; +109;64;208;;;;;; +109;64;224;;;;;; +109;80;208;;;;;; +109;80;224;;;;;; +109;80;240;;;;;; +109;96;224;;;;;; +109;96;240;;;;;; +109;112;240;;;;;; +109;112;256;;;;;; +109;128;256;;;;;; +158;48;208 +158;64;192 +158;64;208 +158;64;224 +158;80;208 +158;80;224 +158;80;240 +158;96;224 +158;96;240 +158;112;240 +158;112;256 +158;128;256 diff --git a/bin/Data/Maps/cave31.map.data b/bin/Data/Maps/cave31.map.data new file mode 100644 index 0000000..3711aa3 --- /dev/null +++ b/bin/Data/Maps/cave31.map.data @@ -0,0 +1,21 @@ +12 +19 +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave32.map b/bin/Data/Maps/cave32.map new file mode 100644 index 0000000..6edc239 --- /dev/null +++ b/bin/Data/Maps/cave32.map @@ -0,0 +1,654 @@ +3 +1 +1 +cave.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,,39,47,13,47,37,,,,,,,,,,,,,,,, +,39,67,63,63,63,68,37,,,,,,,,,,,,,,, +,45,63,63,63,63,63,68,37,,,,,,,,,,,,,, +,45,63,63,63,87,87,87,68,47,47,47,47,47,47,37,,,,,,, +,45,63,63,87,89,89,89,86,63,63,63,63,,,68,47,47,37,,,, +,36,71,63,88,88,88,88,63,63,63,63,,,,,,,68,13,37,, +,,36,46,46,46,46,71,63,86,63,63,,,,,,63,63,63,44,, +,,,,,,,36,46,46,46,46,46,46,46,46,46,46,46,46,38,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,0,0,0,0,0,0,0,,,,,,,,,,,,,,, +0,0,3,,,,4,0,0,,,,,,,,,,,,,, +0,3,,,,,,4,0,0,,,,,,,,,,,,, +0,,,,,,,,4,0,0,0,0,0,0,0,0,,,,,, +0,,,,,,,,,,,,,,,4,0,0,0,0,,, +0,,,,,,,,,,,,,,,,,,4,0,0,0, +0,1,,,,,,,,,,,,,,,,,,,4,0, +0,0,1,,,,,,,,,,,,,,,,,,,0, +,0,0,0,0,0,0,1,,,,,,,,,,,,,2,0, +,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +92 +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;32;32;;; +0;32;96;;; +0;48;16;;; +0;48;112;;; +0;64;112;;; +0;80;16;;; +0;80;112;;; +0;96;32;;; +0;96;112;;; +0;112;48;;; +0;112;112;;; +0;128;64;;; +0;128;128;;; +0;144;64;;; +0;144;128;;; +0;160;64;;; +0;160;128;;; +0;176;64;;; +0;176;128;;; +0;192;64;;; +0;192;128;;; +0;208;64;;; +0;208;128;;; +0;224;64;;; +0;224;128;;; +0;240;80;;; +0;240;128;;; +0;256;80;;; +0;256;128;;; +0;272;80;;; +0;272;128;;; +0;288;96;;; +0;288;128;;; +0;304;80;;; +0;304;128;;; +0;320;96;;; +0;320;112;;; +286;16;152;;;; +153;64;16;;;cave32_left;overworld.map;cave32_left;3;; +153;304;96;;;cave32_right;overworld.map;cave32_right;3;; +299;64;16;;;;;; +299;304;96;;;;;; +457;224;96 +457;240;112 +22;176;96;;;; +22;176;112;;;; +22;272;112;;;; +341;64;80;;;;;; +341;64;96;;;;;; +341;80;64;;;;;; +341;80;80;;;;;; +341;80;96;;;;;; +341;96;64;;;;;; +341;96;80;;;;;; +341;96;96;;;;;; +341;112;64;;;;;; +341;112;80;;;;;; +341;112;96;;;;;; +341;128;80;;;;;; +341;144;112;;;;;; +224;32;80;;;;;;;; +224;144;96;;;;;;;; +287;40;152;37 +157;240;112; +157;256;96; +157;256;112; +157;272;96; +108;240;112;;;;;; +108;256;96;;;;;; +108;256;112;;;;;; +108;272;96;;;;;; +109;192;96;;;;;; +109;192;112;;;;;; +109;208;80;;;;;; +109;208;96;;;;;; +109;208;112;;;;;; +109;224;80;;;;;; +109;224;96;;;;;; +109;224;112;;;;;; +109;240;96;;;;;; +158;192;96 +158;192;112 +158;208;80 +158;208;96 +158;208;112 +158;224;80 +158;224;96 +158;224;112 +158;240;96 diff --git a/bin/Data/Maps/cave32.map.data b/bin/Data/Maps/cave32.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/cave32.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave33.map b/bin/Data/Maps/cave33.map new file mode 100644 index 0000000..baee86d --- /dev/null +++ b/bin/Data/Maps/cave33.map @@ -0,0 +1,569 @@ +3 +0 +0 +cave.png +8 +7 +3 +,,,,,,,, +,,39,47,47,37,,, +,39,67,70,70,68,37,, +,45,70,70,70,70,44,, +,36,71,70,18,72,38,, +,,36,46,46,38,,, +,,,,,,,, +,,,,,,,, +,,,,,,,, +,,,,,,,, +,,,,,,,, +,,,,,,,, +,,,,,,,, +,,,,,,,, +,0,0,0,0,0,0,, +0,0,3,,,4,0,0, +0,3,,,,,4,0, +0,,,,,,,0, +0,1,,,,,2,0, +0,0,1,,,2,0,0, +,0,0,0,0,0,0,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +16 +0;16;48;;; +0;32;32;;; +0;32;64;;; +0;48;16;;; +0;48;80;;; +0;64;16;;; +0;64;80;;; +0;80;32;;; +0;80;64;;; +0;96;48;;; +286;0;-32;;;; +298;64;64;;;;;; +153;64;64;;;cave33;overworld.map;cave33;;1; +287;32;-32;37 +164;48;32;shellsFound;1;chest;ruby20..shell_23.;False +164;48;32;shellsFound;;chest;shellChest..shell_23.;False diff --git a/bin/Data/Maps/cave33.map.data b/bin/Data/Maps/cave33.map.data new file mode 100644 index 0000000..aad1083 --- /dev/null +++ b/bin/Data/Maps/cave33.map.data @@ -0,0 +1,9 @@ +8 +7 +;;;;;;;; +;;;;;;;; +;;;2;2;;;; +;;2;2;2;2;;; +;;;2;;;;; +;;;;;;;; +;;;;;;;; diff --git a/bin/Data/Maps/cave3_2.map b/bin/Data/Maps/cave3_2.map new file mode 100644 index 0000000..486c2db --- /dev/null +++ b/bin/Data/Maps/cave3_2.map @@ -0,0 +1,631 @@ +3 +0 +0 +cave.png +21 +11 +3 +,,,,,,,,,,,,,,,,,,,,, +,44,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,45,,,, +,44,81,81,39,47,47,47,47,47,47,47,47,47,37,81,81,45,,,, +,44,81,39,67,63,63,63,63,63,63,81,63,17,68,37,81,45,,,, +,44,81,45,63,63,28,28,63,28,28,28,28,28,28,68,47,67,,,, +,44,81,45,63,63,39,47,20,47,47,47,47,47,47,47,47,47,37,,, +,44,81,36,71,39,67,70,63,63,70,63,70,63,27,70,70,63,68,37,, +,44,81,81,45,45,63,70,63,27,70,70,70,70,70,63,63,70,70,44,, +,68,47,47,67,45,63,63,70,63,70,70,70,63,70,70,63,27,63,44,, +,,,,,36,46,46,16,15,46,46,46,46,46,46,46,46,46,38,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,, +0,3,,,,,,,,,,,,,,,,4,0,,, +0,,,,,,,,,,,,,,,,,,0,,, +0,,,,,,,,,,,,,,,,,,0,0,, +0,,,,,,,,,,,,,,,,,,4,0,0, +0,,,,,,,,,,,,,,,,,,,4,0, +0,,,,,,,,,,,,,,,,,,,,0, +0,1,,,,,,,,,,,,,,,,,,,0, +0,0,0,0,0,1,,,,,,,,,,,,,,2,0, +,,,,0,0,0,0,,,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +66 +0;48;64;;; +0;48;80;;; +0;64;48;;; +0;64;96;;; +0;80;32;;; +0;80;96;;; +0;80;112;;; +0;80;128;;; +0;96;32;;; +0;96;80;;; +0;96;96;;; +0;96;144;;; +0;112;32;;; +0;112;80;;; +0;112;144;;; +0;128;32;;; +0;136;160;;; +0;144;32;;; +0;144;80;;; +0;160;32;;; +0;160;80;;; +0;160;144;;; +0;176;32;;; +0;176;80;;; +0;176;144;;; +0;192;32;;; +0;192;80;;; +0;192;144;;; +0;208;32;;; +0;208;80;;; +0;208;144;;; +0;224;48;;; +0;224;80;;; +0;224;144;;; +0;240;64;;; +0;240;80;;; +0;240;144;;; +0;256;80;;; +0;256;144;;; +0;272;80;;; +0;272;144;;; +0;288;96;;; +0;288;144;;; +0;304;112;;; +0;304;128;;; +1;96;64;;; +1;112;64;;; +1;144;64;;; +1;160;64;;; +1;176;64;;; +1;192;64;;; +1;208;64;;; +1;224;64;;; +3;128;144;;; +4;144;144;;; +286;-16;32;;;; +298;136;144;;;;;; +153;136;152;;;ce3w;overworld.map;ce3w;1;; +153;208;48;;;ce3_2;cave3.map;ce3_2;;1; +434;256;96;2 +423;64;80;; +423;208;128;; +423;240;128;; +302;80;80;;;;; +287;-16;64;37 +160;128;80; diff --git a/bin/Data/Maps/cave3_2.map.data b/bin/Data/Maps/cave3_2.map.data new file mode 100644 index 0000000..0f7a4b9 --- /dev/null +++ b/bin/Data/Maps/cave3_2.map.data @@ -0,0 +1,13 @@ +21 +11 +;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;2;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;; +;;;;;;;2;;;2;;2;;;2;2;;;;; +;;;;;;;2;;;2;2;2;2;2;;;2;2;;; +;;;;;;;;2;;2;2;2;;2;2;;;;;; +;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave4.map b/bin/Data/Maps/cave4.map new file mode 100644 index 0000000..fd75056 --- /dev/null +++ b/bin/Data/Maps/cave4.map @@ -0,0 +1,632 @@ +3 +1 +1 +cave.png +12 +10 +3 +,,,,,,,,,,,, +,39,47,47,47,47,47,47,47,47,37,, +,45,63,63,89,89,89,89,63,63,44,, +,45,63,63,89,89,89,89,70,63,44,, +,45,87,87,89,89,89,89,87,87,44,, +,45,89,89,89,89,89,89,88,88,44,, +,45,89,89,89,88,88,88,70,70,44,, +,45,89,89,89,70,63,70,63,63,44,, +,36,46,46,46,16,15,46,46,46,38,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0, +0,3,,,,,,,,,4,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,1,,,,,,,,,2,0, +0,0,0,0,0,,,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +70 +382;-16;80; +0;16;32;;; +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;32;16;;; +0;32;128;;; +0;48;16;;; +0;48;128;;; +0;64;16;;; +0;64;128;;; +0;80;16;;; +0;88;144;;; +0;96;16;;; +0;112;16;;; +0;112;128;;; +0;128;16;;; +0;128;128;;; +0;144;16;;; +0;144;128;;; +0;160;32;;; +0;160;48;;; +0;160;64;;; +0;160;80;;; +0;160;96;;; +0;160;112;;; +3;80;128;;; +4;96;128;;; +286;-16;48;;;; +298;88;128;;;;;; +199;32;32;ruby50;;cave4_r50;; +153;88;136;;;c4;overworld.map;c4;1;; +341;32;64;;;;;; +341;32;80;;;;;; +341;32;96;;;;;; +341;32;112;;;;;; +341;48;64;;;;;; +341;48;80;;;;;; +341;48;96;;;;;; +341;48;112;;;;;; +341;64;32;;;;;; +341;64;48;;;;;; +341;64;64;;;;;; +341;64;80;;;;;; +341;64;96;;;;;; +341;64;112;;;;;; +341;80;32;;;;;; +341;80;48;;;;;; +341;80;64;;;;;; +341;80;80;;;;;; +341;80;96;;;;;; +341;96;32;;;;;; +341;96;48;;;;;; +341;96;64;;;;;; +341;96;80;;;;;; +341;96;96;;;;;; +341;112;32;;;;;; +341;112;48;;;;;; +341;112;64;;;;;; +341;112;80;;;;;; +341;112;96;;;;;; +341;128;64;;;;;; +341;128;80;;;;;; +341;144;64;;;;;; +341;144;80;;;;;; +224;144;32;1;;;;;;; +224;144;112;1;;;;;;; +287;-16;16;37 diff --git a/bin/Data/Maps/cave4.map.data b/bin/Data/Maps/cave4.map.data new file mode 100644 index 0000000..590174d --- /dev/null +++ b/bin/Data/Maps/cave4.map.data @@ -0,0 +1,12 @@ +12 +10 +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;2;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;2;2;;; +;;;;;2;;2;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave5.map b/bin/Data/Maps/cave5.map new file mode 100644 index 0000000..539e7ef --- /dev/null +++ b/bin/Data/Maps/cave5.map @@ -0,0 +1,693 @@ +3 +1 +1 +cave.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,39,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,37,, +,45,88,88,89,86,70,63,70,70,63,63,63,63,69,46,46,46,46,71,44,, +,45,70,63,89,86,86,70,63,63,27,63,70,87,44,22,29,29,23,45,44,, +,45,63,70,88,86,86,86,87,63,70,70,70,89,44,24,70,70,21,45,44,, +,45,86,63,63,70,70,70,89,24,28,28,21,89,68,47,20,47,47,67,44,, +,45,86,86,27,86,63,70,88,86,86,86,86,88,70,63,70,70,27,70,44,, +,36,46,71,86,86,86,27,70,29,29,29,29,70,70,70,70,70,70,69,38,, +,,,36,46,16,15,46,46,46,46,46,46,46,46,16,15,46,46,38,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,,,,,,,,,,,,,,,,,,,4,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,1,,,,,,,,,,,,,,,,,,,2,0, +0,0,0,1,,,,,,,,,,,,,,,,2,0,0, +,,0,0,0,,,0,0,0,0,0,0,0,0,,,0,0,0,0,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +131 +382;-8;64; +0;16;32;;; +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;32;16;;; +0;32;112;;; +0;48;16;;; +0;48;112;;; +0;64;16;;; +0;64;128;;; +0;80;16;;; +0;88;144;;; +0;96;16;;; +0;112;16;;; +0;112;128;;; +0;128;16;;; +0;128;128;;; +0;144;16;;; +0;144;128;;; +0;160;16;;; +0;160;128;;; +0;176;16;;; +0;176;128;;; +0;192;16;;; +0;192;128;;; +0;208;16;;; +0;208;128;;; +0;224;16;;; +0;224;128;;; +0;240;16;;; +0;248;144;;; +0;256;16;;; +0;272;16;;; +0;272;128;;; +0;288;16;;; +0;288;128;;; +0;304;16;;; +0;304;112;;; +0;320;32;;; +0;320;48;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +19;288;48;;; +20;144;80;;; +20;240;64;;; +21;192;80;;; +21;288;64;;; +3;80;128;;; +3;240;128;;; +4;96;128;;; +4;256;128;;; +18;240;48;;; +286;-8;40;;;; +275;32;80; +275;32;96; +275;48;96; +275;64;112; +275;80;32; +275;80;48; +275;80;96; +275;80;112; +275;96;48; +275;96;112; +298;88;128;;;;;; +298;248;128;;;;;; +199;128;32;ruby20;;c5_r20;; +199;272;48;ruby50;;c5_r50;; +153;88;136;;;c5_1;overworld.map;c5_1;1;; +153;248;136;;;c5_2;overworld.map;c5_2;1;; +423;32;64;; +423;64;96;; +423;240;96;; +423;256;96;; +423;272;96;; +341;32;32;;;;;; +341;48;32;;;;;; +341;64;32;;;;;; +341;64;48;;;;;; +341;64;64;;;;;; +341;80;64;;;;;; +341;96;64;;;;;; +341;112;64;;;;;; +341;128;64;;;;;; +341;128;80;;;;;; +341;128;96;;;;;; +341;144;96;;;;;; +341;160;96;;;;;; +341;176;96;;;;;; +341;192;96;;;;;; +341;208;48;;;;;; +341;208;64;;;;;; +341;208;80;;;;;; +341;208;96;;;;;; +162;272;80;;18;;8;;;;; +10;160;80;;; +10;176;80;;; +11;144;110;;; +11;160;110;;; +11;176;110;;; +11;192;110;;; +11;256;48;;; +11;272;48;;; +25;224;32;;;; +25;224;48;;;; +25;224;64;;;; +25;224;80;;;; +25;240;32;;;; +25;240;80;;;; +25;256;32;;;; +25;272;32;;;; +25;272;80;;;; +25;288;32;;;; +25;288;80;;;; +25;304;32;;;; +25;304;48;;;; +25;304;64;;;; +25;304;80;;;; +287;-8;16;37 +160;256;80; +230;272;64;;;;;; +246;240;48; +246;240;64; +246;256;48; +246;256;64; +246;256;80; +246;272;64; +246;288;48; +246;288;64; diff --git a/bin/Data/Maps/cave5.map.data b/bin/Data/Maps/cave5.map.data new file mode 100644 index 0000000..b9793ea --- /dev/null +++ b/bin/Data/Maps/cave5.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;2;;2;2;;;;;;;;;;;;; +;;2;;;;;2;;;;;2;;;;;;;;;; +;;;2;;;;;;;2;2;2;;;;2;2;;;;; +;;;;;2;2;2;;;;;;;;;;;;;;; +;;;;;;;2;;;;;;;2;;2;2;;2;;; +;;;;;;;;2;;;;;2;2;2;2;2;2;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave6.map b/bin/Data/Maps/cave6.map new file mode 100644 index 0000000..2af144f --- /dev/null +++ b/bin/Data/Maps/cave6.map @@ -0,0 +1,615 @@ +3 +1 +1 +cave.png +12 +10 +3 +,,,,,,,,,,,, +,39,47,47,47,47,47,47,47,47,37,, +,45,63,86,63,70,70,63,63,63,44,, +,45,27,63,70,70,63,86,27,70,44,, +,45,63,70,86,63,70,63,63,63,44,, +,45,63,63,27,86,63,70,63,27,44,, +,45,70,63,63,63,63,63,63,63,44,, +,45,70,70,63,63,63,63,63,70,44,, +,36,46,46,46,16,15,46,46,46,38,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0, +0,3,,,,,,,,,4,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,1,,,,,,,,,2,0, +0,0,0,0,0,,,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +53 +382;-16;112; +0;16;32;;; +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;32;16;;; +0;32;128;;; +0;48;16;;; +0;48;128;;; +0;64;16;;; +0;64;128;;; +0;80;16;;; +0;88;144;;; +0;96;16;;; +0;112;16;;; +0;112;128;;; +0;128;16;;; +0;128;128;;; +0;144;16;;; +0;144;128;;; +0;160;32;;; +0;160;48;;; +0;160;64;;; +0;160;80;;; +0;160;96;;; +0;160;112;;; +3;80;128;;; +4;96;128;;; +286;-16;16;;;; +275;48;32; +275;64;64; +275;80;80; +275;112;48; +298;88;128;;;;;; +199;80;48;ruby50;;c6_ruby50;; +153;88;136;;;cave6;overworld.map;cave6;1;; +423;32;48;; +423;64;80;; +423;128;48;; +423;144;80;; +224;64;96;;;;;;;; +224;80;64;5;;;;;;; +224;96;48;10;;;;;;; +224;96;80;;;;;;;; +224;96;96;;;;;;;; +224;112;32;5;;;;;;; +224;112;64;;;;;;;; +224;112;112;5;;;;;;; +287;-16;80;37 +230;32;112;;;;;; +230;144;48;;;;;; diff --git a/bin/Data/Maps/cave6.map.data b/bin/Data/Maps/cave6.map.data new file mode 100644 index 0000000..a481ca3 --- /dev/null +++ b/bin/Data/Maps/cave6.map.data @@ -0,0 +1,12 @@ +12 +10 +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;2;2;;;;;; +;;;;2;;;;;2;;; +;;;2;;;2;;;;;; +;;;;;;;2;;;;; +;;2;;;;;;;;;; +;;2;2;;;;;;2;;; +;;;;;;;;;;;; +;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave7.map b/bin/Data/Maps/cave7.map new file mode 100644 index 0000000..7ced255 --- /dev/null +++ b/bin/Data/Maps/cave7.map @@ -0,0 +1,687 @@ +3 +-1 +0 +cave.png +27 +17 +3 +,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,39,47,47,47,37,,,,,39,47,47,47,47,47,47,47,47,47,37,,,,, +,,39,67,86,86,87,68,37,,39,47,67,70,70,70,70,70,70,70,70,70,68,47,37,,, +,39,67,86,70,70,88,87,44,39,67,70,70,70,70,70,70,70,70,70,70,70,70,70,68,37,, +,45,87,70,14,70,70,89,82,82,63,70,70,70,70,70,70,70,70,70,70,70,70,70,70,44,, +,45,88,87,70,70,87,88,44,36,71,70,70,70,70,70,70,70,70,70,70,70,70,70,70,44,, +,36,71,88,86,86,88,69,38,,36,71,70,70,70,70,70,70,69,71,70,70,70,70,69,38,, +,,36,46,46,46,46,38,,,,45,70,70,70,70,70,69,38,36,46,16,15,46,38,,, +,,,,,,,,,,39,67,70,70,70,70,70,44,,,,,,,,,, +,,,,,,,,,39,67,70,70,70,70,70,70,44,,,,,,,,,, +,,,,,,,,,45,70,70,70,70,70,70,70,44,,,,,,,,,, +,,,,,,,,,45,70,70,70,70,70,70,70,44,,,,,,,,,, +,,,,,,,,,45,70,70,70,70,69,46,46,38,,,,,,,,,, +,,,,,,,,,45,70,70,70,70,44,,,,,,,,,,,,, +,,,,,,,,,36,71,70,70,70,44,,,,,,,,,,,,, +,,,,,,,,,,36,16,15,46,38,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,0,0,0,0,0,0,0,,,0,0,0,0,0,0,0,0,0,0,0,0,0,,,, +,0,0,3,,,,4,0,0,0,0,3,,,,,,,,,,4,0,0,0,, +0,0,3,,,,,,4,0,3,,,,,,,,,,,,,,4,0,0, +0,3,,,,,,,,3,,,,,,,,,,,,,,,,4,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,1,,,,,,,,,,,,,,,,,0, +0,1,,,,,,,2,0,1,,,,,,,,,,,,,,,2,0, +0,0,1,,,,,2,0,0,0,,,,,,,,,,,,,,2,0,0, +,0,0,0,0,0,0,0,0,0,3,,,,,,,,0,0,0,,,0,0,0,, +,,,,,,,,0,3,,,,,,,,,0,,,,,,,,, +,,,,,,,,0,,,,,,,,,,0,,,,,,,,, +,,,,,,,,0,,,,,,,,,,0,,,,,,,,, +,,,,,,,,0,,,,,,,,,2,0,,,,,,,,, +,,,,,,,,0,,,,,,,0,0,0,0,,,,,,,,, +,,,,,,,,0,1,,,,,,0,,,,,,,,,,,, +,,,,,,,,0,0,1,,,,2,0,,,,,,,,,,,, +,,,,,,,,,0,0,,,0,0,0,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +104 +382;144;272; +0;16;64;;; +0;16;80;;; +0;32;48;;; +0;32;96;;; +0;48;32;;; +0;48;112;;; +0;64;16;;; +0;64;112;;; +0;80;16;;; +0;80;112;;; +0;96;16;;; +0;96;112;;; +0;112;32;;; +0;112;96;;; +0;128;48;;; +0;128;80;;; +0;144;48;;; +0;144;80;;; +0;144;160;;; +0;144;176;;; +0;144;192;;; +0;144;208;;; +0;160;48;;; +0;160;80;;; +0;160;144;;; +0;160;224;;; +0;176;32;;; +0;176;96;;; +0;176;112;;; +0;176;128;;; +0;184;256;;; +0;192;32;;; +0;208;16;;; +0;208;240;;; +0;224;16;;; +0;224;192;;; +0;224;208;;; +0;224;224;;; +0;240;16;;; +0;240;192;;; +0;256;16;;; +0;256;192;;; +0;272;16;;; +0;272;112;;; +0;272;128;;; +0;272;144;;; +0;272;160;;; +0;272;176;;; +0;288;16;;; +0;288;96;;; +0;304;16;;; +0;304;96;;; +0;320;16;;; +0;320;112;;; +0;336;16;;; +0;344;128;;; +0;352;32;;; +0;368;32;;; +0;368;112;;; +0;384;48;;; +0;384;96;;; +0;400;64;;; +0;400;80;;; +3;176;240;;; +3;336;112;;; +4;192;240;;; +4;352;112;;; +286;448;0;;;; +298;184;240;;;;;; +298;344;112;;;;;; +268;128;64;;cave7_wall;;; +268;144;64;;cave7_wall;2;; +153;64;64;;;cave7_stairs;cave7_2.map;cave7_stairs;2;1; +153;184;248;;;cave7down;overworld.map;cave7down;1;; +153;344;120;;;cave7up;overworld.map;cave7up;1;; +248;-16;0;cave7_wall;; +426;240;16 +443;160;160 +443;192;80 +443;224;32 +443;256;176 +443;384;64 +423;192;192;; +423;208;160;; +423;240;96;; +423;336;48;; +341;32;64;;;;;; +341;32;80;;;;;; +341;48;48;;;;;; +341;48;80;;;;;; +341;48;96;;;;;; +341;64;32;;;;;; +341;64;96;;;;;; +341;80;32;;;;;; +341;80;96;;;;;; +341;96;32;;;;;; +341;96;48;;;;;; +341;96;80;;;;;; +341;96;96;;;;;; +341;112;48;;;;;; +341;112;64;;;;;; +341;112;80;;;;;; +287;448;32;37 diff --git a/bin/Data/Maps/cave7.map.data b/bin/Data/Maps/cave7.map.data new file mode 100644 index 0000000..20120e2 --- /dev/null +++ b/bin/Data/Maps/cave7.map.data @@ -0,0 +1,19 @@ +27 +17 +;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;2;2;2;2;2;2;2;2;2;;;;;; +;;;;2;2;;;;;;2;2;2;2;2;2;2;2;2;2;2;2;2;;;; +;;;2;;2;2;;;;;2;2;2;2;2;2;2;2;2;2;2;2;2;2;;; +;;;;2;2;;;;;;2;2;2;2;2;2;2;2;2;2;2;2;2;2;;; +;;;;;;;;;;;;2;2;2;2;2;2;;;2;2;2;2;;;; +;;;;;;;;;;;;2;2;2;2;2;;;;;;;;;;; +;;;;;;;;;;;;2;2;2;2;2;;;;;;;;;;; +;;;;;;;;;;;2;2;2;2;2;2;;;;;;;;;;; +;;;;;;;;;;2;2;2;2;2;2;2;;;;;;;;;;; +;;;;;;;;;;2;2;2;2;2;2;2;;;;;;;;;;; +;;;;;;;;;;2;2;2;2;;;;;;;;;;;;;; +;;;;;;;;;;2;2;2;2;;;;;;;;;;;;;; +;;;;;;;;;;;2;2;2;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave7_2.map b/bin/Data/Maps/cave7_2.map new file mode 100644 index 0000000..1ab22f1 --- /dev/null +++ b/bin/Data/Maps/cave7_2.map @@ -0,0 +1,645 @@ +3 +0 +1 +cave.png +20 +10 +3 +,,,,,,,,,,,,,,,,,,,, +,,39,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,37,, +,39,67,63,63,63,70,70,86,63,70,70,70,70,70,70,70,17,44,, +,45,63,63,63,63,63,63,63,70,63,63,69,46,46,46,46,46,38,, +,36,71,63,63,63,70,70,63,63,70,70,44,70,70,70,70,63,84,, +,,36,46,46,71,70,70,70,63,70,70,68,47,47,47,20,47,37,, +,,,,,45,70,70,70,63,70,70,70,70,70,70,70,63,44,, +,,,,,36,71,70,70,63,63,70,63,63,70,70,70,69,38,, +,,,,,,36,46,46,46,46,16,15,46,46,46,46,38,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,,,,,,,,,,,,,,,,4,0, +0,3,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,0, +0,1,,,,,,,,,,,,,,,,,,0, +0,0,1,,,,,,,,,,,,,,,,,0, +,0,0,0,0,,,,,,,,,,,,,,,0, +,,,,0,1,,,,,,,,,,,,,2,0, +,,,,0,0,1,,,,,,,,,,,2,0,0, +,,,,,0,0,0,0,0,0,,,0,0,0,0,0,0,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +83 +0;16;48;;; +0;32;32;;; +0;32;64;;; +0;48;16;;; +0;48;80;;; +0;64;16;;; +0;64;80;;; +0;80;16;;; +0;80;80;;; +0;80;96;;; +0;96;16;;; +0;96;112;;; +0;112;16;;; +0;112;128;;; +0;128;16;;; +0;128;128;;; +0;144;16;;; +0;144;128;;; +0;160;16;;; +0;160;128;;; +0;176;16;;; +0;184;144;;; +0;192;16;;; +0;208;16;;; +0;208;128;;; +0;224;16;;; +0;224;128;;; +0;240;16;;; +0;240;128;;; +0;256;16;;; +0;256;128;;; +0;272;16;;; +0;272;80;;; +0;272;112;;; +0;288;32;;; +0;288;96;;; +3;176;128;;; +4;192;128;;; +286;-32;16;;;; +153;184;136;;;cave7_2;overworld.map;cave7_2;1;; +153;272;32;;;cave7_stairs;cave7.map;cave7_stairs;;1; +423;32;48;; +423;112;96;; +423;160;32;; +423;160;80;; +423;272;96;; +341;128;32;;;;;; +162;192;64;-18;;;;;;;; +162;208;56;;-18;64;8;;;;; +162;208;80;;18;48;8;;;;; +25;192;48;;;; +25;192;64;;;; +25;192;80;;;; +25;208;48;;;; +25;208;80;;;; +25;224;48;;;; +25;224;80;;;; +25;240;48;;;; +25;240;80;;;; +25;256;48;;;; +25;272;48;;;; +224;64;48;;;;;;;; +224;80;48;;;;;;;; +224;96;48;;;;;;;; +224;112;48;;;;;;;; +224;128;48;;;;;;;; +224;128;64;;;;;;;; +224;144;32;;;;;;;; +224;144;64;;;;;;;; +224;144;80;;;;;;;; +224;144;96;;;;;;;; +224;144;112;;;;;;;; +224;160;48;;;;;;;; +224;160;112;;;;;;;; +224;176;48;;;;;;;; +224;272;64;0;;;;;;; +287;-32;48;37 +160;256;80; +246;208;64; +246;224;64; +246;240;64; +246;256;64; +246;256;80; diff --git a/bin/Data/Maps/cave7_2.map.data b/bin/Data/Maps/cave7_2.map.data new file mode 100644 index 0000000..bc9c46a --- /dev/null +++ b/bin/Data/Maps/cave7_2.map.data @@ -0,0 +1,12 @@ +20 +10 +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;2;2;;;2;2;2;2;2;2;2;;;; +;;;;;;;;;2;;;;;;;;;;; +;;;;;;2;2;;;2;2;;2;2;2;2;;;; +;;;;;;2;2;2;;2;2;;;;;;;;; +;;;;;;2;2;2;;2;2;2;2;2;2;2;;;; +;;;;;;;2;2;;;2;;;2;2;2;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave8.map b/bin/Data/Maps/cave8.map new file mode 100644 index 0000000..1c9dc9f --- /dev/null +++ b/bin/Data/Maps/cave8.map @@ -0,0 +1,621 @@ +3 +1 +1 +cave.png +12 +10 +3 +,,,,,,,,,,,, +,,39,47,47,47,47,47,47,37,,, +,39,67,63,63,,,63,63,68,37,, +,45,63,63,,,,,63,63,44,, +,45,63,63,,,,,63,63,44,, +,45,63,63,63,,,63,63,63,44,, +,45,63,63,63,63,63,63,63,63,44,, +,36,71,63,63,63,63,63,63,69,38,, +,,36,46,46,83,46,46,46,38,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,0,0,0,0,0,0,0,0,0,0,, +0,0,3,,,,,,,4,0,0, +0,3,,,,,,,,,4,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,1,,,,,,,,,2,0, +0,0,1,,,,,,,2,0,0, +,0,0,0,0,,0,0,0,0,0,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +59 +382;48;160; +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;32;32;;; +0;32;112;;; +0;48;16;;; +0;48;128;;; +0;64;16;;; +0;64;128;;; +0;80;16;;; +0;80;144;;; +0;96;16;;; +0;96;128;;; +0;112;16;;; +0;112;128;;; +0;128;16;;; +0;128;128;;; +0;144;32;;; +0;144;112;;; +0;160;48;;; +0;160;64;;; +0;160;80;;; +0;160;96;;; +72;32;48;;;;;; +71;80;48;;;;;; +286;16;160;;;; +298;80;128;;;;;; +153;80;136;;;cave8;overworld.map;cave8;1;; +307;64;16;;;;; +307;112;16;;;;; +287;16;192;37 +256;16;16 +358;88;30;;npc_hidden;npc_hidden;;0.18.14.28 +157;64;48; +157;64;64; +157;80;32; +157;80;48; +157;80;64; +157;80;80; +157;96;32; +157;96;48; +157;96;64; +157;96;80; +157;112;48; +157;112;64; +108;64;48;;;;;; +108;64;64;;;;;; +108;80;32;;;;;; +108;80;48;;;;;; +108;80;64;;;;;; +108;80;80;;;;;; +108;96;32;;;;;; +108;96;48;;;;;; +108;96;64;;;;;; +108;96;80;;;;;; +108;112;48;;;;;; +108;112;64;;;;;; diff --git a/bin/Data/Maps/cave8.map.data b/bin/Data/Maps/cave8.map.data new file mode 100644 index 0000000..966622a --- /dev/null +++ b/bin/Data/Maps/cave8.map.data @@ -0,0 +1,12 @@ +12 +10 +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; diff --git a/bin/Data/Maps/cave9.map b/bin/Data/Maps/cave9.map new file mode 100644 index 0000000..d5fbeeb --- /dev/null +++ b/bin/Data/Maps/cave9.map @@ -0,0 +1,691 @@ +3 +1 +0 +cave.png +22 +8 +3 +,,,,,,,,,,,,,,,,,,,,,, +,,39,47,47,47,47,47,47,37,,,39,47,47,47,47,47,47,37,,, +,39,67,70,70,70,70,70,,68,47,47,67,,,,63,,,68,37,, +,45,70,14,70,70,70,70,,,,,,,,,63,70,14,70,44,, +,45,70,70,70,70,70,,,,,,,,,,,63,70,70,44,, +,36,71,70,70,70,,,,69,46,46,71,,,,,,63,69,38,, +,,36,46,46,46,46,46,46,38,,,36,46,46,46,46,46,46,38,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,, +0,0,3,,,,,,,4,0,0,3,,,,,,,4,0,0, +0,3,,,,,,,,,,,,,,,,,,,4,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,1,,,,,,,,,,,,,,,,,,,2,0, +0,0,1,,,,,,,2,0,0,1,,,,,,,2,0,0, +,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +135 +0;16;48;;; +0;16;64;;; +0;32;32;;; +0;32;80;;; +0;48;16;;; +0;48;96;;; +0;64;16;;; +0;64;96;;; +0;80;16;;; +0;80;96;;; +0;96;16;;; +0;96;96;;; +0;112;16;;; +0;112;96;;; +0;128;16;;; +0;128;96;;; +0;144;32;;; +0;144;80;;; +0;160;32;;; +0;160;80;;; +0;176;32;;; +0;176;80;;; +0;192;32;;; +0;192;80;;; +0;208;16;;; +0;208;96;;; +0;224;16;;; +0;224;96;;; +0;240;16;;; +0;240;96;;; +0;256;16;;; +0;256;96;;; +0;272;16;;; +0;272;96;;; +0;288;16;;; +0;288;96;;; +0;304;32;;; +0;304;80;;; +0;320;48;;; +0;320;64;;; +286;-24;0;;;; +298;48;48;;;;;; +298;288;48;;;;;; +153;48;48;;;cave9left;overworld.map;cave9left;;1; +153;288;48;;;cave9right;overworld.map;cave9right;;1; +457;112;64 +457;240;48 +457;256;80 +22;80;80;;;; +22;96;64;;;; +22;112;32;;;; +22;112;48;;;; +22;176;48;;;; +22;176;64;;;; +22;256;32;;;; +22;256;48;;;; +22;272;64;;;; +22;288;80;;;; +274;256;32;;;; +274;256;48;;;; +274;272;64;;;; +274;288;80;;;; +307;64;16;;;;; +307;112;16;;;;; +307;224;16;;;;; +307;272;16;;;;; +309;64;96;;;;; +309;112;96;;;;; +309;224;96;;;;; +309;272;96;;;;; +287;-24;24;37 +157;96;80; +157;112;64; +157;112;80; +157;128;32; +157;128;48; +157;128;64; +157;128;80; +157;144;48; +157;144;64; +157;160;48; +157;160;64; +157;176;48; +157;176;64; +157;192;48; +157;208;32; +157;208;48; +157;224;32; +157;224;48; +157;240;32; +157;240;48; +157;240;64; +157;256;64; +157;256;80; +157;272;32; +157;272;80; +157;288;32; +108;96;80;;;;;; +108;112;64;;;;;; +108;112;80;;;;;; +108;128;32;;;;;; +108;128;48;;;;;; +108;128;64;;;;;; +108;128;80;;;;;; +108;144;48;;;;;; +108;144;64;;;;;; +108;160;48;;;;;; +108;160;64;;;;;; +108;176;48;;;;;; +108;176;64;;;;;; +108;192;48;;;;;; +108;208;32;;;;;; +108;208;48;;;;;; +108;224;32;;;;;; +108;224;48;;;;;; +108;240;32;;;;;; +108;240;48;;;;;; +108;240;64;;;;;; +108;256;64;;;;;; +108;256;80;;;;;; +108;272;32;;;;;; +108;272;80;;;;;; +108;288;32;;;;;; +109;192;64;;;;;; +109;208;64;;;;;; +109;208;80;;;;;; +109;224;64;;;;;; +109;224;80;;;;;; +109;240;80;;;;;; +158;192;64 +158;208;64 +158;208;80 +158;224;64 +158;224;80 +158;240;80 diff --git a/bin/Data/Maps/cave9.map.data b/bin/Data/Maps/cave9.map.data new file mode 100644 index 0000000..9c09db6 --- /dev/null +++ b/bin/Data/Maps/cave9.map.data @@ -0,0 +1,10 @@ +22 +8 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;2;2;2;2;2;;;;;;;;;;;;;;; +;;2;;2;2;2;2;;;;;;;;;;2;;2;;; +;;2;2;2;2;2;;;;;;;;;;;;2;2;;; +;;;2;2;2;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/caveBat1.map b/bin/Data/Maps/caveBat1.map new file mode 100644 index 0000000..93c1cf2 --- /dev/null +++ b/bin/Data/Maps/caveBat1.map @@ -0,0 +1,628 @@ +3 +2 +1 +cave.png +14 +10 +3 +,,,,,,,,,,,,,, +,,1,4,4,4,4,4,4,4,4,0,,, +,4,10,63,27,63,63,63,1,4,0,9,4,, +,,1,4,0,64,63,64,5,63,9,0,,, +,,5,63,7,65,25,65,5,63,63,7,,, +,,5,63,7,63,63,63,5,63,14,7,,, +,,5,63,9,4,20,4,10,27,63,7,,, +,,5,,,,,,,,8,2,,, +,,3,6,6,6,6,6,6,6,2,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,0,0,0,0,0,0,0,0,0,0,0,0,, +0,0,3,,,,,,,,,4,0,0, +0,0,,,,,,,,,,,0,0, +0,0,,,,,,,,,,,0,0, +,0,,,,,,,,,,,0,, +,0,,,,,,,,,,,0,, +,0,,,,,,,,,,,0,, +,0,,,,,,,,,,2,0,, +,0,1,,,,,,,,2,0,0,, +,0,0,0,0,0,0,0,0,0,0,0,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +66 +382;0;112; +0;32;64;;; +0;32;80;;; +0;32;96;;; +0;32;112;;; +0;48;48;;; +0;48;128;;; +0;64;64;;; +0;64;128;;; +0;80;64;;; +0;80;128;;; +0;96;64;;; +0;96;128;;; +0;112;64;;; +0;112;128;;; +0;128;48;;; +0;128;64;;; +0;128;128;;; +0;144;32;;; +0;144;128;;; +0;160;48;;; +0;160;112;;; +0;176;64;;; +0;176;80;;; +0;176;96;;; +286;0;80;;;; +298;160;80;;;;;; +28;64;80;;;; +28;64;96;;;; +28;80;96;;;; +28;112;96;;;; +28;128;80;;;; +28;128;96;;;; +153;160;80;;;bc1;overworld.map;bc1;;1; +162;72;80;-18;;8;;;;;; +162;80;96;;18;;8;;;;; +162;112;96;;18;;8;;;;; +162;128;80;18;;8;;;;;; +307;64;16;;;;; +307;128;16;;;;; +309;64;128;;;;; +309;128;128;;;;; +287;0;16;37 +394;96;64;caveBat1_spawned +160;96;96; +230;144;48;;;;;; +230;144;64;;;;;; +230;160;64;;;;;; +246;80;80; +246;96;80; +246;96;96; +246;112;80; +157;48;112; +157;64;112; +157;80;112; +157;96;112; +157;112;112; +157;128;112; +157;144;112; +108;48;112;;;;;; +108;64;112;;;;;; +108;80;112;;;;;; +108;96;112;;;;;; +108;112;112;;;;;; +108;128;112;;;;;; +108;144;112;;;;;; diff --git a/bin/Data/Maps/caveBat1.map.data b/bin/Data/Maps/caveBat1.map.data new file mode 100644 index 0000000..4641476 --- /dev/null +++ b/bin/Data/Maps/caveBat1.map.data @@ -0,0 +1,12 @@ +14 +10 +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/caveBat2.map b/bin/Data/Maps/caveBat2.map new file mode 100644 index 0000000..dffa8f8 --- /dev/null +++ b/bin/Data/Maps/caveBat2.map @@ -0,0 +1,627 @@ +3 +0 +0 +cave.png +14 +10 +3 +,,,,,,,,,,,,,, +,,1,4,4,4,4,4,4,4,4,0,,, +,4,10,63,27,63,63,63,1,4,0,9,4,, +,,1,4,0,64,63,64,5,63,9,0,,, +,,5,63,7,65,25,65,5,63,63,7,,, +,,5,63,7,63,63,63,5,63,14,7,,, +,,5,63,9,4,20,4,10,27,63,7,,, +,,5,,,,,,,,8,2,,, +,,3,6,6,6,6,6,6,6,2,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,0,0,0,0,0,0,0,0,0,0,0,0,, +0,0,3,,,,,,,,,4,0,0, +0,0,,,,,,,,,,,0,0, +0,0,,,,,,,,,,,0,0, +,0,,,,,,,,,,,0,, +,0,,,,,,,,,,,0,, +,0,,,,,,,,,,,0,, +,0,,,,,,,,,,2,0,, +,0,1,,,,,,,,2,0,0,, +,0,0,0,0,0,0,0,0,0,0,0,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +65 +0;32;64;;; +0;32;80;;; +0;32;96;;; +0;32;112;;; +0;48;48;;; +0;48;128;;; +0;64;64;;; +0;64;128;;; +0;80;64;;; +0;80;128;;; +0;96;64;;; +0;96;128;;; +0;112;64;;; +0;112;128;;; +0;128;48;;; +0;128;64;;; +0;128;128;;; +0;144;32;;; +0;144;128;;; +0;160;48;;; +0;160;112;;; +0;176;64;;; +0;176;80;;; +0;176;96;;; +286;0;80;;;; +298;160;80;;;;;; +153;160;80;;;bc2;overworld.map;bc2;;1; +162;72;80;-18;;8;;;;;; +162;80;96;;18;;8;;;;; +162;112;96;;18;;8;;;;; +162;128;80;18;;8;;;;;; +307;64;16;;;;; +307;128;16;;;;; +309;64;128;;;;; +309;128;128;;;;; +25;64;80;;;; +25;64;96;;;; +25;80;96;;;; +25;112;96;;;; +25;128;80;;;; +25;128;96;;;; +287;0;16;37 +394;96;64;caveBat2_spawned +160;96;96; +230;144;48;;;;;; +230;144;64;;;;;; +230;160;64;;;;;; +246;80;80; +246;96;80; +246;96;96; +246;112;80; +157;48;112; +157;64;112; +157;80;112; +157;96;112; +157;112;112; +157;128;112; +157;144;112; +108;48;112;;;;;; +108;64;112;;;;;; +108;80;112;;;;;; +108;96;112;;;;;; +108;112;112;;;;;; +108;128;112;;;;;; +108;144;112;;;;;; diff --git a/bin/Data/Maps/caveBat2.map.data b/bin/Data/Maps/caveBat2.map.data new file mode 100644 index 0000000..4641476 --- /dev/null +++ b/bin/Data/Maps/caveBat2.map.data @@ -0,0 +1,12 @@ +14 +10 +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/caveBat3.map b/bin/Data/Maps/caveBat3.map new file mode 100644 index 0000000..f2891db --- /dev/null +++ b/bin/Data/Maps/caveBat3.map @@ -0,0 +1,620 @@ +3 +2 +1 +cave.png +14 +10 +3 +,,,,,,,,,,,,,, +,,84,1,4,4,4,4,4,4,0,84,,, +,,1,10,63,63,63,63,63,63,9,0,,, +,4,10,27,63,64,63,64,63,63,63,7,,, +,,1,4,0,65,25,65,1,4,0,9,4,, +,,5,,7,63,63,63,5,27,7,63,,, +,,5,,9,4,20,4,10,63,9,0,,, +,,5,,,,,,63,63,14,7,,, +,,3,6,6,6,6,6,6,6,6,2,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,,,,,,,,,,,,,, +,0,0,0,0,0,0,0,0,0,0,0,0,, +,0,3,,,,,,,,,4,0,, +0,0,,,,,,,,,,,0,, +0,0,,,,,,,,,,,0,0, +0,0,,,,,,,,,,,0,0, +,0,,,,,,,,,,,0,0, +,0,,,,,,,,,,,0,, +,0,,,,,,,,,,,0,, +,0,1,,,,,,,,,2,0,, +,0,0,0,0,0,0,0,0,0,0,0,0,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +58 +0;32;80;;; +0;32;96;;; +0;32;112;;; +0;48;128;;; +0;64;128;;; +0;80;64;;; +0;80;128;;; +0;96;64;;; +0;96;128;;; +0;112;64;;; +0;112;128;;; +0;128;128;;; +0;144;128;;; +0;160;80;;; +0;160;96;;; +0;160;128;;; +0;176;112;;; +286;0;16;;;; +286;0;64;;;; +298;160;112;;;;;; +153;160;112;;;bc3;overworld.map;bc3;;1; +162;72;80;-18;;8;;;;;; +162;80;96;;18;;8;;;;; +162;112;96;;18;;8;;;;; +162;128;80;18;;8;;;;;; +307;64;16;;;;; +307;128;16;;;;; +25;48;64;;;; +25;64;64;;;; +25;64;80;;;; +25;64;96;;;; +25;80;96;;;; +25;112;96;;;; +25;128;64;;;; +25;128;80;;;; +25;128;96;;;; +25;144;64;;;; +287;0;88;37 +394;96;64;caveBat3_spawned +160;96;96; +246;80;80; +246;96;80; +246;96;96; +246;112;80; +157;48;80; +157;48;96; +157;48;112; +157;64;112; +157;80;112; +157;96;112; +157;112;112; +108;48;80;;;;;; +108;48;96;;;;;; +108;48;112;;;;;; +108;64;112;;;;;; +108;80;112;;;;;; +108;96;112;;;;;; +108;112;112;;;;;; diff --git a/bin/Data/Maps/caveBat3.map.data b/bin/Data/Maps/caveBat3.map.data new file mode 100644 index 0000000..4641476 --- /dev/null +++ b/bin/Data/Maps/caveBat3.map.data @@ -0,0 +1,12 @@ +14 +10 +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; +;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/caveFairy1.map b/bin/Data/Maps/caveFairy1.map new file mode 100644 index 0000000..6057c1c --- /dev/null +++ b/bin/Data/Maps/caveFairy1.map @@ -0,0 +1,634 @@ +3 +1 +1 +cave.png +12 +10 +3 +,,,,,,,,,,,, +,,39,47,47,47,47,47,47,37,,, +,39,67,30,39,47,47,37,35,68,37,, +,45,63,30,45,,,44,35,63,44,, +,45,63,30,36,46,46,38,35,63,44,, +,45,63,63,29,29,29,29,63,63,44,, +,45,63,63,63,63,63,63,63,63,44,, +,36,71,63,63,63,63,63,63,69,38,, +,,36,46,46,16,15,46,46,38,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,0,0,0,0,0,0,0,0,0,0,, +0,0,3,,,,,,,4,0,0, +0,3,,,,,,,,,4,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,1,,,,,,,,,2,0, +0,0,1,,,,,,,2,0,0, +,0,0,0,0,,,0,0,0,0,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +72 +382;-16;80; +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;32;32;;; +0;32;112;;; +0;48;16;;; +0;48;128;;; +0;64;16;;; +0;64;128;;; +0;80;16;;; +0;88;144;;; +0;96;16;;; +0;112;16;;; +0;112;128;;; +0;128;16;;; +0;128;128;;; +0;144;32;;; +0;144;112;;; +0;160;48;;; +0;160;64;;; +0;160;80;;; +0;160;96;;; +3;80;128;;; +4;96;128;;; +286;-16;16;;;; +54;48;72;;;;;; +54;128;72;;;;;; +298;88;128;;;;;; +28;64;32;;;; +28;80;32;;;; +28;96;32;;;; +28;112;32;;;; +153;88;136;;;fc1;overworld.map;fc1;1;; +393;88;44; +297;88;40;124;;;;125; +11;64;80;;; +11;80;80;;; +11;96;80;;; +11;112;80;;; +12;128;32;;; +12;128;48;;; +12;128;64;;; +13;48;32;;; +13;48;48;;; +13;48;64;;; +287;-16;48;37 +246;48;80; +246;48;96; +246;48;112; +246;64;80; +246;64;96; +246;64;112; +246;80;80; +246;80;96; +246;80;112; +246;80;128; +246;96;80; +246;96;96; +246;96;112; +246;96;128; +246;112;80; +246;112;96; +246;112;112; +246;128;80; +246;128;96; +246;128;112; +157;80;48; +157;96;48; +108;80;48;;;;;; +108;96;48;;;;;; diff --git a/bin/Data/Maps/caveFairy1.map.data b/bin/Data/Maps/caveFairy1.map.data new file mode 100644 index 0000000..966622a --- /dev/null +++ b/bin/Data/Maps/caveFairy1.map.data @@ -0,0 +1,12 @@ +12 +10 +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; diff --git a/bin/Data/Maps/caveFairy2.map b/bin/Data/Maps/caveFairy2.map new file mode 100644 index 0000000..314d640 --- /dev/null +++ b/bin/Data/Maps/caveFairy2.map @@ -0,0 +1,634 @@ +3 +1 +1 +cave.png +12 +10 +3 +,,,,,,,,,,,, +,,39,47,47,47,47,47,47,37,,, +,39,67,30,39,47,47,37,35,68,37,, +,45,63,30,45,,,44,35,63,44,, +,45,63,30,36,46,46,38,35,63,44,, +,45,63,63,29,29,29,29,63,63,44,, +,45,63,63,63,63,63,63,63,63,44,, +,36,71,63,63,63,63,63,63,69,38,, +,,36,46,46,16,15,46,46,38,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,0,0,0,0,0,0,0,0,0,0,, +0,0,3,,,,,,,4,0,0, +0,3,,,,,,,,,4,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,1,,,,,,,,,2,0, +0,0,1,,,,,,,2,0,0, +,0,0,0,0,,,0,0,0,0,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +72 +382;-16;80; +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;32;32;;; +0;32;112;;; +0;48;16;;; +0;48;128;;; +0;64;16;;; +0;64;128;;; +0;80;16;;; +0;88;144;;; +0;96;16;;; +0;112;16;;; +0;112;128;;; +0;128;16;;; +0;128;128;;; +0;144;32;;; +0;144;112;;; +0;160;48;;; +0;160;64;;; +0;160;80;;; +0;160;96;;; +3;80;128;;; +4;96;128;;; +286;-16;16;;;; +54;48;72;;;;;; +54;128;72;;;;;; +298;88;128;;;;;; +28;64;32;;;; +28;80;32;;;; +28;96;32;;;; +28;112;32;;;; +153;88;136;;;fc2;overworld.map;fc2;1;; +393;88;44; +297;88;40;124;;;;125; +11;64;80;;; +11;80;80;;; +11;96;80;;; +11;112;80;;; +12;128;32;;; +12;128;48;;; +12;128;64;;; +13;48;32;;; +13;48;48;;; +13;48;64;;; +287;-16;48;37 +246;48;80; +246;48;96; +246;48;112; +246;64;80; +246;64;96; +246;64;112; +246;80;80; +246;80;96; +246;80;112; +246;80;128; +246;96;80; +246;96;96; +246;96;112; +246;96;128; +246;112;80; +246;112;96; +246;112;112; +246;128;80; +246;128;96; +246;128;112; +157;80;48; +157;96;48; +108;80;48;;;;;; +108;96;48;;;;;; diff --git a/bin/Data/Maps/caveFairy2.map.data b/bin/Data/Maps/caveFairy2.map.data new file mode 100644 index 0000000..966622a --- /dev/null +++ b/bin/Data/Maps/caveFairy2.map.data @@ -0,0 +1,12 @@ +12 +10 +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; diff --git a/bin/Data/Maps/caveFairyMountain.map b/bin/Data/Maps/caveFairyMountain.map new file mode 100644 index 0000000..beebdbb --- /dev/null +++ b/bin/Data/Maps/caveFairyMountain.map @@ -0,0 +1,634 @@ +3 +0 +0 +cave.png +12 +10 +3 +,,,,,,,,,,,, +,,39,47,47,47,47,47,47,37,,, +,39,67,30,39,47,47,37,35,68,37,, +,45,63,30,45,,,44,35,63,44,, +,45,63,30,36,46,46,38,35,63,44,, +,45,63,63,29,29,29,29,63,63,44,, +,45,63,63,63,63,63,63,63,63,44,, +,36,71,63,63,63,63,63,63,69,38,, +,,36,46,46,16,15,46,46,38,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,0,0,0,0,0,0,0,0,0,0,, +0,0,3,,,,,,,4,0,0, +0,3,,,,,,,,,4,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,1,,,,,,,,,2,0, +0,0,1,,,,,,,2,0,0, +,0,0,0,0,,,0,0,0,0,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +72 +382;-16;80; +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;32;32;;; +0;32;112;;; +0;48;16;;; +0;48;128;;; +0;64;16;;; +0;64;128;;; +0;80;16;;; +0;88;144;;; +0;96;16;;; +0;112;16;;; +0;112;128;;; +0;128;16;;; +0;128;128;;; +0;144;32;;; +0;144;112;;; +0;160;48;;; +0;160;64;;; +0;160;80;;; +0;160;96;;; +3;80;128;;; +4;96;128;;; +286;-16;16;;;; +54;48;72;;;;;; +54;128;72;;;;;; +298;88;128;;;;;; +28;64;32;;;; +28;80;32;;;; +28;96;32;;;; +28;112;32;;;; +153;88;136;;;fcm;overworld.map;fcm;1;; +393;88;44; +297;88;40;124;;;;125; +11;64;80;;; +11;80;80;;; +11;96;80;;; +11;112;80;;; +12;128;32;;; +12;128;48;;; +12;128;64;;; +13;48;32;;; +13;48;48;;; +13;48;64;;; +287;-16;48;37 +246;48;80; +246;48;96; +246;48;112; +246;64;80; +246;64;96; +246;64;112; +246;80;80; +246;80;96; +246;80;112; +246;80;128; +246;96;80; +246;96;96; +246;96;112; +246;96;128; +246;112;80; +246;112;96; +246;112;112; +246;128;80; +246;128;96; +246;128;112; +157;80;48; +157;96;48; +108;80;48;;;;;; +108;96;48;;;;;; diff --git a/bin/Data/Maps/caveFairyMountain.map.data b/bin/Data/Maps/caveFairyMountain.map.data new file mode 100644 index 0000000..966622a --- /dev/null +++ b/bin/Data/Maps/caveFairyMountain.map.data @@ -0,0 +1,12 @@ +12 +10 +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; diff --git a/bin/Data/Maps/caveFrogs.map b/bin/Data/Maps/caveFrogs.map new file mode 100644 index 0000000..d46ea3d --- /dev/null +++ b/bin/Data/Maps/caveFrogs.map @@ -0,0 +1,613 @@ +3 +0 +0 +cave.png +12 +10 +3 +,,,,,,,,,,,, +,,39,47,47,47,47,47,47,37,,, +,39,67,63,63,63,63,63,63,68,37,, +,45,63,63,63,63,63,63,63,63,44,, +,45,63,63,,,,,63,27,44,, +,45,63,63,,,,,63,63,44,, +,45,63,63,63,,,63,63,63,44,, +,36,71,27,63,63,63,63,63,14,44,, +,,36,46,46,46,46,46,46,46,38,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,0,0,0,0,0,0,0,0,0,0,, +0,0,3,,,,,,,4,0,0, +0,3,,,,,,,,,4,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,1,,,,,,,,,,0, +0,0,1,,,,,,,,2,0, +,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +51 +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;32;32;;; +0;32;112;;; +0;48;16;;; +0;48;128;;; +0;64;16;;; +0;64;128;;; +0;80;16;;; +0;80;128;;; +0;96;16;;; +0;96;128;;; +0;112;16;;; +0;112;128;;; +0;128;16;;; +0;128;128;;; +0;144;32;;; +0;144;128;;; +0;160;48;;; +0;160;64;;; +0;160;80;;; +0;160;96;;; +0;160;112;;; +286;-8;16;;;; +153;144;112;;;caveFrogs;overworld.map;caveFrogs;;1; +307;64;16;;;;; +307;112;16;;;;; +370;80;32;mamu_gone +287;-8;40;37 +157;64;64; +157;64;80; +157;80;64; +157;80;80; +157;80;96; +157;96;64; +157;96;80; +157;96;96; +157;112;64; +157;112;80; +108;64;64;;;;;; +108;64;80;;;;;; +108;80;64;;;;;; +108;80;80;;;;;; +108;80;96;;;;;; +108;96;64;;;;;; +108;96;80;;;;;; +108;96;96;;;;;; +108;112;64;;;;;; +108;112;80;;;;;; diff --git a/bin/Data/Maps/caveFrogs.map.data b/bin/Data/Maps/caveFrogs.map.data new file mode 100644 index 0000000..966622a --- /dev/null +++ b/bin/Data/Maps/caveFrogs.map.data @@ -0,0 +1,12 @@ +12 +10 +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; diff --git a/bin/Data/Maps/caveMirror.map b/bin/Data/Maps/caveMirror.map new file mode 100644 index 0000000..4396fd4 --- /dev/null +++ b/bin/Data/Maps/caveMirror.map @@ -0,0 +1,674 @@ +3 +1 +2 +cave.png +12 +19 +3 +,,,,,,,,,,,, +,,,,44,63,63,45,,,,, +,39,47,37,68,47,47,67,39,47,37,, +,45,63,44,70,63,63,70,45,63,44,, +,45,63,44,70,63,63,70,45,63,44,, +,45,63,68,37,63,63,39,67,63,44,, +,45,70,70,68,20,20,67,70,70,44,, +,45,70,70,70,70,70,70,70,70,44,, +,36,71,70,70,70,70,70,70,69,38,, +,,36,46,71,70,70,69,46,38,,, +,39,47,47,67,70,70,68,47,47,37,, +,45,70,70,70,70,70,70,70,70,44,, +,45,70,70,70,70,70,70,70,70,44,, +,45,70,70,70,70,70,70,70,70,44,, +,45,70,70,70,70,70,63,70,70,44,, +,45,70,70,70,70,63,14,63,70,44,, +,36,71,70,70,70,70,63,70,69,38,, +,,36,46,46,46,46,46,46,38,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,0,0,0,0,0,0,,,, +0,0,0,0,0,0,0,0,0,0,0,0, +0,3,,,,,,,,,4,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,1,,,,,,,,,2,0, +0,0,,,,,,,,,0,0, +0,3,,,,,,,,,4,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,1,,,,,,,,,2,0, +0,0,1,,,,,,,2,0,0, +,0,0,0,0,0,0,0,0,0,0,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +85 +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;16;176;;; +0;16;192;;; +0;16;208;;; +0;16;224;;; +0;16;240;;; +0;32;32;;; +0;32;128;;; +0;32;160;;; +0;32;256;;; +0;48;48;;; +0;48;64;;; +0;48;144;;; +0;48;160;;; +0;48;272;;; +0;64;144;;; +0;64;160;;; +0;64;272;;; +0;80;32;;; +0;80;272;;; +0;96;32;;; +0;96;272;;; +0;112;144;;; +0;112;160;;; +0;112;272;;; +0;128;48;;; +0;128;64;;; +0;128;144;;; +0;128;160;;; +0;128;272;;; +0;144;32;;; +0;144;128;;; +0;144;160;;; +0;144;256;;; +0;160;48;;; +0;160;64;;; +0;160;80;;; +0;160;96;;; +0;160;112;;; +0;160;176;;; +0;160;192;;; +0;160;208;;; +0;160;224;;; +0;160;240;;; +286;-16;32;;;; +153;112;240;;;caveMirror;overworld.map;caveMirror;;1; +299;112;240;;;;;; +463;32;224 +463;96;192 +424;48;192 +424;64;240 +424;144;224 +200;88;64;;magnifyingLensCollected;trade13;; +302;64;48;;;;; +302;64;64;;;;; +302;112;48;;;;; +302;112;64;;;;; +25;48;80;;;; +25;64;80;;;; +25;64;96;;;; +25;112;80;;;; +25;112;96;;;; +25;128;80;;;; +287;-16;64;37 +256;16;160 +160;80;96; +160;96;96; +230;32;48;;heart;;;; +230;32;64;;heart;;;; +230;32;80;;heart;;;; +230;144;48;;heart;;;; +230;144;64;;heart;;;; +230;144;80;;heart;;;; +246;80;48; +246;80;64; +246;80;80; +246;80;96; +246;96;48; +246;96;64; +246;96;80; +246;96;96; diff --git a/bin/Data/Maps/caveMirror.map.data b/bin/Data/Maps/caveMirror.map.data new file mode 100644 index 0000000..1f4a644 --- /dev/null +++ b/bin/Data/Maps/caveMirror.map.data @@ -0,0 +1,21 @@ +12 +19 +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;2;;;2;;;;; +;;;;2;;;2;;;;; +;;;;;;;;;;;; +;;2;2;;;;;2;2;;; +;;2;2;2;2;2;2;2;2;;; +;;;2;2;2;2;2;2;;;; +;;;;;2;2;;;;;; +;;;;;2;2;;;;;; +;;2;2;2;2;2;2;2;2;;; +;;2;2;2;2;2;2;2;2;;; +;;2;2;2;2;2;2;2;2;;; +;;2;2;2;2;2;;2;2;;; +;;2;2;2;2;;;;2;;; +;;;2;2;2;2;;2;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; diff --git a/bin/Data/Maps/caveTemple.map b/bin/Data/Maps/caveTemple.map new file mode 100644 index 0000000..79595b5 --- /dev/null +++ b/bin/Data/Maps/caveTemple.map @@ -0,0 +1,577 @@ +3 +0 +0 +cave.png +9 +8 +3 +,,,,,,,,, +,,39,47,47,47,37,,, +,39,67,70,70,70,68,37,, +,45,70,70,70,70,70,44,, +,45,70,70,70,70,70,44,, +,36,71,70,70,70,14,44,, +,,36,46,46,46,46,38,, +,,,,,,,,, +,,,,,,,,, +,,,,,,,,, +,,,,,,,,, +,,,,,,,,, +,,,,,,,,, +,,,,,,,,, +,,,,,,,,, +,,,,,,,,, +,0,0,0,0,0,0,0,, +0,0,3,,,,4,0,0, +0,3,,,,,,4,0, +0,,,,,,,,0, +0,,,,,,,,0, +0,1,,,,,,,0, +0,0,1,,,,,2,0, +,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +21 +0;16;48;;; +0;16;64;;; +0;32;32;;; +0;32;80;;; +0;48;16;;; +0;48;96;;; +0;64;16;;; +0;64;96;;; +0;80;16;;; +0;80;96;;; +0;96;32;;; +0;96;96;;; +0;112;48;;; +0;112;64;;; +0;112;80;;; +286;0;144;;;; +298;96;80;;;;;; +153;96;80;;;caveTemple;overworld.map;caveTemple;;1; +287;32;144;37 +164;64;48;shellsFound;1;chest;ruby20..shell_21.;False +164;64;48;shellsFound;;chest;shellChest..shell_21.;False diff --git a/bin/Data/Maps/caveTemple.map.data b/bin/Data/Maps/caveTemple.map.data new file mode 100644 index 0000000..b6b97cc --- /dev/null +++ b/bin/Data/Maps/caveTemple.map.data @@ -0,0 +1,10 @@ +9 +8 +;;;;;;;;; +;;;;;;;;; +;;;2;2;2;;;; +;;2;2;2;2;2;;; +;;2;2;2;2;2;;; +;;;2;2;2;;;; +;;;;;;;;; +;;;;;;;;; diff --git a/bin/Data/Maps/caveVillage.map b/bin/Data/Maps/caveVillage.map new file mode 100644 index 0000000..0f1de2a --- /dev/null +++ b/bin/Data/Maps/caveVillage.map @@ -0,0 +1,772 @@ +3 +2 +1 +cave.png +23 +18 +3 +,,,,,,,,,,,,,,,,,,,,,,, +,,39,47,47,47,37,,,,,,,,,,,,,,,,, +,,45,70,70,70,68,47,47,47,47,47,47,47,47,47,47,47,37,,,,, +,,45,70,39,47,47,47,47,47,47,47,47,47,47,47,47,37,68,37,,,, +,47,67,70,45,70,70,70,70,70,70,70,70,70,70,70,70,68,37,44,,,, +,,39,20,67,29,29,69,46,46,46,46,46,46,46,71,70,70,44,44,,,, +,,45,70,70,70,70,68,47,47,47,37,63,81,81,36,71,70,44,44,,,, +,,45,70,63,63,87,87,87,87,70,44,81,63,81,81,45,70,44,68,37,,, +,,36,46,46,46,46,46,46,71,70,44,81,63,81,81,36,83,38,63,44,,, +,,39,47,47,47,47,47,47,67,63,44,81,81,39,47,47,83,47,37,44,,, +,,45,86,86,86,86,86,70,70,70,68,47,47,67,86,86,70,63,44,68,37,, +,,45,86,86,69,71,70,70,70,86,87,87,87,87,70,70,70,70,68,37,44,, +,,45,86,70,68,67,70,69,71,70,88,88,88,89,86,87,87,87,70,44,44,, +,,45,86,70,70,70,70,68,67,70,70,70,70,89,70,88,88,89,70,44,44,, +,,36,71,86,86,70,70,70,70,70,70,70,87,89,70,70,63,88,70,44,44,, +,,,36,46,71,86,86,86,86,86,86,86,88,88,86,63,70,70,69,38,44,, +,,,,,36,46,46,46,46,46,46,46,46,46,46,46,16,15,38,69,38,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,0,0,0,0,0,0,0,,,,,,,,,,,,,,,, +,0,3,,,,4,0,0,0,0,0,0,0,0,0,0,0,0,0,,,, +,0,,,,,,,,,,,,,,,,,4,0,0,,, +0,0,,,,,,,,,,,,,,,,,,4,0,,, +0,0,,,,,,,,,,,,,,,,,,,0,,, +0,0,,,,,,,,,,,,,,,,,,,0,,, +,0,,,,,,,,,,,,,,,,,,,0,0,, +,0,,,,,,,,,,,,,,,,,,,4,0,, +,0,,,,,,,,,,,,,,,,,,,,0,, +,0,,,,,,,,,,,,,,,,,,,,0,0, +,0,,,,,,,,,,,,,,,,,,,,4,0, +,0,,,,,,,,,,,,,,,,,,,,,0, +,0,,,,,,,,,,,,,,,,,,,,,0, +,0,,,,,,,,,,,,,,,,,,,,,0, +,0,1,,,,,,,,,,,,,,,,,,,,0, +,0,0,1,,,,,,,,,,,,,,,,,,,0, +,,0,0,0,1,,,,,,,,,,,,,,,,2,0, +,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,,,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +186 +0;32;32;;; +0;32;48;;; +0;32;64;;; +0;32;80;;; +0;32;96;;; +0;32;112;;; +0;32;160;;; +0;32;176;;; +0;32;192;;; +0;32;208;;; +0;48;16;;; +0;48;128;;; +0;48;144;;; +0;48;224;;; +0;64;16;;; +0;64;48;;; +0;64;64;;; +0;64;80;;; +0;64;128;;; +0;64;144;;; +0;64;240;;; +0;80;16;;; +0;80;48;;; +0;80;128;;; +0;80;144;;; +0;80;176;;; +0;80;192;;; +0;80;240;;; +0;96;32;;; +0;96;48;;; +0;96;128;;; +0;96;144;;; +0;96;176;;; +0;96;192;;; +0;96;256;;; +0;112;48;;; +0;112;80;;; +0;112;96;;; +0;112;128;;; +0;112;144;;; +0;112;256;;; +0;128;48;;; +0;128;80;;; +0;128;96;;; +0;128;128;;; +0;128;144;;; +0;128;192;;; +0;128;208;;; +0;128;256;;; +0;144;48;;; +0;144;80;;; +0;144;96;;; +0;144;128;;; +0;144;144;;; +0;144;192;;; +0;144;208;;; +0;144;256;;; +0;160;48;;; +0;160;80;;; +0;160;96;;; +0;160;256;;; +0;176;48;;; +0;176;80;;; +0;176;96;;; +0;176;112;;; +0;176;128;;; +0;176;144;;; +0;176;160;;; +0;176;256;;; +0;192;48;;; +0;192;80;;; +0;192;160;;; +0;192;256;;; +0;208;48;;; +0;208;80;;; +0;208;160;;; +0;208;256;;; +0;224;48;;; +0;224;80;;; +0;224;144;;; +0;224;160;;; +0;224;256;;; +0;240;48;;; +0;240;80;;; +0;240;96;;; +0;240;144;;; +0;240;256;;; +0;256;48;;; +0;256;96;;; +0;256;112;;; +0;256;128;;; +0;256;144;;; +0;256;256;;; +0;272;48;;; +0;272;64;;; +0;288;64;;; +0;288;80;;; +0;288;96;;; +0;288;112;;; +0;288;128;;; +0;288;144;;; +0;304;144;;; +0;304;160;;; +0;304;176;;; +0;304;240;;; +0;304;256;;; +0;320;176;;; +0;320;192;;; +0;320;208;;; +0;320;224;;; +0;320;240;;; +3;272;256;;; +4;288;256;;; +286;32;288;;;; +275;48;160; +275;48;176; +275;48;192; +275;64;160; +275;64;176; +275;80;160; +275;96;160; +275;112;160; +298;280;256;;;;;; +266;80;112;;village_cave_barrier_stone;;; +268;272;128;;cave_village_wall;1;; +268;272;144;;cave_village_wall;3;; +153;280;264;;;caveVillage;overworld.map;caveVillage;1;; +426;224;48 +426;240;80 +426;272;64 +427;80;204;1;False; +422;80;160 +422;240;176 +423;96;64;; +423;112;64;; +423;128;64;; +341;48;208;;;;;; +341;64;224;;;;;; +341;80;224;;;;;; +341;96;112;;;;;; +341;96;240;;;;;; +341;112;112;;;;;; +341;112;240;;;;;; +341;128;112;;;;;; +341;128;240;;;;;; +341;144;112;;;;;; +341;144;240;;;;;; +341;160;176;;;;;; +341;160;240;;;;;; +341;176;176;;;;;; +341;176;192;;;;;; +341;176;240;;;;;; +341;192;176;;;;;; +341;192;192;;;;;; +341;192;240;;;;;; +341;208;176;;;;;; +341;208;192;;;;;; +341;208;224;;;;;; +341;208;240;;;;;; +341;224;176;;;;;; +341;224;192;;;;;; +341;224;208;;;;;; +341;224;224;;;;;; +341;224;240;;;;;; +341;240;160;;;;;; +341;240;192;;;;;; +341;240;240;;;;;; +341;256;160;;;;;; +341;256;192;;;;;; +341;256;208;;;;;; +341;272;192;;;;;; +341;272;208;;;;;; +341;288;192;;;;;; +341;288;208;;;;;; +341;288;224;;;;;; +200;80;32;;caveVillage_heartMeter;heartMeter;; +162;64;64;18;;8;;;;;; +162;80;48;;18;;8;;;;; +11;80;80;;; +11;96;80;;; +224;64;112;;;;;;;; +224;256;240;;;;;;;; +224;272;224;;;;;;;; +224;288;160;;;;;;;; +287;0;288;37 +160;48;80; diff --git a/bin/Data/Maps/caveVillage.map.data b/bin/Data/Maps/caveVillage.map.data new file mode 100644 index 0000000..42fa484 --- /dev/null +++ b/bin/Data/Maps/caveVillage.map.data @@ -0,0 +1,20 @@ +23 +18 +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; +;;;2;2;2;;;;;;;;;;;;;;;;;; +;;;2;;;;;;;;;;;;;;;;;;;; +;;;2;;2;2;2;2;2;2;2;2;2;2;2;2;;;;;;; +;;;;;;;;;;;;;;;;2;2;;;;;; +;;;2;2;2;2;;;;;;;;;;;2;;;;;; +;;;2;;;;;;;2;;;;;;;2;;;;;; +;;;;;;;;;;2;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;2;2;2;;;;;;;2;;;;;; +;;;;;;;2;2;2;;;;;;2;2;2;2;;;;; +;;;;2;;;2;;;2;;;;;;;;;2;;;; +;;;;2;2;2;2;;;2;2;2;2;;2;;;;2;;;; +;;;;;;2;2;2;2;2;2;2;;;2;2;;;2;;;; +;;;;;;;;;;;;;;;;;2;2;;;;; +;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/desertTemple.map b/bin/Data/Maps/desertTemple.map new file mode 100644 index 0000000..4231953 --- /dev/null +++ b/bin/Data/Maps/desertTemple.map @@ -0,0 +1,775 @@ +3 +1 +1 +desertTempleTileset.png +12 +26 +3 +,,,,,,,,,,,, +,,,1,2,3,4,2,5,,,, +,,1,6,7,7,7,7,8,5,,, +,,9,7,7,7,7,7,7,10,,, +,1,6,1,2,11,11,2,5,8,5,, +,9,1,6,7,7,7,7,8,5,10,, +,9,9,7,7,7,7,7,7,10,10,, +,9,9,7,7,7,7,7,7,10,10,, +,9,13,14,14,15,16,14,14,17,10,, +,9,1,2,2,19,20,2,2,5,10,, +,9,9,7,7,7,7,7,7,10,10,, +,9,9,7,7,7,7,7,7,10,10,, +,9,9,7,7,7,7,7,7,10,10,, +,9,9,7,7,7,7,7,7,10,10,, +,9,9,7,7,7,7,7,7,10,10,, +,9,13,23,7,7,7,7,24,17,10,, +,9,25,13,14,15,16,14,17,25,10,, +,9,25,1,2,19,20,2,5,25,10,, +,9,25,9,7,7,7,7,10,25,10,, +,9,25,9,7,7,7,7,10,25,10,, +,9,25,13,14,11,11,14,17,25,10,, +,9,25,25,25,25,25,25,25,25,10,, +,9,25,25,27,28,28,29,25,25,10,, +,9,25,25,30,31,32,33,25,25,10,, +,13,14,14,34,35,36,37,14,14,17,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,0,0,0,0,0,0,0,0,,, +,0,0,,,,,,,0,0,, +,0,,,,,,,,,0,, +0,0,,,,,,,,,0,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,0,0,0,0,,,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +165 +0;16;256;;; +0;16;272;;; +0;16;288;;; +0;16;304;;; +0;16;320;;; +0;16;336;;; +0;16;352;;; +0;16;368;;; +0;32;48;;; +0;32;64;;; +0;32;80;;; +0;32;96;;; +0;32;112;;; +0;32;160;;; +0;32;176;;; +0;32;192;;; +0;32;208;;; +0;32;224;;; +0;32;240;;; +0;32;384;;; +0;48;32;;; +0;48;128;;; +0;48;144;;; +0;48;240;;; +0;48;256;;; +0;48;272;;; +0;48;384;;; +0;64;16;;; +0;64;128;;; +0;64;144;;; +0;64;256;;; +0;64;272;;; +0;64;384;;; +0;80;16;;; +0;96;16;;; +0;112;16;;; +0;112;128;;; +0;112;144;;; +0;112;256;;; +0;112;272;;; +0;112;384;;; +0;128;32;;; +0;128;128;;; +0;128;144;;; +0;128;240;;; +0;128;256;;; +0;128;272;;; +0;128;384;;; +0;144;48;;; +0;144;64;;; +0;144;80;;; +0;144;96;;; +0;144;112;;; +0;144;160;;; +0;144;176;;; +0;144;192;;; +0;144;208;;; +0;144;224;;; +0;144;240;;; +0;144;384;;; +0;160;256;;; +0;160;272;;; +0;160;288;;; +0;160;304;;; +0;160;320;;; +0;160;336;;; +0;160;352;;; +0;160;368;;; +1;72;368;;; +1;104;368;;; +3;80;128;;; +3;80;144;;; +3;80;256;;; +3;80;272;;; +3;80;384;;; +4;96;128;;; +4;96;144;;; +4;96;256;;; +4;96;272;;; +4;96;384;;; +286;16;416;;;; +261;88;128;;dt_door;1; +261;88;144;;dt_door;3; +261;88;256;;dt_door;1; +261;88;272;;dt_door;3; +153;88;392;;;desertTemple;overworld.map;desertTemple;1;; +162;64;64;;18;;8;;;;; +162;64;328;;-18;;8;;;;; +162;112;64;;18;;8;;;;; +162;112;328;;-18;;8;;;;; +168;88;-8;dt_light;dt_lamp_0&dt_lamp_1; +168;184;136;dt_door;!dt_enter|dt_armosKnight; +167;208;136;dt_enter;0 +302;48;336;;;;; +302;48;352;;;;; +302;48;368;;;;; +302;64;96;;;;True;dt_lamp_0 +302;112;96;;;;True;dt_lamp_1 +302;128;336;;;;; +302;128;352;;;;; +302;128;368;;;;; +315;64;144;;;;; +315;112;144;;;;; +316;144;192;;;;; +316;144;224;;;;; +316;160;176;;;;; +316;160;240;;;;; +318;16;176;;;;; +318;16;240;;;;; +318;32;192;;;;; +318;32;224;;;;; +170;88;256;dt_enter;1;;; +25;48;64;;;; +25;48;80;;;; +25;48;288;;;; +25;48;304;;;; +25;48;320;;;; +25;64;64;;;; +25;64;320;;;; +25;112;64;;;; +25;112;320;;;; +25;128;64;;;; +25;128;80;;;; +25;128;288;;;; +25;128;304;;;; +25;128;320;;;; +504;80;184;dt_armosKnight +287;48;416;30 +164;88;16;dt_light;0;sign;shrine_dark; +164;88;16;dt_light;1;sign;shrine_message; +231;64;336;;arrow_1;;;; +231;112;336;;arrow_1;;;; +249;16;16;0.6;0.1 +160;80;64; +160;80;320; +160;96;64; +160;96;320; +246;48;48; +246;64;32; +246;64;48; +246;64;336; +246;64;352; +246;64;368; +246;80;32; +246;80;48; +246;80;64; +246;80;320; +246;80;336; +246;80;352; +246;80;368; +246;80;384; +246;96;32; +246;96;48; +246;96;64; +246;96;320; +246;96;336; +246;96;352; +246;96;368; +246;96;384; +246;112;32; +246;112;48; +246;112;336; +246;112;352; +246;112;368; +246;128;48; diff --git a/bin/Data/Maps/desertTemple.map.data b/bin/Data/Maps/desertTemple.map.data new file mode 100644 index 0000000..e40f74e --- /dev/null +++ b/bin/Data/Maps/desertTemple.map.data @@ -0,0 +1,28 @@ +12 +26 +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; diff --git a/bin/Data/Maps/dreamShrine01.map b/bin/Data/Maps/dreamShrine01.map new file mode 100644 index 0000000..999ac67 --- /dev/null +++ b/bin/Data/Maps/dreamShrine01.map @@ -0,0 +1,628 @@ +3 +0 +0 +dreamShrineTileset.png +10 +8 +3 +18,26,26,26,26,26,26,26,26,19, +25,0,0,0,0,0,0,0,0,24, +25,0,29,23,23,23,23,28,0,24, +25,0,24,9,13,6,10,25,0,24, +25,0,24,11,22,1,8,25,0,24, +25,0,30,26,7,26,26,27,0,24, +25,0,0,0,0,0,0,0,0,24, +17,23,23,23,5,4,23,23,23,16, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +72 +242;80;48;dreamShrine02.map;ds_lamp_ +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;0;64;;; +0;0;80;;; +0;0;96;;; +0;16;0;;; +0;16;112;;; +0;32;0;;; +0;32;112;;; +0;48;0;;; +0;48;112;;; +0;64;0;;; +0;72;128;;; +0;80;0;;; +0;96;0;;; +0;96;112;;; +0;112;0;;; +0;112;112;;; +0;128;0;;; +0;128;112;;; +0;144;16;;; +0;144;32;;; +0;144;48;;; +0;144;64;;; +0;144;80;;; +0;144;96;;; +19;96;48;;; +20;48;64;;; +21;96;64;;; +3;64;112;;; +4;80;112;;; +18;48;48;;; +153;64;64;;;bed;dreamShrine02.map;;3;4;False +153;72;120;;;dreamShrine01;overworld.map;dreamShrine01;1;; +299;72;112;;;;;; +285;0;144;;;; +167;-16;16;ds_lamp_1;1 +167;-16;96;ds_lamp_4;1 +167;160;16;ds_lamp_2;1 +167;160;96;ds_lamp_3;1 +302;16;16;;;;;ds_lamp_1 +302;16;96;;;;;ds_lamp_4 +302;128;16;;;;;ds_lamp_2 +302;128;96;;;;;ds_lamp_3 +11;64;48;;; +9;80;48;;; +9;80;64;;; +25;32;32;;;; +25;32;48;;;; +25;32;64;;;; +25;32;80;;;; +25;48;32;;;; +25;48;80;;;; +25;64;32;;;; +25;80;32;;;; +25;80;80;;;; +25;96;32;;;; +25;96;80;;;; +25;112;32;;;; +25;112;48;;;; +25;112;64;;;; +25;112;80;;;; +361;0;176 +287;32;144;35 +160;64;80; +246;48;48; +246;48;64; +246;64;48; +246;64;64; +246;64;80; diff --git a/bin/Data/Maps/dreamShrine01.map.data b/bin/Data/Maps/dreamShrine01.map.data new file mode 100644 index 0000000..c90cdd4 --- /dev/null +++ b/bin/Data/Maps/dreamShrine01.map.data @@ -0,0 +1,10 @@ +10 +8 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/dreamShrine02.map b/bin/Data/Maps/dreamShrine02.map new file mode 100644 index 0000000..da3a704 --- /dev/null +++ b/bin/Data/Maps/dreamShrine02.map @@ -0,0 +1,948 @@ +3 +0 +0 +dreamShrineTileset.png +20 +16 +3 +18,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,19, +25,22,22,31,22,22,22,22,22,22,22,31,31,31,31,31,31,22,22,24, +25,22,29,23,23,23,23,23,23,23,23,23,23,23,23,23,23,28,22,24, +25,31,24,9,13,29,23,23,23,23,23,23,23,23,28,13,10,25,31,24, +25,31,24,15,22,24,0,13,13,10,9,13,13,0,25,22,12,25,31,24, +25,31,24,15,22,24,15,0,0,12,15,0,0,12,25,22,12,25,31,24, +25,31,24,15,22,24,15,0,0,12,15,0,0,12,25,22,12,25,31,24, +25,22,24,15,22,24,15,0,0,12,15,0,0,12,25,22,12,25,22,24, +25,22,24,15,22,24,15,0,0,12,15,0,0,12,25,22,12,25,22,24, +25,31,24,15,22,24,0,14,22,8,11,22,14,0,25,22,12,25,31,24, +25,31,24,15,22,30,26,26,7,26,26,7,26,26,27,22,12,25,31,24, +25,31,24,15,22,22,22,22,22,12,15,22,22,22,22,22,12,25,31,24, +25,31,24,11,20,21,14,22,14,8,11,14,22,14,14,14,8,25,31,24, +25,22,30,26,26,26,26,7,26,26,26,26,7,26,26,26,26,27,22,24, +25,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,24, +17,23,23,23,3,2,23,23,23,23,23,23,23,23,23,23,23,23,23,16, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +368 +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;0;64;;; +0;0;80;;; +0;0;96;;; +0;0;112;;; +0;0;128;;; +0;0;144;;; +0;0;160;;; +0;0;176;;; +0;0;192;;; +0;0;208;;; +0;0;224;;; +0;16;0;;; +0;16;240;;; +0;32;0;;; +0;32;240;;; +0;48;0;;; +0;48;240;;; +0;64;0;;; +0;72;256;;; +0;80;0;;; +0;96;0;;; +0;96;240;;; +0;112;0;;; +0;112;240;;; +0;128;0;;; +0;128;240;;; +0;144;0;;; +0;144;240;;; +0;160;0;;; +0;160;240;;; +0;176;0;;; +0;176;240;;; +0;192;0;;; +0;192;240;;; +0;208;0;;; +0;208;240;;; +0;224;0;;; +0;224;240;;; +0;240;0;;; +0;240;240;;; +0;256;0;;; +0;256;240;;; +0;272;0;;; +0;272;240;;; +0;288;0;;; +0;288;240;;; +0;304;16;;; +0;304;32;;; +0;304;48;;; +0;304;64;;; +0;304;80;;; +0;304;96;;; +0;304;112;;; +0;304;128;;; +0;304;144;;; +0;304;160;;; +0;304;176;;; +0;304;192;;; +0;304;208;;; +0;304;224;;; +19;144;64;;; +19;256;48;;; +20;48;192;;; +20;160;144;;; +20;160;192;;; +21;144;144;;; +21;144;192;;; +21;256;192;;; +3;64;240;;; +4;80;240;;; +16;64;192;;; +17;80;192;;; +18;48;48;;; +18;160;64;;; +277;16;48; +277;16;64; +277;16;80; +277;16;96; +277;16;144; +277;16;160; +277;16;176; +277;16;192; +277;48;16; +277;176;16; +277;192;16; +277;208;16; +277;224;16; +277;240;16; +277;256;16; +277;288;48; +277;288;64; +277;288;80; +277;288;96; +277;288;144; +277;288;160; +277;288;176; +277;288;192; +199;128;96;ocarina;;shrine_ocarina;; +199;176;96;ruby100;;shrine_r100;; +28;80;48;;;; +28;80;64;;;; +28;80;80;;;; +28;80;96;;;; +28;80;112;;;; +28;80;128;;;; +28;80;144;;;; +28;80;160;;;; +28;96;48;;;; +28;96;160;;;; +28;112;48;;;; +28;112;160;;;; +28;128;48;;;; +28;144;48;;;; +28;144;160;;;; +28;160;48;;;; +28;160;160;;;; +28;176;48;;;; +28;192;48;;;; +28;192;160;;;; +28;208;48;;;; +28;208;160;;;; +28;224;48;;;; +28;224;64;;;; +28;224;80;;;; +28;224;96;;;; +28;224;112;;;; +28;224;128;;;; +28;224;144;;;; +28;224;160;;;; +153;72;238;;;bed;dreamShrine01.map;;1;4;False +153;72;248;;;;dreamShrine01.map;bed;1;;False +463;16;48 +463;16;80 +463;16;192 +463;64;16 +463;112;16 +463;208;16 +463;224;16 +463;240;16 +463;288;32 +463;288;64 +463;288;144 +463;288;160 +463;288;176 +463;288;192 +274;176;224;;;; +285;0;264;;;; +162;72;208;;18;;8;;;;; +302;96;64;;;;; +302;96;144;;;;; +302;96;224;;;;; +302;208;64;;;;; +302;208;144;;;;; +309;48;240;;;;; +309;96;240;;;;; +10;96;192;;; +10;112;144;;; +10;128;192;;; +10;176;192;;; +10;192;144;;; +10;208;192;;; +10;224;192;;; +10;240;192;;; +11;64;48;;; +11;112;64;;; +11;128;64;;; +11;176;64;;; +11;192;64;;; +11;240;48;;; +12;48;64;;; +12;48;80;;; +12;48;96;;; +12;48;112;;; +12;48;128;;; +12;48;144;;; +12;48;160;;; +12;48;176;;; +12;96;80;;; +12;96;96;;; +12;96;112;;; +12;96;128;;; +12;160;80;;; +12;160;96;;; +12;160;112;;; +12;160;128;;; +12;160;176;;; +13;144;80;;; +13;144;96;;; +13;144;112;;; +13;144;128;;; +13;144;176;;; +13;208;80;;; +13;208;96;;; +13;208;112;;; +13;208;128;;; +13;256;64;;; +13;256;80;;; +13;256;96;;; +13;256;112;;; +13;256;128;;; +13;256;144;;; +13;256;160;;; +13;256;176;;; +25;32;32;;;; +25;32;48;;;; +25;32;64;;;; +25;32;80;;;; +25;32;96;;;; +25;32;112;;;; +25;32;128;;;; +25;32;144;;;; +25;32;160;;;; +25;32;176;;;; +25;32;192;;;; +25;32;208;;;; +25;48;32;;;; +25;48;208;;;; +25;64;32;;;; +25;64;208;;;; +25;80;32;;;; +25;80;208;;;; +25;96;32;;;; +25;96;208;;;; +25;112;32;;;; +25;128;32;;;; +25;128;208;;;; +25;144;32;;;; +25;144;208;;;; +25;160;32;;;; +25;160;208;;;; +25;176;32;;;; +25;176;208;;;; +25;192;32;;;; +25;208;32;;;; +25;208;208;;;; +25;224;32;;;; +25;224;208;;;; +25;240;32;;;; +25;240;208;;;; +25;256;32;;;; +25;256;208;;;; +25;272;32;;;; +25;272;48;;;; +25;272;64;;;; +25;272;80;;;; +25;272;96;;;; +25;272;112;;;; +25;272;128;;;; +25;272;144;;;; +25;272;160;;;; +25;272;176;;;; +25;272;192;;;; +25;272;208;;;; +361;0;288 +287;24;264;82 +160;112;208; +160;128;160; +160;176;160; +160;192;208; +246;48;48; +246;48;64; +246;48;80; +246;48;96; +246;48;112; +246;48;128; +246;48;144; +246;48;160; +246;48;176; +246;48;192; +246;64;48; +246;64;64; +246;64;80; +246;64;96; +246;64;112; +246;64;128; +246;64;144; +246;64;160; +246;64;176; +246;64;192; +246;80;176; +246;80;192; +246;96;176; +246;96;192; +246;112;176; +246;112;192; +246;112;208; +246;128;176; +246;128;192; +246;144;176; +246;144;192; +246;160;176; +246;160;192; +246;176;176; +246;176;192; +246;192;176; +246;192;192; +246;192;208; +246;208;176; +246;208;192; +246;224;176; +246;224;192; +246;240;48; +246;240;64; +246;240;80; +246;240;96; +246;240;112; +246;240;128; +246;240;144; +246;240;160; +246;240;176; +246;240;192; +246;256;48; +246;256;64; +246;256;80; +246;256;96; +246;256;112; +246;256;128; +246;256;144; +246;256;160; +246;256;176; +246;256;192; +247;96;80; +247;96;96; +247;96;112; +247;96;128; +247;112;64; +247;112;80; +247;112;96; +247;112;112; +247;112;128; +247;112;144; +247;128;64; +247;128;80; +247;128;112; +247;128;128; +247;128;144; +247;128;160; +247;144;64; +247;144;80; +247;144;96; +247;144;112; +247;144;128; +247;144;144; +247;160;64; +247;160;80; +247;160;96; +247;160;112; +247;160;128; +247;160;144; +247;176;64; +247;176;80; +247;176;112; +247;176;128; +247;176;144; +247;176;160; +247;192;64; +247;192;80; +247;192;96; +247;192;112; +247;192;128; +247;192;144; +247;208;80; +247;208;96; +247;208;112; +247;208;128; diff --git a/bin/Data/Maps/dreamShrine02.map.data b/bin/Data/Maps/dreamShrine02.map.data new file mode 100644 index 0000000..c56ac4a --- /dev/null +++ b/bin/Data/Maps/dreamShrine02.map.data @@ -0,0 +1,18 @@ +20 +16 +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon 7_2d.map.data b/bin/Data/Maps/dungeon 7_2d.map.data new file mode 100644 index 0000000..ac712ae --- /dev/null +++ b/bin/Data/Maps/dungeon 7_2d.map.data @@ -0,0 +1,18 @@ +10 +16 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon1.map b/bin/Data/Maps/dungeon1.map new file mode 100644 index 0000000..a187228 --- /dev/null +++ b/bin/Data/Maps/dungeon1.map @@ -0,0 +1,1798 @@ +3 +1 +2 +dungeon 1.png +72 +51 +3 +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,43,13,13,44,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,40,42,39,48,42,42,46,40,42,39,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,44,0,43,24,24,24,24,44,0,43,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,44,0,43,24,24,24,24,44,0,43,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,44,0,43,24,24,24,24,44,0,43,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,44,0,48,42,8,8,42,46,0,43,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,44,0,0,0,24,24,0,0,0,43,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,44,0,0,0,24,24,0,0,0,43,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,37,41,41,41,19,14,41,41,41,38,, +,,,,,,,,,,,40,42,42,42,42,42,42,42,42,39,40,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,39,,,,,,,,,,,,,,,,,,,,,40,42,42,42,20,15,42,42,42,39,, +,,,,,,,,,,,44,0,0,49,0,0,49,0,0,43,44,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,43,,,,,,,,,,,,,,,,,,,,,44,53,51,24,24,24,24,51,53,43,, +,,,,,,,,,,,44,0,49,0,0,0,0,49,0,21,18,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,0,43,,,,,,,,,,,,,,,,,,,,,44,53,24,24,24,24,24,24,53,43,, +,,,,,,,,,,,44,0,0,0,0,0,0,0,0,16,17,24,0,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,0,43,,,,,,,,,,,,,,,,,,,,,44,53,24,24,24,24,24,24,53,43,, +,,,,,,,,,,,44,0,0,0,0,0,0,0,0,43,44,0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,24,24,0,43,,,,,,,,,,,,,,,,,,,,,44,53,24,24,24,24,24,24,53,43,, +,,,,,,,,,,,44,0,0,0,0,0,0,0,0,43,44,11,49,49,11,11,11,11,11,11,11,11,11,24,0,0,24,24,0,43,,,,,,,,,,,,,,,,,,,,,44,53,24,24,24,24,24,24,53,43,, +,,,,,,,,,,,37,45,0,0,0,0,0,0,47,38,44,0,0,0,24,24,24,24,24,24,24,24,24,24,24,24,24,24,0,43,,,,,,,,,,,,,,,,,,,,,44,53,50,24,24,24,24,50,53,43,, +,,,,,,,,,,,,37,41,41,41,41,41,41,38,,37,41,41,41,19,14,41,41,41,41,41,41,41,41,41,41,41,41,41,38,,,,,,,,,,,,,,,,,,,,,37,41,41,41,19,14,41,41,41,38,, +,40,42,42,42,42,42,42,42,42,39,,,,,,,,,,,,,40,42,20,15,42,39,30,11,11,11,11,11,11,11,11,11,11,11,11,11,11,26,40,42,42,42,39,,,40,42,42,42,42,42,42,39,,40,42,42,42,20,15,42,42,42,39,, +,44,55,0,24,24,24,0,55,55,43,,,,,,,,,,,,40,46,0,0,0,52,43,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,44,0,0,0,48,39,40,46,35,35,35,35,35,35,48,39,44,0,0,0,0,0,0,0,0,43,, +,44,55,0,24,24,24,0,55,55,43,,,,,,,,,,,40,46,49,0,0,0,55,43,12,0,0,4,10,10,10,10,10,5,0,0,0,0,0,9,44,0,0,0,0,43,44,35,35,35,35,35,35,35,35,43,44,0,0,0,0,0,0,0,0,43,, +,44,55,0,24,24,24,0,55,55,43,,,,,,,,,,,44,0,0,0,0,49,55,43,27,10,10,28,40,42,42,42,39,27,10,10,10,10,0,28,44,0,0,0,0,43,44,35,35,35,35,35,35,35,35,43,44,0,0,0,0,29,0,0,0,43,, +,44,54,49,49,0,49,49,54,54,43,,,,,,,,,,,44,0,36,0,0,0,55,48,42,42,42,42,46,55,54,55,48,42,42,39,40,42,8,42,46,52,0,0,0,43,44,35,35,35,35,35,35,35,35,43,44,0,0,0,0,0,0,0,0,43,, +,44,0,0,0,0,0,0,0,0,43,,,,,,,,,,,44,0,0,0,0,0,54,54,54,54,54,54,54,54,0,54,54,54,54,43,44,0,0,0,0,55,0,0,0,43,44,35,35,35,35,35,35,35,35,43,44,0,0,0,0,0,0,0,0,43,, +,44,0,0,0,0,0,0,0,0,43,,,,,,,,,,,44,0,0,0,0,0,0,0,47,41,41,45,0,0,0,0,0,0,0,43,44,0,0,0,0,54,0,0,0,43,37,45,35,35,35,35,35,35,47,38,44,0,0,0,0,0,0,0,0,43,, +,37,41,41,45,0,47,41,41,41,38,,,,,,,,,,,44,0,0,0,0,0,0,0,43,,,44,0,0,0,0,0,0,0,43,37,41,41,41,41,41,45,0,47,38,13,37,41,45,0,0,47,41,38,13,37,41,41,41,19,14,41,41,41,38,, +,,,,44,0,43,,,,,,,40,42,42,42,42,42,42,39,44,0,0,0,0,0,0,0,43,,,44,0,0,0,0,0,0,0,43,40,42,42,42,42,42,46,0,48,39,40,42,42,46,0,0,48,42,42,39,40,42,42,42,20,15,42,42,42,39,, +,,,,44,0,43,,,,,,40,46,55,54,54,54,55,55,43,44,0,0,0,0,0,0,0,48,42,42,46,0,24,24,24,0,0,0,48,46,0,0,0,0,0,0,0,0,43,44,0,0,0,0,0,0,0,0,43,44,24,24,24,24,24,24,24,24,43,, +,,,,44,0,43,,,,,,44,55,54,24,24,24,54,54,43,44,0,0,0,0,0,0,0,0,0,0,0,0,24,24,24,0,24,0,0,0,0,0,0,0,0,0,0,0,43,44,0,0,0,0,0,0,52,49,43,44,24,24,24,24,24,24,24,24,43,, +,,,,44,0,43,,,,,,44,55,24,24,24,24,24,24,2,2,0,52,0,0,0,0,52,0,0,0,0,0,24,24,24,0,0,0,0,0,0,0,0,0,0,0,0,0,21,18,0,0,47,41,45,0,55,0,21,18,24,24,24,24,24,24,24,24,43,, +,,,,44,0,43,,,,,,44,55,24,24,24,24,24,24,43,44,0,54,0,0,0,0,54,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,17,0,0,48,42,46,0,55,0,16,17,24,24,24,24,24,24,24,24,43,, +,,,,44,0,43,,,,,,44,55,52,24,24,24,52,52,43,44,52,0,0,0,0,0,0,0,0,0,0,0,0,24,0,0,24,0,0,0,0,0,0,0,0,0,0,0,43,44,0,0,0,0,0,0,54,49,43,44,24,24,24,24,24,24,24,24,43,, +,,,,44,0,43,,,,,,37,45,55,52,52,52,55,55,43,44,55,52,52,0,0,52,52,52,0,0,0,0,0,0,0,0,0,0,47,45,0,0,0,0,0,0,0,0,43,44,0,0,0,0,0,0,0,0,43,44,24,24,24,24,24,24,24,24,43,, +,,,,44,0,43,,,,,,,37,41,41,41,41,41,41,38,37,41,41,41,19,14,41,41,41,41,41,41,41,41,41,41,41,41,41,38,37,41,41,41,19,14,41,41,41,38,37,41,41,41,41,41,41,41,41,38,37,41,41,41,41,41,41,41,41,38,, +,,,,44,0,43,,,,,,,,,,,,,,,,40,42,42,20,15,42,42,39,13,40,42,42,42,42,42,42,42,42,39,40,42,42,42,20,15,42,42,42,39,,,,,,,,,,,,,,,,,,,,,, +,,,,44,0,43,,,,,,,,,,,,,,,40,46,49,49,0,0,49,49,48,39,44,0,0,0,0,0,0,0,0,43,44,55,0,24,24,24,24,0,0,43,,,,,,,,,,,,,,,,,,,,,, +,,,,44,0,43,,,,,,,,,,,,,,,44,52,0,0,0,0,0,0,49,43,44,0,0,52,0,0,52,0,0,48,46,54,0,24,24,24,24,0,0,43,,,,,,,,,,,,,,,,,,,,,, +,,40,42,46,0,48,42,39,,,,,,,,,,,,,44,55,0,0,0,0,0,0,0,21,18,0,0,55,0,0,55,0,0,0,0,0,0,24,24,24,24,0,0,43,,,,,,,,,,,,,,,,,,,,,, +,,44,0,0,0,0,0,43,,,,,,,,,,,,,44,55,0,0,0,0,0,0,0,16,17,0,0,54,49,49,54,0,0,0,0,0,0,24,24,24,24,0,0,43,,,,,,,,,,,,,,,,,,,,,, +,,44,0,0,29,0,0,43,,,,,,,,,,,,,44,54,0,0,0,0,0,0,49,43,44,0,0,0,0,0,0,0,0,47,45,52,0,0,0,0,0,0,0,43,,,,,,,,,,,,,,,,,,,,,, +,,44,0,0,0,0,0,43,,,,,,,,,,,,,37,45,49,49,0,0,49,49,47,38,44,0,0,0,0,0,0,0,0,43,44,55,0,0,0,0,0,0,0,43,,,,,,,,,,,,,,,,,,,,,, +,,37,41,41,41,41,41,38,,,,,,,,,,,,,,37,41,41,41,41,41,41,38,13,37,41,41,45,0,0,47,41,41,38,37,41,41,41,41,41,41,41,41,38,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,40,42,42,42,42,42,39,,,,,40,42,42,42,42,42,42,39,13,40,42,42,46,0,0,48,42,42,39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,44,0,0,0,0,0,43,,,,40,46,54,54,54,54,54,54,48,39,44,24,24,24,24,24,24,24,24,43,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,44,0,24,24,24,0,48,42,42,39,44,54,0,0,0,0,0,0,54,48,46,24,0,0,0,0,0,0,24,43,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,44,0,24,24,24,0,0,0,0,21,18,0,24,0,0,0,0,0,0,0,0,24,0,0,0,0,0,0,24,43,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,44,0,24,24,24,0,0,0,0,16,17,0,0,0,0,0,0,0,0,0,0,24,0,0,0,0,0,0,24,43,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,44,0,0,0,0,0,47,41,41,38,44,52,0,0,0,0,0,0,52,47,45,24,0,1,25,25,3,0,24,43,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,44,0,0,0,0,0,43,,,,37,45,52,52,52,52,52,52,47,38,44,24,24,6,34,33,7,24,24,43,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,37,41,41,41,41,41,38,,,,,37,41,41,41,41,41,41,38,,37,41,41,31,22,23,32,41,41,38,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0, +,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0, +0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,0, +0,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,,,,,,,,,0,,,,,,,,,,,0, +0,,,,,,,,,,,0,,,,,,,,,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,0,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,0,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,0,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,0,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,0,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,0,0,0,,,,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,,0,,,,0,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,,0,,,,0,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,,0,,,,0,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,,0,,,,0,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,,0,,,,0,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,,0,,,,0,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,,0,,,,0,,,,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,,0,,,,0,,,,,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +,,,0,,,,0,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,0,0,0,,,,0,0,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,0,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,0,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,0,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,0,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,0,,,,,,,,0,0,0,0,0,0,0,0,0,0,,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,0,0,0,0,0,0,0,0,0,0,,,,,,,,0,,0,0,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,0,0,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,0,0,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,0,,0,0,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,0,0,0,0,0,0,0,0,0,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +1113 +169;576;592;d1b1 +0;16;304;;; +0;16;320;;; +0;16;336;;; +0;16;352;;; +0;16;368;;; +0;32;288;;; +0;32;624;;; +0;48;288;;; +0;48;400;;; +0;64;288;;; +0;64;400;;; +0;64;416;;; +0;64;432;;; +0;64;448;;; +0;64;464;;; +0;64;480;;; +0;64;496;;; +0;64;512;;; +0;64;528;;; +0;64;544;;; +0;64;560;;; +0;64;576;;; +0;64;592;;; +0;64;656;;; +0;80;288;;; +0;80;656;;; +0;96;288;;; +0;96;400;;; +0;96;416;;; +0;96;432;;; +0;96;448;;; +0;96;464;;; +0;96;480;;; +0;96;496;;; +0;96;512;;; +0;96;528;;; +0;96;544;;; +0;96;560;;; +0;96;576;;; +0;96;592;;; +0;96;656;;; +0;112;288;;; +0;112;400;;; +0;112;592;;; +0;128;288;;; +0;128;400;;; +0;128;624;;; +0;144;288;;; +0;160;304;;; +0;160;320;;; +0;160;336;;; +0;160;352;;; +0;160;368;;; +0;176;176;;; +0;176;192;;; +0;176;208;;; +0;176;224;;; +0;176;704;;; +0;176;720;;; +0;176;736;;; +0;176;752;;; +0;192;160;;; +0;192;448;;; +0;192;464;;; +0;192;480;;; +0;192;496;;; +0;208;160;;; +0;208;432;;; +0;208;512;;; +0;208;672;;; +0;208;784;;; +0;224;160;;; +0;224;272;;; +0;224;416;;; +0;224;528;;; +0;224;672;;; +0;224;784;;; +0;240;160;;; +0;240;272;;; +0;240;416;;; +0;240;528;;; +0;240;672;;; +0;240;784;;; +0;256;160;;; +0;256;272;;; +0;256;416;;; +0;256;528;;; +0;272;160;;; +0;272;272;;; +0;272;416;;; +0;272;528;;; +0;272;688;;; +0;272;704;;; +0;272;752;;; +0;288;160;;; +0;288;416;;; +0;288;528;;; +0;288;704;;; +0;288;752;;; +0;304;160;;; +0;304;416;;; +0;304;528;;; +0;304;704;;; +0;304;752;;; +0;320;176;;; +0;320;224;;; +0;320;432;;; +0;320;448;;; +0;320;480;;; +0;320;496;;; +0;320;512;;; +0;320;704;;; +0;336;176;;; +0;336;224;;; +0;336;240;;; +0;336;336;;; +0;336;352;;; +0;336;368;;; +0;336;384;;; +0;336;400;;; +0;336;416;;; +0;336;432;;; +0;336;448;;; +0;336;480;;; +0;336;496;;; +0;336;512;;; +0;336;576;;; +0;336;592;;; +0;336;608;;; +0;336;624;;; +0;336;704;;; +0;336;752;;; +0;352;320;;; +0;352;528;;; +0;352;560;;; +0;352;640;;; +0;352;688;;; +0;352;768;;; +0;368;160;;; +0;368;272;;; +0;368;304;;; +0;368;352;;; +0;368;528;;; +0;368;544;;; +0;368;656;;; +0;368;672;;; +0;368;784;;; +0;384;160;;; +0;384;272;;; +0;384;288;;; +0;384;528;;; +0;384;544;;; +0;384;656;;; +0;384;672;;; +0;384;784;;; +0;400;160;;; +0;400;656;;; +0;400;672;;; +0;400;784;;; +0;416;160;;; +0;416;656;;; +0;416;672;;; +0;416;784;;; +0;432;160;;; +0;432;272;;; +0;432;288;;; +0;432;528;;; +0;432;544;;; +0;432;656;;; +0;432;672;;; +0;432;784;;; +0;448;160;;; +0;448;272;;; +0;448;528;;; +0;448;544;;; +0;448;656;;; +0;448;672;;; +0;448;784;;; +0;464;160;;; +0;464;272;;; +0;464;384;;; +0;464;400;;; +0;464;416;;; +0;464;432;;; +0;464;528;;; +0;464;560;;; +0;464;640;;; +0;464;688;;; +0;464;768;;; +0;480;160;;; +0;480;272;;; +0;480;384;;; +0;480;400;;; +0;480;416;;; +0;480;432;;; +0;480;528;;; +0;480;576;;; +0;480;624;;; +0;480;704;;; +0;480;752;;; +0;480;768;;; +0;496;160;;; +0;496;272;;; +0;496;384;;; +0;496;400;;; +0;496;416;;; +0;496;432;;; +0;496;528;;; +0;496;560;;; +0;496;576;;; +0;496;624;;; +0;496;704;;; +0;496;752;;; +0;512;160;;; +0;512;272;;; +0;512;384;;; +0;512;400;;; +0;512;416;;; +0;512;432;;; +0;512;528;;; +0;512;544;;; +0;512;672;;; +0;512;784;;; +0;528;160;;; +0;528;272;;; +0;528;528;;; +0;528;544;;; +0;528;656;;; +0;528;672;;; +0;528;784;;; +0;544;160;;; +0;544;272;;; +0;544;528;;; +0;544;544;;; +0;544;656;;; +0;544;672;;; +0;544;784;;; +0;560;160;;; +0;560;272;;; +0;560;448;;; +0;560;528;;; +0;560;544;;; +0;568;800;;; +0;576;160;;; +0;576;272;;; +0;576;528;;; +0;576;544;;; +0;592;160;;; +0;592;272;;; +0;592;528;;; +0;592;544;;; +0;592;656;;; +0;592;672;;; +0;592;784;;; +0;608;160;;; +0;608;272;;; +0;608;528;;; +0;608;544;;; +0;608;656;;; +0;608;672;;; +0;608;784;;; +0;624;272;;; +0;624;528;;; +0;624;544;;; +0;624;672;;; +0;640;192;;; +0;640;208;;; +0;640;224;;; +0;640;240;;; +0;640;256;;; +0;640;272;;; +0;640;368;;; +0;640;384;;; +0;640;400;;; +0;640;416;;; +0;640;432;;; +0;640;512;;; +0;640;560;;; +0;640;576;;; +0;640;624;;; +0;640;640;;; +0;640;704;;; +0;640;720;;; +0;640;736;;; +0;640;752;;; +0;656;272;;; +0;656;368;;; +0;656;384;;; +0;656;432;;; +0;656;512;;; +0;656;560;;; +0;656;576;;; +0;656;624;;; +0;656;640;;; +0;672;272;;; +0;672;400;;; +0;672;416;;; +0;672;528;;; +0;672;544;;; +0;672;656;;; +0;688;272;;; +0;688;400;;; +0;688;416;;; +0;688;528;;; +0;688;544;;; +0;688;656;;; +0;704;272;;; +0;704;400;;; +0;704;416;;; +0;704;528;;; +0;704;544;;; +0;704;656;;; +0;720;400;;; +0;720;416;;; +0;720;656;;; +0;736;288;;; +0;736;400;;; +0;736;416;;; +0;736;656;;; +0;752;288;;; +0;752;400;;; +0;752;416;;; +0;752;528;;; +0;752;544;;; +0;752;656;;; +0;768;288;;; +0;768;528;;; +0;768;544;;; +0;768;656;;; +0;784;304;;; +0;784;400;;; +0;784;416;;; +0;784;528;;; +0;784;544;;; +0;784;656;;; +0;800;320;;; +0;800;336;;; +0;800;352;;; +0;800;368;;; +0;800;384;;; +0;800;432;;; +0;800;448;;; +0;800;496;;; +0;800;512;;; +0;800;560;;; +0;800;576;;; +0;800;592;;; +0;800;608;;; +0;800;624;;; +0;800;640;;; +0;816;320;;; +0;816;336;;; +0;816;352;;; +0;816;368;;; +0;816;432;;; +0;816;448;;; +0;816;496;;; +0;816;512;;; +0;832;304;;; +0;832;384;;; +0;832;416;;; +0;832;528;;; +0;848;288;;; +0;848;400;;; +0;848;416;;; +0;848;528;;; +0;864;288;;; +0;864;400;;; +0;864;416;;; +0;864;464;;; +0;864;480;;; +0;864;528;;; +0;880;288;;; +0;880;464;;; +0;880;480;;; +0;880;528;;; +0;896;288;;; +0;896;464;;; +0;896;480;;; +0;896;528;;; +0;912;288;;; +0;912;400;;; +0;912;416;;; +0;912;528;;; +0;928;288;;; +0;928;400;;; +0;928;416;;; +0;928;528;;; +0;944;304;;; +0;944;384;;; +0;944;416;;; +0;944;528;;; +0;960;320;;; +0;960;336;;; +0;960;352;;; +0;960;368;;; +0;960;432;;; +0;960;448;;; +0;960;496;;; +0;960;512;;; +0;976;64;;; +0;976;80;;; +0;976;96;;; +0;976;112;;; +0;976;176;;; +0;976;192;;; +0;976;208;;; +0;976;224;;; +0;976;240;;; +0;976;256;;; +0;976;304;;; +0;976;320;;; +0;976;336;;; +0;976;352;;; +0;976;368;;; +0;976;384;;; +0;976;432;;; +0;976;448;;; +0;976;496;;; +0;976;512;;; +0;992;160;;; +0;992;272;;; +0;992;288;;; +0;992;400;;; +0;992;416;;; +0;992;528;;; +0;1008;144;;; +0;1008;160;;; +0;1008;272;;; +0;1008;288;;; +0;1008;400;;; +0;1008;416;;; +0;1008;528;;; +0;1024;144;;; +0;1024;160;;; +0;1024;272;;; +0;1024;288;;; +0;1024;400;;; +0;1024;416;;; +0;1024;528;;; +0;1040;32;;; +0;1040;528;;; +0;1056;32;;; +0;1056;528;;; +0;1072;144;;; +0;1072;160;;; +0;1072;272;;; +0;1072;288;;; +0;1072;400;;; +0;1072;416;;; +0;1072;528;;; +0;1088;144;;; +0;1088;160;;; +0;1088;272;;; +0;1088;288;;; +0;1088;400;;; +0;1088;416;;; +0;1088;528;;; +0;1104;160;;; +0;1104;272;;; +0;1104;288;;; +0;1104;400;;; +0;1104;416;;; +0;1104;528;;; +0;1120;64;;; +0;1120;80;;; +0;1120;96;;; +0;1120;112;;; +0;1120;176;;; +0;1120;192;;; +0;1120;208;;; +0;1120;224;;; +0;1120;240;;; +0;1120;256;;; +0;1120;304;;; +0;1120;320;;; +0;1120;336;;; +0;1120;352;;; +0;1120;368;;; +0;1120;384;;; +0;1120;432;;; +0;1120;448;;; +0;1120;464;;; +0;1120;480;;; +0;1120;496;;; +0;1120;512;;; +19;704;288;;; +20;464;336;;; +20;608;336;;; +21;512;336;;; +21;704;336;;; +1;320;208;;; +1;320;736;;; +1;336;208;;; +1;336;736;;; +1;480;608;;; +1;496;608;;; +1;552;768;;; +1;584;768;;; +1;800;480;;; +1;816;480;;; +1;960;480;;; +1;976;480;;; +3;400;272;;; +3;400;288;;; +3;400;528;;; +3;400;544;;; +3;560;784;;; +3;720;528;;; +3;720;544;;; +3;1040;144;;; +3;1040;160;;; +3;1040;272;;; +3;1040;288;;; +3;1040;400;;; +3;1040;416;;; +4;416;272;;; +4;416;288;;; +4;416;528;;; +4;416;544;;; +4;576;784;;; +4;736;528;;; +4;736;544;;; +4;1056;144;;; +4;1056;160;;; +4;1056;272;;; +4;1056;288;;; +4;1056;400;;; +4;1056;416;;; +2;320;192;;; +2;320;720;;; +2;336;192;;; +2;336;720;;; +2;480;592;;; +2;496;592;;; +2;800;464;;; +2;816;464;;; +2;960;464;;; +2;976;464;;; +16;608;320;;; +17;512;320;;; +18;464;288;;; +458;848;320;;d1_boys +458;880;336;1;d1_boys +458;928;320;2;d1_boys +199;80;320;feather;;d1_feather;; +199;224;720;compass;one;d1_compass;; +199;560;304;nightmarekey;one;d1_nightmarekey;; +199;560;448;smallkeyChest;one;d1k3;; +289;424;728;d1k1 +289;560;288;d1_nightmarekey +289;560;464;d1k3 +289;568;600;d1k2 +261;320;200;;d1d3;; +261;320;728;;d1_door_1;; +261;336;200;;d1d3;2; +261;336;728;;d1_door_1;2; +261;408;272;;d1l1;1; +261;408;288;1;d1l1;3;d1l1 +261;408;528;;d1d1;1; +261;408;544;;d1d1;3; +261;480;600;;d1d1;; +261;496;600;;d1d1;2; +261;800;472;1;d1l2;;d1l2 +261;816;472;;d1l2;2; +261;960;472;;d1mb;; +261;976;472;;d1mb;2; +261;1048;144;2;d1ntop;1; +261;1048;160;2;d1ntop;3; +261;1048;272;2;d1_ndoor;1; +261;1048;288;3;d1_ndoor;3;d1_nkeyhole +261;1048;400;;d1mb;1; +261;1048;416;;d1mb;3; +174;512;816;dungeon_1 +153;80;624;;;d1s2;dungeon1_2d_1.map;d1s2;2;1;False +153;568;792;;;d1;overworld.map;d1;1;; +153;1056;336;;;d1s3;dungeon1_2d_2.map;d1s3;1;1;False +299;568;792;;;;;; +245;16;816;one;; +284;48;816;;220;200;175 +248;176;416;d1_wall;; +271;400;512;;;; +271;416;512;;;; +271;480;480;;;; +278;352;576; +278;352;592; +278;352;608; +278;352;624; +278;368;560; +278;368;640; +278;384;560; +278;384;640; +278;432;560; +278;432;640; +278;448;560; +278;448;640; +278;464;576; +278;464;624; +331;728;528 +350;256;161;d1_beak_1 +350;384;161;d1_beak_2 +350;896;289;d1_beak_1 +51;208;704;;;;;; +51;240;704;;;;;; +51;384;384;;;;;; +51;384;432;;;;;; +51;384;448;;;;;; +51;384;592;;;;;; +51;384;608;;;;;; +51;432;384;;;;;; +51;432;432;;;;;; +51;432;448;;;;;; +51;432;592;;;;;; +51;432;608;;;;;; +51;528;704;;;;;; +51;528;720;;;;;; +51;528;736;;;;;; +51;544;704;;;;;; +51;592;704;;;;;; +51;608;704;;;;;; +51;608;720;;;;;; +51;608;736;;;;;; +51;704;624;;;;;; +51;752;624;;;;;; +51;1024;48;;;;;; +51;1024;80;;;;;; +51;1024;352;;;;;; +51;1040;352;;;;;; +51;1056;352;;;;;; +51;1072;48;;;;;; +51;1072;80;;;;;; +51;1072;352;;;;;; +321;336;464;;d1_wall;;; +426;400;592 +426;400;608 +426;416;352 +426;416;592 +426;416;608 +426;720;624 +426;736;464 +426;736;624 +426;752;448 +427;428;208;;; +427;544;180;2;; +427;560;436;2;; +427;592;252;2;False; +427;608;508;;; +427;896;492;;; +427;928;516;2;; +429;400;448 +429;576;464 +436;704;608; +436;720;480; +436;752;608; +436;864;448; +421;32;368;;3;; +421;144;368;3;;; +421;352;336;;3;;2 +421;992;304;;3;;2 +421;992;384;;3;2; +421;1104;304;3;;;2 +421;1104;384;3;;2; +425;528;624 +425;544;208 +425;576;176 +425;608;624 +422;384;704 +422;432;704 +422;560;560 +422;768;320 +423;208;720;; +423;208;736;; +423;240;720;; +423;240;736;; +252;224;760;d1_et_2 +252;248;216;d1_et_6 +252;400;624;d1_et_3 +252;400;728;d1_et_1 +252;408;480;d1_et_5 +252;728;584;d1_et_4 +22;800;472;;;; +22;880;400;;;; +22;896;400;;;; +341;32;304;;;;;; +341;32;320;;;;;; +341;32;336;;;;;; +341;32;352;;;;;; +341;48;352;;;;;; +341;64;352;;;;;; +341;96;352;;;;;; +341;112;352;;;;;; +341;128;304;;;;;; +341;128;320;;;;;; +341;128;336;;;;;; +341;128;352;;;;;; +341;144;304;;;;;; +341;144;320;;;;;; +341;144;336;;;;;; +341;144;352;;;;;; +341;208;192;;;;;; +341;208;448;;;;;; +341;208;464;;;;;; +341;208;480;;;;;; +341;208;496;;;;;; +341;224;176;;;;;; +341;224;432;;;;;; +341;224;448;;;;;; +341;224;496;;;;;; +341;224;512;;;;;; +341;240;432;;;;;; +341;240;512;;;;;; +341;256;432;;;;;; +341;256;512;;;;;; +341;272;176;;;;;; +341;272;432;;;;;; +341;272;512;;;;;; +341;288;192;;;;;; +341;288;432;;;;;; +341;288;448;;;;;; +341;288;496;;;;;; +341;288;512;;;;;; +341;304;432;;;;;; +341;304;448;;;;;; +341;304;496;;;;;; +341;304;512;;;;;; +341;352;496;;;;;; +341;352;512;;;;;; +341;352;704;;;;;; +341;352;752;;;;;; +341;368;240;;;;;; +341;368;320;;;;;; +341;368;464;;;;;; +341;368;480;;;;;; +341;368;512;;;;;; +341;368;688;;;;;; +341;368;768;;;;;; +341;384;240;;;;;; +341;384;512;;;;;; +341;384;688;;;;;; +341;384;768;;;;;; +341;400;688;;;;;; +341;400;768;;;;;; +341;416;336;;;;;; +341;416;688;;;;;; +341;416;768;;;;;; +341;432;304;;;;;; +341;432;320;;;;;; +341;432;336;;;;;; +341;432;352;;;;;; +341;432;368;;;;;; +341;432;512;;;;;; +341;432;688;;;;;; +341;432;768;;;;;; +341;448;368;;;;;; +341;448;464;;;;;; +341;448;480;;;;;; +341;448;512;;;;;; +341;448;688;;;;;; +341;448;768;;;;;; +341;464;368;;;;;; +341;464;512;;;;;; +341;464;704;;;;;; +341;464;752;;;;;; +341;480;368;;;;;; +341;496;368;;;;;; +341;512;368;;;;;; +341;528;368;;;;;; +341;544;352;;;;;; +341;544;368;;;;;; +341;544;576;;;;;; +341;544;592;;;;;; +341;544;608;;;;;; +341;560;352;;;;;; +341;560;608;;;;;; +341;576;352;;;;;; +341;576;368;;;;;; +341;576;608;;;;;; +341;592;368;;;;;; +341;592;576;;;;;; +341;592;592;;;;;; +341;592;608;;;;;; +341;608;368;;;;;; +341;624;368;;;;;; +341;672;560;;;;;; +341;672;576;;;;;; +341;672;624;;;;;; +341;672;640;;;;;; +341;736;352;;;;;; +341;736;368;;;;;; +341;736;384;;;;;; +341;928;448;;;;;; +341;928;464;;;;;; +341;928;480;;;;;; +341;928;496;;;;;; +341;944;448;;;;;; +341;944;496;;;;;; +341;992;176;;;;;; +341;992;192;;;;;; +341;992;208;;;;;; +341;992;224;;;;;; +341;992;240;;;;;; +341;992;256;;;;;; +341;1008;176;;;;;; +341;1008;256;;;;;; +341;1088;176;;;;;; +341;1088;256;;;;;; +341;1104;176;;;;;; +341;1104;192;;;;;; +341;1104;208;;;;;; +341;1104;224;;;;;; +341;1104;240;;;;;; +341;1104;256;;;;;; +342;408;560;1 +342;464;600;2 +343;992;176;dungeon1_2d_2.map;d1s3p2 +343;992;192;dungeon1_2d_2.map;d1s3p3 +343;992;208;dungeon1_2d_2.map;d1s3p4 +343;992;224;dungeon1_2d_2.map;d1s3p5 +343;992;240;dungeon1_2d_2.map;d1s3p6 +343;992;256;dungeon1_2d_2.map;d1s3p7 +343;1008;176;dungeon1_2d_2.map;d1s3p5 +343;1008;256;dungeon1_2d_2.map;d1s3p7 +343;1088;176;dungeon1_2d_2.map;d1s3p2 +343;1088;256;dungeon1_2d_2.map;d1s3p7 +343;1104;176;dungeon1_2d_2.map;d1s3p2 +343;1104;192;dungeon1_2d_2.map;d1s3p3 +343;1104;208;dungeon1_2d_2.map;d1s3p4 +343;1104;224;dungeon1_2d_2.map;d1s3p5 +343;1104;240;dungeon1_2d_2.map;d1s3p6 +343;1104;256;dungeon1_2d_2.map;d1s3p7 +200;80;480;w;;heart_3;; +200;1048;72;;d1_instrument;instrument0;; +162;1016;64;-18;2;8;;;;;; +162;1088;64;18;2;8;;;;;; +168;304;608;d1d1;d1_et_3|!d1_enter_1; +168;320;816;d1_door_1;d1_et_2|!d1_enter_2; +168;960;560;d1mb;d1mbkilled|!d1mbenter; +168;1152;152;d1ntop;d1_nHeart&!d1_enter_I|d1_instrument; +168;1152;208;d1_heart;d1_n1_killed&!d1_enter_n; +168;1152;280;d1_ndoor;d1_nkeyhole&!d1_enter_n|d1_nHeart; +333;688;368;d1kb1 +167;208;816;d1_et_2;0 +167;240;816;d1_enter_2;0 +167;304;576;d1_et_3;0 +167;304;592;d1_enter_1;0 +167;568;832;d1teleporter; +167;984;560;d1mbenter;0 +167;1176;152;d1_enter_I;0 +167;1176;256;d1_n_trigger;0 +167;1176;280;d1_enter_n;0 +302;32;384;;;;; +302;48;304;;;;; +302;48;608;;;;; +302;48;640;;;;; +302;112;304;;;;; +302;112;608;;;;; +302;112;640;;;;; +302;144;384;;;;; +302;192;240;;;;; +302;192;688;;;;; +302;192;768;;;;; +302;208;256;;;;; +302;256;688;;;;; +302;256;768;;;;; +302;288;256;;;;; +302;304;240;;;;; +302;352;176;;;;; +302;352;256;;;;; +302;352;384;;;;; +302;512;288;;;;; +302;512;640;;;;; +302;512;688;;;;; +302;512;768;;;;; +302;528;288;;;;; +302;592;288;;;;; +302;608;288;;;;; +302;624;176;;;;; +302;624;256;;;;; +302;624;640;;;;; +302;624;688;;;;; +302;624;768;;;;; +302;704;560;;;;; +302;752;560;;;;; +302;832;320;;;;; +302;944;368;;;;; +302;992;48;;;;; +302;992;128;;;;; +302;1024;336;;;;; +302;1072;336;;;;; +302;1104;48;;;;; +302;1104;128;;;;; +307;1024;160;;;;; +307;1024;288;;;;; +307;1024;416;;;;; +307;1072;160;;;;; +307;1072;288;;;;; +307;1072;416;;;;; +308;480;576;;;;; +308;480;624;;;;; +308;960;448;;;;; +308;960;496;;;;; +309;384;272;;;;; +309;432;272;;;;; +309;1024;144;;;;; +309;1072;144;;;;; +310;336;176;;;;; +310;336;224;;;;; +310;336;704;;;;; +310;336;752;;;;; +310;976;448;;;;; +310;976;496;;;;; +170;320;728;d1_enter_2;;;; +170;408;544;d1_enter_1;3;;; +170;480;600;d1_enter_1;;;; +170;976;472;d1mbenter;2;;; +170;1048;144;d1_enter_I;1;;; +170;1048;272;d1_enter_n;1;;; +297;80;624;64;;;;75; +297;1056;336;64;;;;75; +10;480;336;;; +10;496;336;;; +10;528;320;;; +10;544;320;;; +10;560;320;;; +10;576;320;;; +10;592;320;;; +10;624;336;;; +10;640;336;;; +10;656;336;;; +10;672;336;;; +11;352;240;;; +11;400;240;;; +11;416;240;;; +11;432;240;;; +11;448;240;;; +11;464;240;;; +11;480;240;;; +11;480;288;;; +11;496;240;;; +11;496;288;;; +11;512;240;;; +11;528;240;;; +11;544;288;;; +11;560;288;;; +11;576;288;;; +11;624;288;;; +11;640;288;;; +11;656;288;;; +11;672;288;;; +11;688;288;;; +12;464;304;;; +12;464;320;;; +13;704;304;;; +13;704;320;;; +25;448;288;;;; +25;448;304;;;; +25;448;320;;;; +25;448;336;;;; +25;448;352;;;; +25;464;352;;;; +25;480;352;;;; +25;496;352;;;; +25;512;352;;;; +25;528;336;;;; +25;528;352;;;; +25;544;336;;;; +25;560;336;;;; +25;576;336;;;; +25;592;336;;;; +25;592;352;;;; +25;608;352;;;; +25;624;352;;;; +25;640;352;;;; +25;656;352;;;; +25;672;352;;;; +25;704;352;;;; +25;720;288;;;; +25;720;304;;;; +25;720;320;;;; +25;720;336;;;; +25;720;352;;;; +25;1008;64;;;; +25;1008;80;;;; +25;1008;96;;;; +25;1024;96;;;; +25;1072;96;;;; +25;1088;64;;;; +25;1088;80;;;; +25;1088;96;;;; +495;1104;468;d1mbenter;d1mbkilled +223;368;208;4;d1d3;;;;;; +223;400;192;0;;;;;;; +223;416;208;0;;;;;;; +223;432;192;0;;;;;;; +223;448;208;0;;;;;;; +223;528;208;0;;;;;;; +223;544;192;0;;;;;;; +223;544;240;0;;;;;;; +223;560;224;0;;;;;;; +223;560;496;0;;;;;;; +223;576;208;0;;;;;;; +223;592;192;0;;;;;;; +223;592;240;0;;;;;;; +223;608;224;0;;;;;;; +223;608;448;0;;;;;;; +223;608;496;0;;;;;;; +223;640;464;0;;;;;;; +223;656;464;0;;;;;;; +223;672;464;0;;;;;;; +223;688;464;0;;;;;;; +223;704;448;0;;;;;;; +223;704;464;0;;;;;;; +223;720;448;0;;;;;;; +223;736;448;0;;;;;;; +223;752;448;0;;;;;;; +223;768;448;0;;;;;;; +223;784;448;0;;;;;;; +287;16;848;19 +513;1040;200;d1_n1_killed;d1_n_trigger +164;240;464;shellsFound;;chest;shellChest..shell_4;False +164;240;464;shellsFound;1;chest;ruby20..shell_4;False +164;296;728;d1_et_2;1;dialogBox;sound_secrete; +164;368;192;d1d3;1;dialogBox;d1_moveStone; +164;416;624;d1_et_3;1;dialogBox;sound_secrete; +164;568;728;d1mbkilled;1;dungeonTeleporter;.d1teleport; +164;1048;216;d1_heart;1;item;.d1_nHeart.heartMeterFull;False +164;1048;472;d1mbkilled;1;dungeonTeleporter;.d1teleport; +164;1152;128;d1_enter_I;1;dialogBox;d1_instrument_music; +164;1152;256;d1_enter_n;1;dialogBox;d1_n_enter_dialog; +166;304;176;d1_et_6;1;d1_cave0 +166;368;720;d1_et_1;1;d1k1spawn +166;480;448;d1_et_5;1;d1c3 +166;624;576;d1b1;1;d1_button_0 +166;784;576;d1_et_4;1;d1c2 +166;944;320;d1_boys;1;d1_boys_sound +454;208;208 +454;256;240 +160;688;352; +160;1040;96; +160;1056;96; +460;192;688;d1_et_2 +460;256;688;d1_et_2 +246;464;288; +246;464;304; +246;464;320; +246;464;336; +246;480;288; +246;480;304; +246;480;320; +246;480;336; +246;496;288; +246;496;304; +246;496;320; +246;496;336; +246;512;304; +246;512;320; +246;512;336; +246;528;304; +246;528;320; +246;544;288; +246;544;304; +246;544;320; +246;560;288; +246;560;304; +246;560;320; +246;576;288; +246;576;304; +246;576;320; +246;592;304; +246;592;320; +246;608;304; +246;608;320; +246;608;336; +246;624;288; +246;624;304; +246;624;320; +246;624;336; +246;640;288; +246;640;304; +246;640;320; +246;640;336; +246;656;288; +246;656;304; +246;656;320; +246;656;336; +246;672;288; +246;672;304; +246;672;320; +246;672;336; +246;688;288; +246;688;304; +246;688;320; +246;688;336; +246;688;352; +246;704;288; +246;704;304; +246;704;320; +246;704;336; +246;1024;48; +246;1024;64; +246;1024;80; +246;1040;48; +246;1040;64; +246;1040;80; +246;1040;96; +246;1056;48; +246;1056;64; +246;1056;80; +246;1056;96; +246;1072;48; +246;1072;64; +246;1072;80; diff --git a/bin/Data/Maps/dungeon1.map.data b/bin/Data/Maps/dungeon1.map.data new file mode 100644 index 0000000..e668683 --- /dev/null +++ b/bin/Data/Maps/dungeon1.map.data @@ -0,0 +1,53 @@ +72 +51 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon1_2d_1.map b/bin/Data/Maps/dungeon1_2d_1.map new file mode 100644 index 0000000..1507aa5 --- /dev/null +++ b/bin/Data/Maps/dungeon1_2d_1.map @@ -0,0 +1,669 @@ +3 +0 +0 +tileset 2d.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,28,28,66,28,28,28,28,28,28,28,28,28,28,28,28,28,28,66,28,28,, +,18,113,66,113,113,113,110,108,110,113,113,110,108,110,113,113,113,66,113,18,, +,18,113,66,113,113,113,108,113,108,113,113,108,113,108,113,113,113,66,113,18,, +,18,113,66,113,113,113,113,113,113,113,113,113,113,113,113,113,28,66,28,28,, +,28,28,66,28,28,113,28,28,66,28,28,66,113,28,28,113,113,66,48,49,, +,49,46,66,113,113,113,113,113,66,18,18,66,113,113,113,113,113,66,48,49,, +,49,46,66,113,113,113,113,113,66,18,18,66,113,113,113,113,113,66,48,49,, +,49,49,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,49,49,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,0,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,0,0,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,1,,,,,,,,,,,,,,,,,,,2,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +107 +0;16;16;;; +0;16;32;;; +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;16;128;;; +0;32;16;;; +0;32;80;;; +0;32;96;;; +0;32;112;;; +0;32;128;;; +0;48;128;;; +0;64;16;;; +0;64;80;;; +0;64;128;;; +0;80;16;;; +0;80;80;;; +0;80;128;;; +0;96;16;;; +0;96;128;;; +0;112;16;;; +0;112;80;;; +0;112;128;;; +0;128;16;;; +0;128;80;;; +0;128;128;;; +0;144;16;;; +0;144;128;;; +0;160;16;;; +0;160;80;;; +0;160;96;;; +0;160;112;;; +0;160;128;;; +0;176;16;;; +0;176;80;;; +0;176;96;;; +0;176;112;;; +0;176;128;;; +0;192;16;;; +0;192;128;;; +0;208;16;;; +0;208;128;;; +0;224;16;;; +0;224;80;;; +0;224;128;;; +0;240;16;;; +0;240;80;;; +0;240;128;;; +0;256;16;;; +0;256;128;;; +0;272;16;;; +0;272;64;;; +0;272;128;;; +0;288;128;;; +0;304;16;;; +0;304;64;;; +0;304;80;;; +0;304;96;;; +0;304;112;;; +0;304;128;;; +0;320;16;;; +0;320;32;;; +0;320;48;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +0;320;112;;; +0;320;128;;; +153;48;8;;;d1s2;dungeon1.map;d1s2;3;;False +153;288;8;;;d1s1;dungeon1.map;d1s1;3;;False +245;-8;88;one;False; +284;-8;40;;200;200;150 +258;48;16; +258;48;32; +258;48;48; +258;48;64; +258;48;80; +258;48;96; +258;48;112; +258;144;80; +258;144;96; +258;144;112; +258;192;80; +258;192;96; +258;192;112; +258;288;16; +258;288;32; +258;288;48; +258;288;64; +258;288;80; +258;288;96; +258;288;112; +259;48;80; +259;144;80; +259;192;80; +259;288;64; +484;96;112 +484;208;112 +484;256;112 +303;128;48;;;;; +303;208;48;;;;; +297;48;16;90;;200;200;200; +297;288;16;90;;200;200;200; +257;-8;16 +287;-8;64;32 diff --git a/bin/Data/Maps/dungeon1_2d_1.map.data b/bin/Data/Maps/dungeon1_2d_1.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/dungeon1_2d_1.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon1_2d_2.map b/bin/Data/Maps/dungeon1_2d_2.map new file mode 100644 index 0000000..bd0800a --- /dev/null +++ b/bin/Data/Maps/dungeon1_2d_2.map @@ -0,0 +1,628 @@ +3 +0 +0 +tileset 2d.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,18,113,68,113,113,68,113,113,68,113,113,113,113,113,113,28,28,66,28,28,, +,18,113,90,113,113,68,113,113,90,113,113,113,113,113,113,18,113,66,113,18,, +,18,113,93,113,113,90,113,113,93,113,113,113,113,113,113,18,113,66,113,18,, +,28,28,110,108,110,93,110,108,110,113,113,110,108,110,113,28,28,66,28,28,, +,18,113,108,108,108,113,108,108,108,113,113,108,108,108,113,113,113,66,113,18,, +,18,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,66,113,18,, +,18,89,89,113,89,113,113,113,113,113,113,113,113,113,89,113,89,66,89,18,, +,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,0,,,,,,,,,,,,,0,0,0,,0,0,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +66 +0;16;16;;; +0;16;32;;; +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;16;128;;; +0;32;64;;; +0;32;128;;; +0;48;128;;; +0;64;128;;; +0;80;128;;; +0;96;128;;; +0;112;128;;; +0;128;128;;; +0;144;128;;; +0;160;128;;; +0;176;128;;; +0;192;128;;; +0;208;128;;; +0;224;128;;; +0;240;128;;; +0;256;16;;; +0;256;32;;; +0;256;48;;; +0;256;64;;; +0;256;128;;; +0;272;16;;; +0;272;64;;; +0;272;128;;; +0;288;128;;; +0;304;16;;; +0;304;64;;; +0;304;128;;; +0;320;16;;; +0;320;32;;; +0;320;48;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +0;320;112;;; +0;320;128;;; +153;64;8;;;d1s3p2;;;2;7;False +153;80;8;;;d1s3p3;;;2;7;False +153;96;8;;;d1s3p4;;;2;7;False +153;112;8;;;d1s3p5;;;2;7;False +153;128;8;;;d1s3p6;;;2;7;False +153;144;8;;;d1s3p7;;;2;7;False +153;288;8;;;d1s3;dungeon1.map;d1s3;3;;False +245;-8;88;one;False; +284;-8;40;;200;200;150 +258;288;16; +258;288;32; +258;288;48; +258;288;64; +258;288;80; +258;288;96; +258;288;112; +259;288;64; +303;64;80;;;;; +303;128;80;;;;; +303;208;80;;;;; +297;288;16;;;;;100; +257;-8;16 +287;-8;64;32 diff --git a/bin/Data/Maps/dungeon1_2d_2.map.data b/bin/Data/Maps/dungeon1_2d_2.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/dungeon1_2d_2.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon2.map b/bin/Data/Maps/dungeon2.map new file mode 100644 index 0000000..4916946 --- /dev/null +++ b/bin/Data/Maps/dungeon2.map @@ -0,0 +1,2002 @@ +3 +1 +1 +dungeon 2.png +62 +58 +3 +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,14,18,18,18,18,18,18,18,13,,14,18,18,18,18,18,18,18,18,18,18,18,13,,14,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,13,14,18,18,18,18,18,18,18,18,13,, +,,17,39,39,39,39,39,39,39,16,14,23,43,42,36,36,36,36,36,36,36,0,0,24,18,23,0,0,0,36,36,0,36,36,36,40,36,36,36,36,36,36,36,36,36,36,36,36,36,16,17,36,36,36,36,36,36,36,36,16,, +,,17,39,39,39,39,39,39,39,16,17,42,42,36,36,36,36,36,36,36,36,0,0,36,36,36,0,36,0,36,36,0,36,36,36,36,36,36,36,36,36,36,36,3,3,3,36,36,36,16,17,36,36,36,36,36,36,36,36,16,, +,,17,39,39,39,39,39,39,39,28,31,36,36,36,36,36,36,36,22,19,25,0,0,0,0,0,0,0,0,22,19,25,41,41,36,41,41,36,41,41,41,41,41,3,3,3,36,36,36,28,31,36,36,36,36,36,36,36,36,16,, +,,17,39,39,39,39,39,39,39,29,30,36,36,36,36,36,40,40,16,,17,40,40,40,40,40,40,40,40,16,,17,42,42,40,42,42,40,42,22,25,36,36,3,3,3,36,36,36,29,30,36,36,36,36,36,36,36,36,16,, +,,11,25,39,39,39,39,39,22,12,17,41,41,36,36,36,36,36,24,18,23,0,0,36,36,36,36,0,0,24,18,23,0,0,0,0,0,0,36,24,23,36,36,36,36,36,36,36,36,16,17,36,36,36,36,36,36,36,36,16,, +,,,11,25,39,39,39,22,12,,11,25,43,41,36,36,36,36,36,36,36,36,36,0,0,0,0,36,36,36,36,36,36,36,36,36,0,0,36,36,36,36,36,36,36,36,36,36,36,16,17,36,36,36,36,36,36,36,36,16,, +,,,,11,19,19,19,12,,,,11,19,25,36,22,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,36,22,12,11,19,19,19,19,19,19,19,19,12,, +,,,,,,,,,,,14,18,18,23,36,24,18,13,,,,,,,,,,,,,,,,,,,,,,,14,18,18,18,18,18,23,36,24,13,,,,,,,,,,,, +,,,,,,,,,,,17,36,36,36,36,36,36,16,,,,,,,,,,,,,,,,,,,,,,,17,35,36,36,36,36,36,36,36,16,,,,,,,,,,,, +,,,,,,,,,,,17,36,36,40,36,36,36,24,18,13,,,,,,,,,,,,,,,,,,,,,17,36,36,36,36,36,36,36,36,16,,,,,,,,,,,, +,,,,,,,,,,,17,36,36,36,40,36,36,36,36,16,,,,,,,,,,,,,,,,,,,,,17,36,36,36,36,36,36,36,36,16,,,,,,,,,,,, +,,,,,,,,,,,17,41,36,36,36,40,36,36,36,16,,,,,,,,,,,,,,,,,,,,,17,36,36,36,36,36,36,36,36,16,,,,,,,,,,,, +,,,,,,,,,,,17,42,41,36,36,36,40,36,36,16,,,,,,,,,,,,,,,,,,,,,17,36,36,36,39,39,36,36,36,16,,,,,,,,,,,, +,,,,,,,,,,,17,36,43,41,36,36,36,36,36,16,,,,,,,,,,,,,,,,,,,,,17,36,36,36,39,39,36,36,36,16,,,,,,,,,,,, +,,,,,,,,,,,11,19,19,19,19,19,25,36,22,12,,,,,,,,,,,,,,,,,,,,,11,19,19,19,19,19,19,19,19,12,,,,,,,,,,,, +,,14,18,18,18,18,18,18,13,,14,18,18,18,18,18,23,36,24,13,,,,,,,,,,,,,,,,,,,,,14,18,13,24,18,18,23,14,18,13,,,14,18,18,18,18,13,,,, +,14,23,40,40,40,40,40,40,24,13,17,36,36,42,36,36,42,36,36,16,,,,,,,,,,,,,,,,,,,,,17,36,16,3,3,3,3,17,36,16,14,18,23,3,3,3,3,24,18,13,, +,17,40,3,3,3,3,3,3,40,16,17,36,36,36,36,36,36,36,36,16,,,,,,,,,,,,,,,,,,,,,17,36,16,3,3,3,3,17,36,16,17,3,3,3,3,3,3,3,3,16,, +,17,40,3,3,3,3,3,3,40,16,17,36,36,36,36,36,36,36,40,16,,,,,,,,,,,,,,,,,,,,,17,36,16,3,3,3,3,17,36,16,17,3,3,3,3,3,3,3,3,16,, +,17,40,3,3,3,3,3,3,40,16,17,36,36,36,35,36,36,36,36,16,,,,,,,,,,,,,,,,,,,,,17,36,24,18,15,15,18,23,36,28,31,3,3,3,3,3,3,3,3,16,, +,17,3,3,3,3,3,3,3,3,28,31,36,36,36,36,36,36,36,36,16,,,,,,,,,,,,,,,,,,,,,17,36,36,36,36,36,36,36,36,29,30,3,3,3,3,3,3,3,3,16,, +,17,3,40,40,3,3,40,40,3,29,30,36,36,41,36,36,41,36,36,16,,,,,,,,,,,,,,,,,,,,,17,36,36,36,36,36,36,36,36,16,17,3,3,3,3,3,3,3,3,16,, +,11,19,19,19,32,27,19,19,19,12,11,19,19,19,19,19,19,19,19,12,,,,,,,,,,,,,,,,,,,,,11,19,19,19,19,19,19,19,19,12,11,19,19,19,32,27,19,19,19,12,, +,14,18,18,18,33,26,18,18,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,14,18,18,18,33,26,18,18,18,13,, +,17,39,39,39,39,39,39,39,24,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,36,36,41,38,37,41,36,34,16,, +,17,39,39,41,40,40,41,41,41,16,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,11,25,36,43,40,40,43,36,22,12,, +,17,39,41,43,39,39,43,43,43,16,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,36,43,38,37,43,36,16,,, +,17,39,42,43,39,39,43,43,43,16,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,36,43,38,37,43,36,16,,, +,17,39,39,42,40,40,42,42,42,16,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,36,42,40,40,42,36,16,,, +,17,39,39,39,39,39,39,34,22,12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,36,36,36,36,36,36,16,,, +,11,19,19,19,19,19,19,19,12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,11,19,19,19,19,19,19,12,,, +,,,14,18,18,18,18,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,14,18,18,18,18,18,18,18,18,13,, +,,,17,3,3,3,3,16,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,36,36,36,36,36,36,36,36,16,, +,14,18,23,3,3,3,3,24,18,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,36,36,36,36,36,36,36,36,16,, +,17,39,39,3,3,3,3,39,39,16,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,36,36,36,3,3,36,36,36,16,, +,17,41,41,40,40,40,40,41,41,16,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,36,36,36,36,36,36,36,36,16,, +,17,42,42,39,39,39,39,42,42,16,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,36,36,36,36,36,36,36,36,16,, +,17,39,39,39,39,39,39,39,39,16,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,36,36,36,36,36,36,36,36,16,, +,11,19,19,19,32,27,19,19,19,12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,11,19,19,19,19,19,19,32,27,12,, +,14,18,18,18,33,26,18,18,18,13,,14,18,18,18,18,18,18,13,,,,14,18,18,18,18,13,,,,14,18,18,18,18,18,18,13,,,,,14,18,18,18,18,18,13,,14,18,18,18,18,18,33,26,13,, +,17,39,39,39,39,39,39,39,39,16,,17,39,39,39,39,39,39,16,,,,17,36,36,36,36,16,,,,17,36,36,36,36,36,36,16,,,,,17,36,36,36,36,36,24,18,23,36,36,36,36,36,36,36,16,, +,17,39,39,39,39,39,39,39,39,16,14,23,39,22,19,19,25,39,24,13,14,18,23,36,36,36,36,24,18,18,18,23,36,36,36,36,36,36,24,18,18,18,18,23,36,36,36,36,36,36,36,36,36,3,3,3,3,36,36,16,, +,17,39,39,39,39,39,39,39,39,28,31,39,39,16,3,3,17,39,39,28,31,36,3,36,36,36,36,0,36,36,36,36,36,36,36,36,36,36,36,36,36,36,3,36,36,36,36,36,36,36,36,36,36,3,36,36,3,36,36,16,, +,17,39,39,39,39,39,39,39,39,29,30,39,39,16,3,3,17,39,39,29,30,36,36,36,36,36,36,0,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,3,36,36,3,36,36,16,, +,17,39,39,39,39,39,39,39,39,16,11,25,39,24,15,15,23,39,22,12,11,19,25,36,36,36,36,22,19,19,19,25,36,36,36,36,36,36,22,19,19,19,19,25,36,36,36,36,36,36,36,36,36,3,3,3,3,36,36,16,, +,17,39,39,39,39,39,39,39,39,16,,17,39,39,39,39,39,39,16,,,,17,36,36,36,36,16,,,,17,0,0,0,0,0,0,16,,,,,17,36,36,36,36,36,22,19,25,36,36,36,36,36,36,36,16,, +,11,19,19,19,19,19,19,19,19,12,,11,19,25,36,36,22,19,12,,,,11,19,32,27,19,12,,,,17,36,36,36,36,36,36,16,,,,,17,36,36,22,19,19,12,,11,19,19,19,19,19,19,19,12,, +,,,,,,,,,,,14,18,18,23,36,36,24,18,18,13,14,18,18,18,33,26,18,18,18,13,,17,36,36,36,36,36,36,16,,14,18,18,23,36,36,24,18,18,13,,,,,,,,,,,, +,,,,,,,,,,,17,36,36,3,3,3,3,36,36,16,17,36,36,36,36,36,36,3,3,16,14,23,36,36,36,36,36,36,16,,17,36,0,43,36,36,0,43,36,16,,,,,,,,,,,, +,,,,,,,,,,,17,36,36,3,3,3,3,36,36,16,17,36,36,36,36,36,36,3,36,16,17,36,36,36,36,36,36,36,16,,17,36,0,43,40,41,40,43,36,16,,,,,,,,,,,, +,,,,,,,,,,,17,36,36,3,3,3,3,36,36,16,17,36,36,36,36,36,36,3,3,16,17,36,36,0,0,0,36,36,24,18,23,40,40,43,0,43,0,43,36,16,,,,,,,,,,,, +,,,,,,,,,,,17,36,36,36,36,36,36,36,36,16,17,36,36,36,36,36,36,36,36,16,17,36,0,36,36,36,0,36,0,36,36,0,0,43,0,43,0,43,40,16,,,,,,,,,,,, +,,,,,,,,,,,11,19,25,9,6,6,10,22,19,12,11,25,36,36,36,36,36,36,22,12,17,36,36,0,0,0,36,36,0,36,36,36,0,43,0,43,0,43,36,16,,,,,,,,,,,, +,,,,,,,,,,,,,17,20,5,4,21,16,,,,11,25,36,36,36,36,22,12,,11,25,36,36,36,36,36,36,22,19,25,36,0,43,0,43,0,43,36,16,,,,,,,,,,,, +,,,,,,,,,,,,,11,8,2,1,7,12,,,,,11,19,19,19,19,12,,,,11,19,19,19,19,19,19,12,,11,19,19,19,19,19,19,19,19,12,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +,0,,,,,,,,,,0,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,0,0,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,0,0,,,,,,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,,0,0,0,0,0,0,0,0,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0, +,,,,,,,,,,0,,,,,,,,,0,0,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,0,0,0,0,0,0,0,0,,, +0,0,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,0,,,,,,,0,0,0, +0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,0, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,,,,,,,,,0,0, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,0,, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,0,, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,0,, +0,,,,,,,,,,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,,,,,,,,,0,0, +0,0,0,,,,,,,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0, +0,0,0,,,,,,,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0, +0,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,,0,0,0,0,0,0,0,0,,0,0,0,0,0,0,0,0,0,0,,,0,0,0,0,0,0,0,0,,,,,,,,,,,0, +0,,,,,,,,,,,0,,,,,,,,,0,,0,,,,,,,0,,0,,,,,,,,,0,,,0,,,,,,,,0,,,,,,,,,,0, +0,,,,,,,,,,,0,,,,,,,,,0,0,0,,,,,,,0,0,0,,,,,,,,,0,0,0,0,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,0,,,,,,,,,0,0,0,,,,,,,0,0,0,,,,,,,,,0,0,0,0,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,0,,,,,,,,,0,0,0,,,,,,,0,0,0,,,,,,,,,0,0,0,0,,,,,,,,0,,,,,,,,,,0, +0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,0,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,0,0,,,,,,,0,0,0,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,,,0,,,,,,,0,,0,0,,,,,,,0,0,0,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,,,0,0,0,,,0,0,0,,,0,0,0,0,0,0,0,0,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,, +524 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +waterfallSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +1295 +169;784;864;d2_button_1 +171;320;712;;;d2_room_enter_0;1;False; +171;328;712;;;d2b;0;False; +171;480;704;;32;d2_room_enter_0;1;False; +0;16;304;;; +0;16;320;;; +0;16;336;;; +0;16;352;;; +0;16;368;;; +0;16;432;;; +0;16;448;;; +0;16;464;;; +0;16;480;;; +0;16;576;;; +0;16;592;;; +0;16;608;;; +0;16;624;;; +0;16;672;;; +0;16;688;;; +0;16;704;;; +0;16;720;;; +0;16;736;;; +0;16;752;;; +0;32;32;;; +0;32;48;;; +0;32;64;;; +0;32;80;;; +0;32;288;;; +0;32;384;;; +0;32;560;;; +0;32;640;;; +0;32;656;;; +0;32;768;;; +0;48;16;;; +0;48;96;;; +0;48;272;;; +0;48;384;;; +0;48;400;;; +0;48;512;;; +0;48;544;;; +0;48;560;;; +0;48;640;;; +0;48;656;;; +0;48;768;;; +0;64;16;;; +0;64;112;;; +0;64;272;;; +0;64;384;;; +0;64;400;;; +0;64;512;;; +0;64;528;;; +0;64;640;;; +0;64;656;;; +0;64;768;;; +0;80;16;;; +0;80;128;;; +0;80;272;;; +0;80;512;;; +0;80;528;;; +0;80;768;;; +0;96;16;;; +0;96;128;;; +0;96;272;;; +0;96;512;;; +0;96;528;;; +0;96;768;;; +0;112;16;;; +0;112;128;;; +0;112;272;;; +0;112;384;;; +0;112;400;;; +0;112;512;;; +0;112;528;;; +0;112;640;;; +0;112;656;;; +0;112;768;;; +0;128;16;;; +0;128;112;;; +0;128;272;;; +0;128;384;;; +0;128;400;;; +0;128;512;;; +0;128;544;;; +0;128;560;;; +0;128;640;;; +0;128;656;;; +0;128;768;;; +0;144;16;;; +0;144;96;;; +0;144;288;;; +0;144;384;;; +0;144;416;;; +0;144;496;;; +0;144;560;;; +0;144;640;;; +0;144;656;;; +0;144;768;;; +0;160;32;;; +0;160;48;;; +0;160;96;;; +0;160;304;;; +0;160;320;;; +0;160;336;;; +0;160;384;;; +0;160;432;;; +0;160;448;;; +0;160;464;;; +0;160;480;;; +0;160;576;;; +0;160;592;;; +0;160;608;;; +0;160;624;;; +0;160;672;;; +0;160;688;;; +0;160;736;;; +0;160;752;;; +0;176;48;;; +0;176;96;;; +0;176;160;;; +0;176;176;;; +0;176;192;;; +0;176;208;;; +0;176;224;;; +0;176;240;;; +0;176;288;;; +0;176;304;;; +0;176;320;;; +0;176;336;;; +0;176;384;;; +0;176;688;;; +0;176;736;;; +0;176;800;;; +0;176;816;;; +0;176;832;;; +0;176;848;;; +0;192;32;;; +0;192;112;;; +0;192;144;;; +0;192;256;;; +0;192;272;;; +0;192;384;;; +0;192;672;;; +0;192;688;;; +0;192;736;;; +0;192;752;;; +0;192;784;;; +0;192;864;;; +0;208;16;;; +0;208;128;;; +0;208;144;;; +0;208;256;;; +0;208;272;;; +0;208;384;;; +0;208;656;;; +0;208;768;;; +0;208;784;;; +0;208;864;;; +0;208;880;;; +0;224;16;;; +0;224;128;;; +0;224;144;;; +0;224;256;;; +0;224;272;;; +0;224;384;;; +0;224;656;;; +0;224;688;;; +0;224;704;;; +0;224;768;;; +0;224;784;;; +0;224;896;;; +0;240;16;;; +0;240;256;;; +0;240;272;;; +0;240;384;;; +0;240;656;;; +0;240;688;;; +0;256;16;;; +0;256;128;;; +0;256;144;;; +0;256;256;;; +0;256;272;;; +0;256;384;;; +0;256;656;;; +0;256;688;;; +0;272;16;;; +0;272;128;;; +0;272;144;;; +0;272;256;;; +0;272;272;;; +0;272;384;;; +0;272;656;;; +0;272;688;;; +0;272;704;;; +0;272;768;;; +0;272;784;;; +0;272;896;;; +0;288;16;;; +0;288;128;;; +0;288;160;;; +0;288;176;;; +0;288;384;;; +0;288;656;;; +0;288;768;;; +0;288;784;;; +0;288;864;;; +0;288;880;;; +0;304;16;;; +0;304;64;;; +0;304;80;;; +0;304;96;;; +0;304;128;;; +0;304;176;;; +0;304;256;;; +0;304;272;;; +0;304;384;;; +0;304;672;;; +0;304;688;;; +0;304;736;;; +0;304;752;;; +0;304;768;;; +0;304;784;;; +0;304;864;;; +0;320;16;;; +0;320;64;;; +0;320;96;;; +0;320;128;;; +0;320;192;;; +0;320;208;;; +0;320;224;;; +0;320;240;;; +0;320;288;;; +0;320;304;;; +0;320;320;;; +0;320;336;;; +0;320;352;;; +0;320;368;;; +0;320;800;;; +0;320;816;;; +0;320;832;;; +0;320;848;;; +0;336;16;;; +0;336;64;;; +0;336;80;;; +0;336;96;;; +0;336;128;;; +0;336;800;;; +0;336;816;;; +0;336;832;;; +0;336;848;;; +0;352;16;;; +0;352;128;;; +0;352;688;;; +0;352;736;;; +0;352;784;;; +0;352;864;;; +0;368;16;;; +0;368;128;;; +0;368;672;;; +0;368;688;;; +0;368;736;;; +0;368;752;;; +0;368;784;;; +0;368;880;;; +0;384;32;;; +0;384;128;;; +0;384;656;;; +0;384;768;;; +0;384;784;;; +0;384;896;;; +0;400;32;;; +0;400;128;;; +0;400;656;;; +0;400;896;;; +0;416;32;;; +0;416;128;;; +0;416;656;;; +0;416;896;;; +0;432;16;;; +0;432;128;;; +0;432;656;;; +0;432;768;;; +0;432;784;;; +0;432;896;;; +0;448;16;;; +0;448;128;;; +0;448;672;;; +0;448;688;;; +0;448;736;;; +0;448;752;;; +0;448;784;;; +0;448;880;;; +0;464;16;;; +0;464;128;;; +0;464;688;;; +0;464;736;;; +0;464;784;;; +0;464;864;;; +0;480;16;;; +0;480;64;;; +0;480;80;;; +0;480;96;;; +0;480;128;;; +0;480;688;;; +0;480;736;;; +0;480;800;;; +0;480;816;;; +0;480;832;;; +0;480;848;;; +0;496;16;;; +0;496;64;;; +0;496;96;;; +0;496;128;;; +0;496;688;;; +0;496;736;;; +0;496;800;;; +0;496;816;;; +0;496;848;;; +0;496;864;;; +0;512;16;;; +0;512;64;;; +0;512;80;;; +0;512;96;;; +0;512;128;;; +0;512;672;;; +0;512;688;;; +0;512;736;;; +0;512;752;;; +0;512;768;;; +0;512;784;;; +0;512;800;;; +0;512;880;;; +0;528;16;;; +0;528;128;;; +0;528;656;;; +0;528;896;;; +0;544;16;;; +0;544;128;;; +0;544;656;;; +0;544;896;;; +0;560;16;;; +0;560;128;;; +0;560;656;;; +0;560;896;;; +0;576;16;;; +0;576;128;;; +0;576;656;;; +0;576;896;;; +0;592;16;;; +0;592;128;;; +0;592;656;;; +0;592;896;;; +0;608;16;;; +0;608;128;;; +0;608;656;;; +0;608;896;;; +0;624;16;;; +0;624;128;;; +0;624;672;;; +0;624;688;;; +0;624;736;;; +0;624;752;;; +0;624;768;;; +0;624;784;;; +0;624;800;;; +0;624;816;;; +0;624;832;;; +0;624;880;;; +0;640;16;;; +0;640;80;;; +0;640;96;;; +0;640;128;;; +0;640;688;;; +0;640;736;;; +0;640;832;;; +0;640;880;;; +0;656;16;;; +0;656;80;;; +0;656;96;;; +0;656;128;;; +0;656;160;;; +0;656;176;;; +0;656;192;;; +0;656;208;;; +0;656;224;;; +0;656;240;;; +0;656;288;;; +0;656;304;;; +0;656;320;;; +0;656;336;;; +0;656;352;;; +0;656;368;;; +0;656;688;;; +0;656;736;;; +0;656;800;;; +0;656;816;;; +0;656;832;;; +0;656;880;;; +0;672;16;;; +0;672;128;;; +0;672;144;;; +0;672;256;;; +0;672;272;;; +0;672;384;;; +0;672;688;;; +0;672;736;;; +0;672;784;;; +0;672;896;;; +0;688;16;;; +0;688;128;;; +0;688;144;;; +0;688;256;;; +0;688;288;;; +0;688;384;;; +0;688;688;;; +0;688;736;;; +0;688;784;;; +0;688;896;;; +0;704;16;;; +0;704;128;;; +0;704;144;;; +0;704;256;;; +0;704;272;;; +0;704;384;;; +0;704;672;;; +0;704;688;;; +0;704;736;;; +0;704;752;;; +0;704;768;;; +0;704;784;;; +0;704;896;;; +0;720;16;;; +0;720;128;;; +0;720;144;;; +0;720;256;;; +0;720;272;;; +0;720;384;;; +0;720;656;;; +0;720;896;;; +0;736;16;;; +0;736;128;;; +0;736;144;;; +0;736;256;;; +0;736;272;;; +0;736;384;;; +0;736;656;;; +0;736;896;;; +0;752;16;;; +0;752;128;;; +0;752;144;;; +0;752;256;;; +0;752;272;;; +0;752;384;;; +0;752;656;;; +0;752;768;;; +0;752;784;;; +0;752;896;;; +0;768;16;;; +0;768;256;;; +0;768;288;;; +0;768;384;;; +0;768;656;;; +0;768;768;;; +0;768;784;;; +0;768;896;;; +0;784;16;;; +0;784;128;;; +0;784;144;;; +0;784;256;;; +0;784;272;;; +0;784;384;;; +0;784;656;;; +0;784;768;;; +0;784;784;;; +0;800;32;;; +0;800;48;;; +0;800;96;;; +0;800;112;;; +0;800;160;;; +0;800;176;;; +0;800;192;;; +0;800;208;;; +0;800;224;;; +0;800;240;;; +0;800;288;;; +0;800;304;;; +0;800;320;;; +0;800;368;;; +0;800;672;;; +0;800;752;;; +0;800;800;;; +0;800;816;;; +0;800;832;;; +0;800;848;;; +0;800;864;;; +0;800;880;;; +0;816;32;;; +0;816;48;;; +0;816;96;;; +0;816;112;;; +0;816;304;;; +0;816;320;;; +0;816;368;;; +0;816;416;;; +0;816;544;;; +0;816;560;;; +0;816;576;;; +0;816;592;;; +0;816;608;;; +0;816;624;;; +0;816;672;;; +0;816;752;;; +0;832;16;;; +0;832;128;;; +0;832;288;;; +0;832;384;;; +0;832;400;;; +0;832;432;;; +0;832;448;;; +0;832;464;;; +0;832;480;;; +0;832;496;;; +0;832;528;;; +0;832;640;;; +0;832;672;;; +0;832;752;;; +0;848;16;;; +0;848;128;;; +0;848;288;;; +0;848;384;;; +0;848;400;;; +0;848;512;;; +0;848;528;;; +0;848;640;;; +0;848;656;;; +0;848;768;;; +0;864;16;;; +0;864;128;;; +0;864;272;;; +0;864;384;;; +0;864;400;;; +0;864;512;;; +0;864;528;;; +0;864;640;;; +0;864;656;;; +0;864;768;;; +0;880;16;;; +0;880;128;;; +0;880;272;;; +0;880;512;;; +0;880;528;;; +0;880;640;;; +0;880;656;;; +0;880;768;;; +0;896;16;;; +0;896;128;;; +0;896;272;;; +0;896;512;;; +0;896;528;;; +0;896;640;;; +0;896;656;;; +0;896;768;;; +0;912;16;;; +0;912;128;;; +0;912;272;;; +0;912;384;;; +0;912;400;;; +0;912;512;;; +0;912;528;;; +0;912;640;;; +0;912;656;;; +0;912;768;;; +0;928;16;;; +0;928;128;;; +0;928;288;;; +0;928;384;;; +0;928;400;;; +0;928;512;;; +0;928;528;;; +0;928;768;;; +0;944;16;;; +0;944;128;;; +0;944;288;;; +0;944;384;;; +0;944;400;;; +0;944;432;;; +0;944;448;;; +0;944;464;;; +0;944;480;;; +0;944;496;;; +0;944;528;;; +0;944;768;;; +0;960;32;;; +0;960;48;;; +0;960;64;;; +0;960;80;;; +0;960;96;;; +0;960;112;;; +0;960;304;;; +0;960;320;;; +0;960;336;;; +0;960;352;;; +0;960;368;;; +0;960;416;;; +0;960;544;;; +0;960;560;;; +0;960;576;;; +0;960;592;;; +0;960;608;;; +0;960;624;;; +0;960;672;;; +0;960;688;;; +0;960;704;;; +0;960;720;;; +0;960;736;;; +0;960;752;;; +1;160;80;;; +1;160;368;;; +1;160;720;;; +1;176;80;;; +1;176;368;;; +1;176;720;;; +1;232;880;;; +1;264;880;;; +1;320;720;;; +1;336;720;;; +1;800;80;;; +1;800;352;;; +1;816;80;;; +1;816;352;;; +3;80;384;;; +3;80;400;;; +3;80;640;;; +3;80;656;;; +3;240;896;;; +3;400;768;;; +3;400;784;;; +3;880;384;;; +3;880;400;;; +3;928;640;;; +3;928;656;;; +4;96;384;;; +4;96;400;;; +4;96;640;;; +4;96;656;;; +4;256;896;;; +4;416;768;;; +4;416;784;;; +4;896;384;;; +4;896;400;;; +4;944;640;;; +4;944;656;;; +2;160;64;;; +2;160;352;;; +2;160;704;;; +2;176;64;;; +2;176;352;;; +2;176;704;;; +2;320;704;;; +2;336;704;;; +2;800;64;;; +2;800;336;;; +2;816;64;;; +2;816;336;;; +199;80;560;stonebeak;two;d2_stoneBeak;; +199;192;816;ruby50;;d2_ruby50;; +199;208;176;dmap;two;d2_dmap;; +199;288;48;ruby20;;d2_ruby20;; +199;448;48;smallkeyChest;two;d2_smallkey_4;; +199;546;846;smallkeyChest;two;d2_smallkey_2;; +289;128;64;d2_stonelifter +289;408;680;d2_key_1 +289;480;48;d2_smallkey_4 +289;560;816;d2_smallkey_2 +289;688;720;d2_key_3 +289;784;192;d2_spawn_nkey +289;784;832;d2_smallkey_3 +261;88;640;;d2_door_8;1;d2_door_1 +261;88;656;;d2_door_8;3;d2_door_1 +261;160;72;;d2_door_5;; +261;160;360;;d2_door_7;; +261;160;712;;d2_door_1;; +261;176;72;1;d2_door_5;2;d2_door_5 +261;176;360;;d2_door_7;2; +261;176;712;1;d2_door_1;2;d2_door_1 +261;320;712;;d2_door_2;; +261;336;712;;d2_door_2;2; +261;408;768;1;d2_door_3;1;d2_door_3 +261;408;784;;d2_door_3;3; +261;800;72;1;d2_door_6;;d2_door_6 +261;800;344;2;d2_door_boss_1;; +261;816;72;;d2_door_6;2; +261;816;344;2;d2_door_boss_1;2; +261;888;384;2;d2_door_boss_0;1; +261;888;400;3;d2_door_boss_0;3;d2_nboss_door +261;936;640;;d2_door_4;1; +261;936;656;1;d2_door_4;3;d2_door_4 +174;40;952;dungeon_2 +153;128;496;;;d2_cave_0_left;dungeon2_2d_1.map;d2_cave_0_left;;1;False +153;240;336;;;d2_cave_1_left;dungeon2_2d_2.map;d2_cave_1_left;;1;False +153;248;888;;;d2_vac;;;3;6;False +153;248;904;;;d2;overworld.map;d2;1;; +153;672;160;;;d2_cave_1_right;dungeon2_2d_2.map;d2_cave_1_right;3;1;False +153;944;416;;;d2_cave_2_left;dungeon2_2d_3.map;d2_cave_2_left;;1;False +245;40;928;two;; +281;32;304; +281;32;320; +281;32;336; +281;48;288; +281;48;368; +281;64;288; +281;64;368; +281;80;288; +281;96;288; +281;112;288; +281;112;368; +281;128;288; +281;128;368; +281;144;304; +281;144;320; +281;144;336; +335;352;32;d2b;; +335;352;48;d2b;; +335;352;64;d2b;; +335;352;96;d2b;True; +335;368;32;d2b;; +335;368;48;d2b;; +335;368;64;d2b;; +335;368;96;d2b;True; +335;384;64;d2b;; +335;384;112;d2b;True; +335;400;64;d2b;True; +335;400;112;d2b;True; +335;416;64;d2b;; +335;416;112;d2b;True; +335;432;32;d2b;; +335;432;48;d2b;; +335;432;64;d2b;; +335;432;112;d2b;True; +335;448;32;d2b;; +335;448;64;d2b;; +335;448;96;d2b;True; +335;448;704;d2b;; +335;448;720;d2b;; +335;464;32;d2b;; +335;464;48;d2b;; +335;464;64;d2b;; +335;464;96;d2b;True; +335;512;32;d2b;True; +335;512;48;d2b;True; +335;528;96;d2b;True; +335;528;752;d2b;True; +335;528;848;d2b;; +335;544;96;d2b;True; +335;544;752;d2b;True; +335;544;832;d2b;; +335;544;864;d2b;; +335;560;96;d2b;True; +335;560;752;d2b;True; +335;560;832;d2b;; +335;560;864;d2b;; +335;576;96;d2b;True; +335;576;752;d2b;True; +335;576;832;d2b;; +335;576;864;d2b;; +335;592;96;d2b;; +335;592;112;d2b;; +335;592;752;d2b;True; +335;592;848;d2b;; +335;608;96;d2b;; +335;608;112;d2b;; +335;608;752;d2b;True; +335;624;848;d2b;; +335;624;864;d2b;; +335;672;848;d2b;; +335;688;800;d2b;True; +335;688;816;d2b;True; +335;688;848;d2b;; +335;688;864;d2b;True; +335;688;880;d2b;; +335;720;832;d2b;; +335;720;848;d2b;; +335;720;864;d2b;True; +335;720;880;d2b;True; +335;752;800;d2b;True; +335;752;832;d2b;True; +335;752;848;d2b;; +335;752;864;d2b;; +335;752;880;d2b;True; +284;16;928;;;; +332;88;384 +351;256;273;d2_beak_3 +351;560;657;d2_beak_1 +351;848;529;d2_beak_2 +52;208;304;;;;;; +52;208;352;;;;;; +52;288;304;;;;;; +52;288;352;;;;;; +52;544;688;;;;;; +52;592;688;;;;;; +52;704;288;;;;;; +52;704;320;;;;;; +52;752;288;;;;;; +52;752;320;;;;;; +331;400;48;d2b +331;568;712;d2b +331;574;846;d2b +331;720;64;d2b +331;784;879;d2b +432;80;48;d2_lamp_ghosts +432;96;80;d2_lamp_ghosts +440;192;240;dungeon2.map;d2_vac; +427;48;432 +427;64;704 +427;112;704 +427;208;64 +427;208;304 +427;240;176 +427;256;192 +427;272;208 +427;288;64 +427;288;352 +427;560;112 +427;704;48 +427;704;80 +427;736;48 +427;736;80 +427;768;240 +427;880;560 +427;880;608 +428;32;428;1;False; +428;208;668;2;False; +428;528;668;2;False; +428;852;628;;; +437;400;704; +425;912;80 +422;32;672;;3;;2 +422;32;752;;3;2; +422;144;672;3;;;2 +422;144;752;3;;2; +426;544;48 +423;96;544 +423;608;32 +252;88;704;d2_et_darkroom +252;112;48;d2_et_ghosts +252;408;736;d2_et_key_1 +252;408;824;d2_et_compass +252;736;720;d2_et_key_3 +252;944;48;d2_et_stairs +22;160;712;;;; +22;240;784;;;; +22;256;784;;;; +22;336;712;;;; +22;496;704;;;; +22;496;720;;;; +22;528;784;;;; +22;544;784;;;; +22;560;784;;;; +22;576;784;;;; +22;592;784;;;; +22;608;784;;;; +22;656;704;;;; +22;656;720;;;; +22;936;640;;;; +342;32;592;;;;;; +342;32;608;;;;;; +342;48;448;;;;;; +342;48;464;;;;;; +342;48;592;;;;;; +342;48;608;;;;;; +342;64;432;;;;;; +342;64;448;;;;;; +342;64;464;;;;;; +342;64;480;;;;;; +342;64;592;;;;;; +342;80;432;;;;;; +342;80;480;;;;;; +342;80;592;;;;;; +342;96;432;;;;;; +342;96;480;;;;;; +342;96;592;;;;;; +342;112;432;;;;;; +342;112;448;;;;;; +342;112;464;;;;;; +342;112;480;;;;;; +342;112;592;;;;;; +342;128;432;;;;;; +342;128;448;;;;;; +342;128;464;;;;;; +342;128;480;;;;;; +342;128;592;;;;;; +342;128;608;;;;;; +342;144;432;;;;;; +342;144;448;;;;;; +342;144;464;;;;;; +342;144;480;;;;;; +342;144;592;;;;;; +342;144;608;;;;;; +342;192;48;;;;;; +342;192;96;;;;;; +342;192;208;;;;;; +342;192;224;;;;;; +342;208;32;;;;;; +342;208;48;;;;;; +342;208;96;;;;;; +342;208;112;;;;;; +342;208;224;;;;;; +342;208;240;;;;;; +342;224;32;;;;;; +342;224;112;;;;;; +342;224;176;;;;;; +342;224;240;;;;;; +342;224;288;;;;;; +342;224;368;;;;;; +342;240;192;;;;;; +342;256;208;;;;;; +342;272;80;;;;;; +342;272;224;;;;;; +342;272;288;;;;;; +342;272;368;;;;;; +342;288;80;;;;;; +342;304;320;;;;;; +342;352;80;;;;;; +342;368;80;;;;;; +342;384;80;;;;;; +342;400;80;;;;;; +342;416;80;;;;;; +342;432;80;;;;;; +342;448;80;;;;;; +342;464;80;;;;;; +342;528;64;;;;;; +342;528;80;;;;;; +342;544;64;;;;;; +342;544;80;;;;;; +342;560;80;;;;;; +342;576;32;;;;;; +342;576;64;;;;;; +342;576;80;;;;;; +342;592;64;;;;;; +342;592;80;;;;;; +342;608;80;;;;;; +342;624;64;;;;;; +342;624;80;;;;;; +342;640;64;;;;;; +342;656;64;;;;;; +342;672;64;;;;;; +342;672;832;;;;;; +342;688;64;;;;;; +342;688;832;;;;;; +342;704;800;;;;;; +342;704;816;;;;;; +342;704;832;;;;;; +342;704;848;;;;;; +342;704;864;;;;;; +342;704;880;;;;;; +342;720;816;;;;;; +342;736;816;;;;;; +342;736;832;;;;;; +342;736;848;;;;;; +342;736;864;;;;;; +342;736;880;;;;;; +342;752;816;;;;;; +342;768;800;;;;;; +342;768;816;;;;;; +342;768;832;;;;;; +342;768;848;;;;;; +342;768;864;;;;;; +342;768;880;;;;;; +342;784;848;;;;;; +342;864;416;;;;;; +342;864;432;;;;;; +342;864;448;;;;;; +342;864;464;;;;;; +342;864;480;;;;;; +342;880;432;;;;;; +342;880;480;;;;;; +342;896;432;;;;;; +342;896;480;;;;;; +342;912;416;;;;;; +342;912;432;;;;;; +342;912;448;;;;;; +342;912;464;;;;;; +342;912;480;;;;;; +343;88;368;3 +200;80;464;w;;heart_3;; +200;256;48;w;;powder_10;; +200;272;368;w;;heart_3;; +200;728;312;;d2_instrument;instrument1;; +200;736;848;w;;powder_10;; +162;232;720;-18;2;8;12;;;;; +162;272;720;18;2;8;12;;;;; +162;696;304;-18;2;8;;;;;; +162;768;304;18;2;8;;;;;; +168;-8;640;d2_door_8;d2_et_darkroom; +168;96;-16;d2_lamp_ghosts;d2_lamp_3|d2_lamp_4; +168;168;280;d2_door_7;d2_hinox; +168;304;608;d2_lamps;d2_lamp_1&d2_lamp_2; +168;328;632;d2_door_2;(d2_lamp_1&d2_lamp_2)|d2_room_enter_0; +168;792;408;d2_door_boss_1;d2_nboss_door&(!d2_genie_enter|d2_nHeart)&(!d2_instrument_enter|d2_instrument); +168;984;392;d2_door_boss_0;d2_nboss_door&(!d2_genie_enter|d2_nHeart); +168;984;544;d2_stone;d2_stone_0_dir=2&d2_stone_1_dir=0;False +168;984;576;d2_block_reset;!d2_stone&d2_block_leave; +167;-8;656;d2_et_darkroom;0 +167;768;408;d2_instrument_enter;0 +167;984;648;d2_block_leave; +167;1008;392;d2_genie_enter;0 +254;752;176;d2_kot +303;32;416;;;;True; +303;32;496;;;;True; +303;48;48;;;;True;d2_lamp_3 +303;64;608;;;;True; +303;64;736;;;;True; +303;96;112;;;;True;d2_lamp_4 +303;112;608;;;;True; +303;112;736;;;;True; +303;192;160;;;;; +303;240;704;;;;True;d2_lamp_1 +303;240;816;;;;; +303;256;704;;;;True;d2_lamp_2 +303;256;816;;;;; +303;272;160;;;;; +303;304;192;;;;; +303;672;240;;;;; +303;672;288;;;;; +303;672;368;;;;; +303;784;240;;;;; +303;784;288;;;;; +303;784;368;;;;; +303;864;320;;;;; +303;912;320;;;;; +308;208;784;;;;; +308;256;16;;;;; +308;288;784;;;;; +308;320;96;;;;; +308;384;656;;;;; +308;384;784;;;;; +308;400;32;;;;; +308;432;656;;;;; +308;432;784;;;;; +308;448;16;;;;; +308;496;96;;;;; +308;544;16;;;;; +308;544;656;;;;; +308;592;16;;;;; +308;592;656;;;;; +308;688;784;;;;; +308;720;16;;;;; +308;768;784;;;;; +308;832;288;;;;; +308;864;16;;;;; +308;864;400;;;;; +308;864;528;;;;; +308;864;656;;;;; +308;912;16;;;;; +308;912;400;;;;; +308;912;528;;;;; +308;912;656;;;;; +308;944;288;;;;; +309;320;832;;;;; +309;800;48;;;;; +309;800;96;;;;; +309;960;688;;;;; +309;960;736;;;;; +310;224;384;;;;; +310;272;384;;;;; +310;320;64;;;;; +310;368;128;;;;; +310;384;768;;;;; +310;432;768;;;;; +310;448;128;;;;; +310;496;64;;;;; +310;544;128;;;;; +310;544;896;;;;; +310;592;128;;;;; +310;592;896;;;;; +310;688;896;;;;; +310;704;384;;;;; +310;720;128;;;;; +310;752;384;;;;; +310;768;896;;;;; +310;848;384;;;;; +310;864;128;;;;; +310;864;512;;;;; +310;864;640;;;;; +310;864;768;;;;; +310;912;128;;;;; +310;912;512;;;;; +310;912;640;;;;; +310;912;768;;;;; +310;928;384;;;;; +311;176;48;;;;; +311;176;96;;;;; +311;176;832;;;;; +311;496;832;;;;; +170;240;784;d2_room_enter_0;1;32;;True +170;320;712;d2_room_enter_0;;;;True +170;800;344;d2_instrument_enter;;;; +170;888;384;d2_genie_enter;1;;; +170;936;640;d2_block_leave;1;;;True +170;936;640;d2_block_leave;3;;; +298;88;328;164;;200;200;175; +298;128;496;64;;;;125; +298;240;336;64;;;;100; +298;248;896;100;;;;; +298;672;160;64;;;;100; +298;944;416;64;;;;100; +12;880;416;;; +12;880;448;;; +12;880;464;;; +13;896;416;;; +13;896;448;;; +13;896;464;;; +25;224;720;;;; +25;224;736;;;; +25;272;720;;;; +25;272;736;;;; +25;688;304;;;; +25;688;320;;;; +25;688;336;;;; +25;704;336;;;; +25;752;336;;;; +25;768;304;;;; +25;768;320;;;; +25;768;336;;;; +463;400;864 +463;736;704 +463;752;704 +498;80;296;d2_hinox; +223;224;352;0;;;;;;; +223;240;352;0;;;;;;; +223;256;352;0;;;;;;; +223;272;352;0;;;;;;; +223;288;320;0;;;;;;; +223;288;336;0;;;;;;; +223;384;48;0;;;;;;; +223;416;48;0;;;;;;; +223;672;80;0;;;;;;; +223;688;80;0;;;;;;; +223;704;96;0;;;;;;; +223;704;224;0;;;;;;; +223;704;240;0;;;;;;; +223;704;704;0;;;;;;; +223;704;720;0;;;;;;; +223;720;96;0;;;;;;; +223;720;208;-1;;;;;;; +223;736;96;0;;;;;;; +223;736;208;-1;;;;;;; +223;752;48;0;;;;;;; +223;752;64;0;;;;;;; +223;752;80;0;;;;;;; +223;752;96;0;;;;;;; +223;752;224;0;;;;;;; +223;752;240;0;;;;;;; +223;864;576;-1;d2_stone_0;;;;;;d2_block_reset +223;880;704;0;;;;;;; +223;880;720;0;;;;;;; +223;896;704;0;;;;;;; +223;896;720;0;;;;;;; +223;912;576;-1;d2_stone_1;;;;;;d2_block_reset +287;16;952;20 +515;888;304;d2_genie_killed +164;88;328;d2_hinox;1;dungeonTeleporter;.d2teleport; +164;88;728;d2_et_darkroom;1;dialogBox;sound_secrete; +164;248;840;d2_hinox;1;dungeonTeleporter;.d2teleport; +164;328;608;d2_lamps;1;dialogBox;d2_open_door; +164;656;408;d2_instrument_enter;1;dialogBox;d2_instrument_music; +431;720;240 +431;880;80 +431;928;112 +166;144;48;d2_et_ghosts;1;d2_spawn_stonelifter +166;368;704;d2_et_key_1;1;d2_spawn_key_1 +166;464;816;d2_et_compass;1;d2_spawn_compass +166;688;704;d2_et_key_3;1;d2_spawn_key_3 +166;784;176;d2_kot;1;d2_spawn_nkey +166;784;816;d2_button_1;1;d2_spawn_key_0 +166;944;32;d2_et_stairs;1;d2_spawn_stairs_1 +166;944;544;d2_stone;1;d2_spawn_stairs_0 +231;192;800;;;;;; +231;192;832;;;;;; +231;192;848;;;;;; +231;208;320;;heart;;;; +231;208;336;;;;;; +231;208;800;;;;;; +231;208;816;;;;;; +231;208;832;;;;;; +231;208;848;;;;;; +231;224;304;;;;;; +231;225;48;;;;;; +231;240;304;;;;;; +231;241;48;;ruby;;;; +231;256;304;;;;;; +231;272;32;;;;;; +231;272;48;;;;;; +231;272;96;;;;;; +231;272;112;;;;;; +231;272;304;;;;;; +231;288;32;;;;;; +231;288;96;;ruby;;;; +231;288;112;;;;;; +231;288;800;;heart;;;; +231;288;816;;;;;; +231;288;832;;;;;; +231;288;848;;;;;; +231;304;800;;heart;;;; +231;304;816;;heart;;;; +231;304;832;;;;;; +231;304;848;;;;;; +231;305;32;;heart;;;; +231;305;48;;;;;; +231;384;96;;heart;;;; +231;384;848;;;;;; +231;400;96;;heart;;;; +231;400;848;;;;;; +231;416;96;;heart;;;; +231;416;848;;;;;; +231;432;96;;heart;;;; +231;432;848;;;;;; +231;672;799;;;;;; +231;672;815;;;;;; +231;689;160;;;;;; +231;689;176;;;;;; +231;705;160;;;;;; +231;720;673;;;;;; +231;720;690;;;;;; +231;735;673;;;;;; +231;769;751;;;;;; +231;784;734;;;;;; +231;784;751;;;;;; +231;832;32;;;;;; +231;832;48;;;;;; +231;832;96;;;;;; +231;832;112;;;;;; +231;832;576;;;;;; +231;832;592;;;;;; +231;848;32;;;;;; +231;848;48;;;;;; +231;848;96;;;;;; +231;848;112;;;;;; +231;864;32;;;;;; +231;864;48;;;;;; +231;864;96;;;;;; +231;864;112;;fairy;;;; +231;864;544;;;;;; +231;864;624;;;;;; +231;880;32;;;;;; +231;880;48;;;;;; +231;880;96;;;;;; +231;880;112;;;;;; +231;880;544;;;;;; +231;880;560;;;;;; +231;880;608;;;;;; +231;880;624;;;;;; +231;896;48;;;;;; +231;896;64;;;;;; +231;896;80;;;;;; +231;896;96;;ruby;;;; +231;896;544;;;;;; +231;896;560;;;;;; +231;896;608;;;;;; +231;896;624;;;;;; +231;912;544;;;;;; +231;912;624;;;;;; +231;943;576;;;;;; +231;943;592;;;;;; +249;16;16;0.35;0.1 +249;16;400;0.45;0.1 +249;16;528;0.45;0.1 +249;16;656;0.45;0.1 +249;176;528;0.45;0.1 +249;176;656;0.45;0.1 +414;688;208 +455;896;688 +455;944;752 +160;240;736; +160;256;736; +160;720;336; +160;736;336; +438;416;704 +438;784;32 +415;528;880 +246;240;720; +246;240;736; +246;256;720; +246;256;736; +246;704;304; +246;704;320; +246;720;288; +246;720;304; +246;720;320; +246;720;336; +246;736;288; +246;736;304; +246;736;320; +246;736;336; +246;752;304; +246;752;320; diff --git a/bin/Data/Maps/dungeon2.map.data b/bin/Data/Maps/dungeon2.map.data new file mode 100644 index 0000000..7d11c6a --- /dev/null +++ b/bin/Data/Maps/dungeon2.map.data @@ -0,0 +1,60 @@ +62 +58 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon2_2d_1.map b/bin/Data/Maps/dungeon2_2d_1.map new file mode 100644 index 0000000..caf6c8b --- /dev/null +++ b/bin/Data/Maps/dungeon2_2d_1.map @@ -0,0 +1,635 @@ +3 +0 +0 +tileset 2d.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,62,66,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,66,62,, +,46,66,113,113,113,54,49,49,49,49,49,49,49,49,49,49,53,113,66,48,, +,46,66,113,113,113,113,54,49,49,49,49,49,49,49,49,53,113,113,66,48,, +,49,45,43,113,113,113,113,81,65,81,81,65,81,65,81,113,113,113,66,48,, +,49,49,46,113,113,113,113,113,81,113,113,81,113,81,113,113,113,113,66,48,, +,49,49,46,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,48,, +,49,49,46,83,83,45,45,83,45,45,45,45,83,83,83,83,83,83,44,48,, +,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,0,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,1,,,,,,,,,,,,,,,,,,,2,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +73 +0;16;16;;; +0;16;32;;; +0;16;48;;; +0;32;64;;; +0;48;16;;; +0;48;64;;; +0;48;80;;; +0;48;96;;; +0;48;112;;; +0;64;16;;; +0;64;128;;; +0;80;16;;; +0;80;128;;; +0;96;16;;; +0;98;112;;; +0;110;112;;; +0;112;16;;; +0;128;16;;; +0;128;128;;; +0;144;16;;; +0;146;112;;; +0;160;16;;; +0;160;112;;; +0;176;16;;; +0;176;112;;; +0;190;112;;; +0;192;16;;; +0;208;16;;; +0;208;128;;; +0;224;16;;; +0;224;128;;; +0;240;16;;; +0;240;128;;; +0;256;16;;; +0;256;128;;; +0;272;16;;; +0;272;128;;; +0;288;16;;; +0;288;128;;; +0;306;112;;; +0;320;16;;; +0;320;32;;; +0;320;48;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +286;-16;40;;;; +153;32;8;;;d2_cave_0_left;dungeon2.map;d2_cave_0_left;3;;False +153;304;8;;;d2c0r;dungeon2.map;d2c0r;3;;False +245;-16;88;two;False; +300;32;16;;;;;; +300;304;16;;;;;; +258;32;16; +258;32;32; +258;32;48; +258;304;16; +258;304;32; +258;304;48; +258;304;64; +258;304;80; +257;-16;16 +346;64;64;;48;;2000; +346;224;112;48;;;2000; +287;-16;64;32 +348;64;112 +348;80;112 +348;128;112 +348;208;112 +348;224;112 +348;240;112 +348;256;112 +348;272;112 +348;288;112 diff --git a/bin/Data/Maps/dungeon2_2d_1.map.data b/bin/Data/Maps/dungeon2_2d_1.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/dungeon2_2d_1.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon2_2d_2.map b/bin/Data/Maps/dungeon2_2d_2.map new file mode 100644 index 0000000..080feac --- /dev/null +++ b/bin/Data/Maps/dungeon2_2d_2.map @@ -0,0 +1,634 @@ +3 +0 +0 +tileset 2d.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,, +,49,49,49,49,53,65,81,65,81,65,65,81,65,81,65,54,49,49,49,49,, +,49,49,49,53,113,81,113,81,113,81,81,113,81,113,81,113,54,49,49,49,, +,46,65,81,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,65,48,, +,46,81,113,113,113,113,113,113,113,27,27,27,113,113,113,113,27,76,81,48,, +,27,113,113,33,113,113,113,33,113,113,113,113,113,113,33,113,113,76,113,27,, +,27,76,27,33,27,27,27,33,27,27,27,113,113,113,33,113,113,27,76,27,, +,27,76,27,33,27,27,27,33,27,27,27,27,27,27,33,27,27,27,76,27,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,,,,,,,,,,,,,,,,,,,4,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,0,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +72 +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;16;128;;; +0;32;48;;; +0;48;48;;; +0;48;112;;; +0;48;128;;; +0;64;48;;; +0;64;96;;; +0;80;32;;; +0;80;112;;; +0;96;16;;; +0;96;112;;; +0;112;16;;; +0;112;112;;; +0;128;16;;; +0;128;96;;; +0;144;16;;; +0;144;112;;; +0;160;16;;; +0;160;80;;; +0;160;112;;; +0;176;16;;; +0;176;80;;; +0;176;112;;; +0;192;16;;; +0;192;80;;; +0;192;128;;; +0;208;16;;; +0;208;128;;; +0;224;16;;; +0;224;128;;; +0;240;16;;; +0;240;96;;; +0;240;112;;; +0;256;32;;; +0;256;128;;; +0;272;48;;; +0;272;80;;; +0;272;128;;; +0;288;48;;; +0;288;112;;; +0;288;128;;; +0;304;48;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +0;320;112;;; +0;320;128;;; +286;-16;40;;;; +153;32;136;;;d2_cave_1_left;dungeon2.map;d2_cave_1_left;1;;False +153;304;136;;;d2_cave_1_right;dungeon2.map;d2_cave_1_right;1;;False +258;32;112; +258;32;128; +258;288;80; +258;288;96; +258;304;112; +258;304;128; +259;32;112; +259;288;80; +259;304;112; +489;64;80 +489;128;80 +489;240;80 +484;96;96 +484;208;112 +297;32;96;200;;200;200;100; +297;304;96;200;;200;200;100; +257;-16;16 +287;-16;64;32 diff --git a/bin/Data/Maps/dungeon2_2d_2.map.data b/bin/Data/Maps/dungeon2_2d_2.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/dungeon2_2d_2.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon2_2d_3.map b/bin/Data/Maps/dungeon2_2d_3.map new file mode 100644 index 0000000..8d687a7 --- /dev/null +++ b/bin/Data/Maps/dungeon2_2d_3.map @@ -0,0 +1,662 @@ +3 +0 +0 +tileset 2d.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,62,66,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,66,62,, +,33,66,113,113,109,107,109,113,113,113,113,113,113,113,109,107,109,113,66,33,, +,33,66,62,113,107,113,107,113,66,62,62,62,62,113,107,113,107,113,66,33,, +,33,66,33,113,113,113,113,113,66,33,49,49,33,113,113,113,113,113,66,33,, +,62,66,62,113,113,62,62,62,66,62,62,62,62,113,113,62,62,62,62,62,, +,46,66,113,113,113,33,113,113,66,113,113,113,113,113,113,113,113,113,48,49,, +,46,66,113,113,113,33,113,113,66,113,113,113,113,113,113,113,113,113,48,49,, +,49,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,49,49,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,0,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,1,,,,,,,,,,,,,,,,,,,2,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +100 +0;16;16;;; +0;16;32;;; +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;32;128;;; +0;48;16;;; +0;48;48;;; +0;48;64;;; +0;48;80;;; +0;48;128;;; +0;64;16;;; +0;64;128;;; +0;80;16;;; +0;80;128;;; +0;96;16;;; +0;96;80;;; +0;96;96;;; +0;96;112;;; +0;112;16;;; +0;112;80;;; +0;112;128;;; +0;128;16;;; +0;128;80;;; +0;128;128;;; +0;144;16;;; +0;144;128;;; +0;160;16;;; +0;160;48;;; +0;160;64;;; +0;160;80;;; +0;160;128;;; +0;176;16;;; +0;176;48;;; +0;176;80;;; +0;176;128;;; +0;192;16;;; +0;192;48;;; +0;192;80;;; +0;192;128;;; +0;208;16;;; +0;208;48;;; +0;208;64;;; +0;208;80;;; +0;208;128;;; +0;224;16;;; +0;224;128;;; +0;240;16;;; +0;240;128;;; +0;256;16;;; +0;256;80;;; +0;256;128;;; +0;272;16;;; +0;272;80;;; +0;272;128;;; +0;288;16;;; +0;288;80;;; +0;288;128;;; +0;304;80;;; +0;304;96;;; +0;304;112;;; +0;320;16;;; +0;320;32;;; +0;320;48;;; +0;320;64;;; +0;320;80;;; +286;-16;40;;;; +153;32;8;;;d2_cave_2_left;dungeon2.map;d2_cave_2_left;3;;False +153;304;8;;;d2_cave_2_right;dungeon2.map;d2_cave_2_right;3;;False +245;-16;88;two;False; +258;32;16; +258;32;32; +258;32;48; +258;32;64; +258;32;80; +258;32;96; +258;32;112; +258;144;48; +258;144;64; +258;144;80; +258;144;96; +258;144;112; +258;304;16; +258;304;32; +258;304;48; +258;304;64; +259;32;48; +259;144;48; +259;144;80; +257;-16;16 +346;64;80;;32;;;2 +346;224;80;;32;;;1 +287;-16;64;32 +165;112;112;;pot2D; +233;272;112;;;;;; +233;288;112;;;;;; +304;96;48;;;;; +304;256;48;;;;; diff --git a/bin/Data/Maps/dungeon2_2d_3.map.data b/bin/Data/Maps/dungeon2_2d_3.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/dungeon2_2d_3.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon3_1.map b/bin/Data/Maps/dungeon3_1.map new file mode 100644 index 0000000..9b65661 --- /dev/null +++ b/bin/Data/Maps/dungeon3_1.map @@ -0,0 +1,1029 @@ +3 +1 +1 +dungeon 3.png +22 +42 +3 +,,,,,,,,,,,,,,,,,,,,,, +,,,28,44,44,44,44,29,,,,,,,,,,,,,, +,,28,51,30,30,30,30,50,29,,,,,,,,,,,,, +,28,51,13,13,13,0,0,0,50,29,,,,,,,,,,,, +,43,30,13,30,13,0,7,0,30,46,,,,,,,,,,,, +,43,30,13,13,13,0,0,0,30,46,,,,,,,,,,,, +,43,30,49,45,48,30,30,30,30,46,,,,,,,,,,,, +,43,30,46,6,43,30,30,30,30,46,,,,,,,,,,,, +,43,30,46,6,26,48,30,30,49,27,,,,,,,,,,,, +,43,30,46,6,28,51,30,30,50,29,,,,,,,,,,,, +,43,30,46,6,43,30,30,0,0,46,,,,,,,,,,,, +,43,30,46,6,43,30,30,0,30,46,,,,,,,,,,,, +,43,30,46,6,43,30,30,0,0,46,,,,,,,,,,,, +,43,30,46,6,43,30,30,30,30,46,,,,,,,,,,,, +,43,30,46,6,43,30,30,30,30,46,,,,,,,,,,,, +,43,30,46,6,43,30,30,30,30,46,,,,,,,,,,,, +,43,30,46,6,26,45,35,39,45,27,,,,,,,,,,,, +,43,30,46,6,28,44,34,37,44,29,28,44,44,44,44,44,44,44,44,29,, +,43,30,46,6,43,30,30,30,30,46,43,30,30,13,13,13,13,13,13,46,, +,43,30,46,6,43,30,30,30,30,46,43,30,30,49,45,45,45,48,13,46,, +,43,30,46,6,43,30,30,30,30,33,36,30,30,46,0,0,0,43,13,46,, +,43,30,46,6,43,30,30,30,30,38,40,30,30,46,0,0,0,43,13,46,, +,43,30,46,6,43,30,30,30,30,46,43,30,30,50,44,47,44,51,13,46,, +,43,30,46,6,43,30,30,30,30,46,43,30,30,30,30,30,13,13,13,46,, +,43,30,46,6,26,45,35,39,45,27,26,45,45,45,45,45,45,45,45,27,, +,43,30,46,6,28,44,34,37,44,29,,,,,,,,,,,, +,43,30,46,6,43,30,30,0,0,46,,,,,,,,,,,, +,43,30,46,6,43,30,30,0,30,46,,,,,,,,,,,, +,43,30,50,44,51,30,30,0,0,46,,,,,,,,,,,, +,43,30,30,30,30,30,30,30,30,46,,,,,,,,,,,, +,43,30,30,30,30,30,30,30,30,46,,,,,,,,,,,, +,26,48,30,30,30,30,30,30,49,27,,,,,,,,,,,, +,,26,45,45,35,39,45,45,27,,,,,,,,,,,,, +,,,,28,34,37,29,,,,28,44,44,44,44,44,44,44,44,29,, +,28,44,44,51,0,0,50,44,44,29,43,55,55,55,55,55,55,0,0,46,, +,43,30,0,0,0,0,0,0,30,50,51,53,53,53,53,53,53,0,0,46,, +,43,30,0,0,0,0,0,0,30,30,30,30,30,30,30,30,30,0,0,46,, +,43,30,0,0,0,0,0,0,30,30,30,30,30,30,30,30,30,30,30,46,, +,43,30,30,12,5,5,11,30,30,49,48,54,54,54,54,54,54,30,30,46,, +,43,30,30,32,1,2,31,30,30,46,43,55,55,55,55,55,55,30,30,46,, +,26,45,45,9,4,3,10,45,45,27,26,45,45,45,45,45,45,45,45,27,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +56,,0,0,0,0,0,0,0,0,,,,,,,,,,,,, +,0,0,,,,,,,0,0,,,,,,,,,,,, +0,0,,,,,,,,,0,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,0,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,,,,,0,0,0,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,0,0,0,0,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +524 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +waterfallSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +370 +171;112;64;;;d3_l1_top_enter;1;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;16;128;;; +0;16;144;;; +0;16;160;;; +0;16;176;;; +0;16;192;;; +0;16;208;;; +0;16;224;;; +0;16;240;;; +0;16;256;;; +0;16;272;;; +0;16;288;;; +0;16;304;;; +0;16;320;;; +0;16;336;;; +0;16;352;;; +0;16;368;;; +0;16;384;;; +0;16;400;;; +0;16;416;;; +0;16;432;;; +0;16;448;;; +0;16;464;;; +0;16;480;;; +0;16;560;;; +0;16;576;;; +0;16;592;;; +0;16;608;;; +0;16;624;;; +0;32;48;;; +0;32;496;;; +0;32;544;;; +0;32;640;;; +0;48;32;;; +0;48;96;;; +0;48;112;;; +0;48;128;;; +0;48;144;;; +0;48;160;;; +0;48;176;;; +0;48;192;;; +0;48;208;;; +0;48;224;;; +0;48;240;;; +0;48;256;;; +0;48;272;;; +0;48;288;;; +0;48;304;;; +0;48;320;;; +0;48;336;;; +0;48;352;;; +0;48;368;;; +0;48;384;;; +0;48;400;;; +0;48;416;;; +0;48;432;;; +0;48;448;;; +0;48;512;;; +0;48;544;;; +0;48;640;;; +0;64;16;;; +0;64;96;;; +0;64;448;;; +0;64;512;;; +0;64;528;;; +0;64;544;;; +0;64;640;;; +0;80;16;;; +0;80;96;;; +0;80;112;;; +0;80;160;;; +0;80;176;;; +0;80;192;;; +0;80;208;;; +0;80;224;;; +0;80;240;;; +0;80;288;;; +0;80;304;;; +0;80;320;;; +0;80;336;;; +0;80;352;;; +0;80;368;;; +0;80;416;;; +0;80;432;;; +0;80;448;;; +0;88;656;;; +0;96;16;;; +0;96;128;;; +0;96;144;;; +0;96;256;;; +0;96;272;;; +0;96;384;;; +0;96;400;;; +0;112;16;;; +0;112;512;;; +0;112;528;;; +0;112;544;;; +0;112;640;;; +0;128;32;;; +0;128;512;;; +0;128;544;;; +0;128;640;;; +0;144;48;;; +0;144;128;;; +0;144;144;;; +0;144;256;;; +0;144;272;;; +0;144;384;;; +0;144;400;;; +0;144;496;;; +0;144;544;;; +0;144;640;;; +0;160;64;;; +0;160;80;;; +0;160;96;;; +0;160;112;;; +0;160;160;;; +0;160;176;;; +0;160;192;;; +0;160;208;;; +0;160;224;;; +0;160;240;;; +0;160;288;;; +0;160;304;;; +0;160;352;;; +0;160;368;;; +0;160;416;;; +0;160;432;;; +0;160;448;;; +0;160;464;;; +0;160;480;;; +0;160;560;;; +0;160;608;;; +0;160;624;;; +0;176;288;;; +0;176;304;;; +0;176;352;;; +0;176;368;;; +0;176;544;;; +0;176;560;;; +0;176;608;;; +0;176;624;;; +0;192;272;;; +0;192;384;;; +0;192;528;;; +0;192;640;;; +0;208;272;;; +0;208;384;;; +0;208;528;;; +0;208;640;;; +0;224;272;;; +0;224;384;;; +0;224;528;;; +0;224;640;;; +0;240;272;;; +0;240;384;;; +0;240;528;;; +0;240;640;;; +0;256;272;;; +0;256;384;;; +0;256;528;;; +0;256;640;;; +0;272;272;;; +0;272;384;;; +0;272;528;;; +0;272;640;;; +0;288;272;;; +0;288;384;;; +0;288;528;;; +0;288;640;;; +0;304;272;;; +0;304;384;;; +0;304;528;;; +0;304;640;;; +0;320;288;;; +0;320;304;;; +0;320;320;;; +0;320;336;;; +0;320;352;;; +0;320;368;;; +0;320;544;;; +0;320;560;;; +0;320;576;;; +0;320;592;;; +0;320;608;;; +0;320;624;;; +1;72;624;;; +1;104;624;;; +1;160;336;;; +1;176;336;;; +3;80;512;;; +3;80;528;;; +3;80;640;;; +3;112;256;;; +3;112;272;;; +3;112;384;;; +3;112;400;;; +4;96;512;;; +4;96;528;;; +4;96;640;;; +4;128;256;;; +4;128;272;;; +4;128;384;;; +4;128;400;;; +2;160;320;;; +2;176;320;;; +199;64;64;stonebeak;three;d3_stonebeak;; +199;120;304;greenZol;;d3_chest_zol;; +199;256;320;dmap;three;d3_map;; +199;304;560;smallkeyChest;three;d3k1;; +289;144;416;d3k2 +289;304;544;d3k1 +261;88;512;;d3_door_1;1; +261;88;528;;d3_door_1;3; +261;120;256;;d3_door_2;1; +261;120;272;;d3_door_2;3; +261;120;384;;d3_door_2;1; +261;120;400;;d3_door_2;3; +261;160;328;;d3_door_2;; +261;176;328;;d3_door_2;2; +174;16;704;dungeon_3 +153;88;648;;;d3;overworld.map;d3;1;; +153;112;64;;;d3_1;dungeon3_2.map;d3_1;2;1;False +300;88;640;;;;;; +245;48;672;three;; +62;64;560;;;;;; +62;64;576;;;;;; +62;112;560;;;;;; +62;112;576;;;;;; +336;48;48;d3_barrier;; +336;48;64;d3_barrier;; +336;48;80;d3_barrier;; +336;64;48;d3_barrier;; +336;64;80;d3_barrier;True; +336;80;48;d3_barrier;True; +336;80;64;d3_barrier;True; +336;80;80;d3_barrier;True; +336;224;288;d3_barrier;True; +336;240;288;d3_barrier;True; +336;256;288;d3_barrier;True; +336;272;288;d3_barrier;True; +336;272;368;d3_barrier;True; +336;288;288;d3_barrier;True; +336;288;368;d3_barrier;True; +336;304;288;d3_barrier;True; +336;304;304;d3_barrier;True; +336;304;320;d3_barrier;True; +336;304;336;d3_barrier;True; +336;304;352;d3_barrier;True; +336;304;368;d3_barrier;True; +284;16;672;;220;200;175 +441;32;464 +441;144;464 +440;288;576;;;True +427;192;368 +427;208;320 +437;96;192; +437;96;208; +426;32;192 +426;32;448 +424;96;48;; +424;96;80;; +424;112;320;; +424;112;336;; +424;128;48;; +424;128;80;; +424;128;320;; +424;128;336;; +252;120;360;d3_et_2 +252;128;176;d3_et_3 +252;128;432;d3_et_1 +22;112;136;;;; +22;120;256;;;; +22;120;272;;;; +22;120;384;;;; +22;120;400;;;; +22;128;136;;;; +22;160;328;;;; +22;176;328;;;; +342;192;544;;;;;; +342;192;560;;;;;; +342;192;608;;;;;; +342;192;624;;;;;; +342;208;544;;;;;; +342;208;560;;;;;; +342;208;608;;;;;; +342;208;624;;;;;; +342;224;544;;;;;; +342;224;560;;;;;; +342;224;608;;;;;; +342;224;624;;;;;; +342;240;544;;;;;; +342;240;560;;;;;; +342;240;608;;;;;; +342;240;624;;;;;; +342;256;544;;;;;; +342;256;560;;;;;; +342;256;608;;;;;; +342;256;624;;;;;; +342;272;544;;;;;; +342;272;560;;;;;; +342;272;608;;;;;; +342;272;624;;;;;; +274;32;320;;;; +274;32;336;;;; +162;232;320;-18;2;8;32;;;;; +162;240;312;;-18;48;8;;;;;True +162;240;352;;18;;8;;;;; +162;272;352;;18;;8;;;;; +162;288;320;18;2;8;32;;;;;True +168;184;248;d3_door_2;d3_et_2|!d3_door_2_entry; +168;184;504;d3_door_1;d3_door_1_hit|d3_l1_top_enter; +167;16;16;d3_l1_top_enter;0 +167;208;224;d3_door_2_entry;0 +167;208;248;d3_et_2;0 +167;208;504;d3_door_1_hit;0 +303;32;624;;;;; +303;144;624;;;;; +308;48;544;;;;; +308;64;16;;;;; +308;96;272;;;;; +308;112;16;;;;; +308;128;544;;;;; +308;144;272;;;;; +308;240;352;;;;; +308;272;352;;;;; +310;48;512;;;;; +310;128;512;;;;; +170;120;272;d3_door_2_entry;3;;; +170;120;384;d3_door_2_entry;1;;; +25;224;304;;;; +25;224;320;;;; +25;224;336;;;; +25;224;352;;;; +25;240;304;;;; +25;240;352;;;; +25;256;304;;;; +25;272;304;;;; +25;272;352;;;; +25;288;304;;;; +25;288;320;;;; +25;288;336;;;; +25;288;352;;;; +226;96;32;;;;;;;; +226;208;368;;;;;;;; +287;48;704;21 +165;143;607;d3_door_1;pot; +164;8;520;d3_door_1_hit;1;dialogBox;sound_secrete; +164;88;528;d3_l1_top_enter;;hitTrigger;1024.d3_door_1_hit; +164;88;592;d3_et_11;1;dungeonTeleporter;dungeon3_3$map.d3_teleporter;False +164;96;328;d3_et_2;1;dialogBox;sound_secrete; +166;144;176;d3_et_3;1;d3_spawn_2 +166;144;432;d3_et_1;1;d3_spawn_1 +231;32;607;;;;;; +231;48;607;;;;;; +231;48;623;;;;;; +231;127;607;;;;;; +231;127;623;;;;;; +160;256;352; +415;96;448 +415;272;336 +246;240;320; +246;240;336; +246;256;336; +246;272;320; +246;272;336; diff --git a/bin/Data/Maps/dungeon3_1.map.data b/bin/Data/Maps/dungeon3_1.map.data new file mode 100644 index 0000000..a15566b --- /dev/null +++ b/bin/Data/Maps/dungeon3_1.map.data @@ -0,0 +1,44 @@ +22 +42 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon3_2.map b/bin/Data/Maps/dungeon3_2.map new file mode 100644 index 0000000..e0e1d3e --- /dev/null +++ b/bin/Data/Maps/dungeon3_2.map @@ -0,0 +1,887 @@ +3 +1 +1 +dungeon 3.png +32 +26 +3 +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,28,44,44,44,44,44,44,29,,,,,,,,,,,,, +,,,,,,,,,,,28,51,30,30,30,30,30,30,50,29,,,,,,,,,,,, +,,,,,,,,,,,43,30,21,0,22,21,0,22,30,46,,,,,,,,,,,, +,,,,,,,,,,,43,30,0,0,0,0,0,0,30,46,,,,,,,,,,,, +,,,,,,,,,,,43,30,19,0,20,19,0,20,30,46,,,,,,,,,,,, +,,,,,,,,,,,43,30,30,30,30,30,30,30,30,46,,,,,,,,,,,, +,,,,,,,,,,,43,30,30,30,30,30,30,30,30,46,,,,,,,,,,,, +,,,,,,,,,,,26,45,45,45,35,39,45,45,45,27,,,,,,,,,,,, +,,28,44,44,44,44,44,44,29,,,,28,44,34,37,44,29,,,,,,,,,,,,,, +,28,51,30,30,54,30,30,30,50,29,28,44,51,30,30,30,30,50,44,29,28,44,44,44,44,44,44,44,44,29,, +,43,30,30,30,55,30,30,30,30,46,43,30,30,30,30,30,30,30,30,46,43,30,30,30,30,30,30,30,30,46,, +,43,30,30,30,55,30,30,30,30,33,36,30,30,30,30,30,8,30,30,33,36,30,30,30,30,30,30,30,30,46,, +,43,30,30,30,55,30,30,30,30,38,40,30,30,30,30,30,30,30,30,38,40,30,30,30,30,30,30,30,30,46,, +,43,30,30,30,55,30,30,30,30,46,43,30,30,30,30,30,30,30,30,46,43,30,30,30,8,30,30,30,30,46,, +,26,48,30,30,53,30,30,30,49,27,26,45,48,30,30,30,30,49,45,27,26,45,45,45,45,45,45,45,45,27,, +,,26,45,45,45,45,45,45,27,,,,26,45,35,39,45,27,,,,,,,,,,,,,, +,,,,,,,,,,,,,28,44,34,37,44,29,,,,,,,,,,,,,, +,,,,,,,,,,,28,44,51,30,30,30,30,50,44,29,,,,,,,,,,,, +,,,,,,,,,,,43,30,30,30,30,30,30,30,30,46,,,,,,,,,,,, +,,,,,,,,,,,43,30,30,30,30,30,30,30,30,46,,,,,,,,,,,, +,,,,,,,,,,,43,30,30,30,52,52,30,30,30,46,,,,,,,,,,,, +,,,,,,,,,,,43,30,30,30,30,30,30,30,30,46,,,,,,,,,,,, +,,,,,,,,,,,26,48,30,30,30,30,30,30,49,27,,,,,,,,,,,, +,,,,,,,,,,,,26,45,45,45,45,45,45,27,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,, +,,,,,,,,,,0,0,,,,,,,,,0,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,0,,,,,,,,,,, +0,0,,,,,,,,,0,0,0,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,0,,,,,,,,,0,0,0,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0, +,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,0,0,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,0,,,,,,,,,0,0,,,,,,,,,,, +,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +277 +0;16;176;;; +0;16;192;;; +0;16;208;;; +0;16;224;;; +0;32;160;;; +0;32;240;;; +0;48;144;;; +0;48;256;;; +0;64;144;;; +0;64;256;;; +0;80;144;;; +0;80;256;;; +0;96;144;;; +0;96;256;;; +0;112;144;;; +0;112;256;;; +0;128;144;;; +0;128;256;;; +0;144;160;;; +0;144;240;;; +0;160;176;;; +0;160;224;;; +0;176;48;;; +0;176;64;;; +0;176;80;;; +0;176;96;;; +0;176;112;;; +0;176;176;;; +0;176;224;;; +0;176;304;;; +0;176;320;;; +0;176;336;;; +0;176;352;;; +0;192;32;;; +0;192;128;;; +0;192;160;;; +0;192;240;;; +0;192;288;;; +0;192;368;;; +0;208;16;;; +0;208;128;;; +0;208;160;;; +0;208;240;;; +0;208;288;;; +0;208;384;;; +0;224;16;;; +0;224;128;;; +0;224;144;;; +0;224;256;;; +0;224;272;;; +0;224;384;;; +0;240;16;;; +0;240;384;;; +0;256;16;;; +0;256;384;;; +0;272;16;;; +0;272;128;;; +0;272;144;;; +0;272;256;;; +0;272;272;;; +0;272;384;;; +0;288;16;;; +0;288;128;;; +0;288;160;;; +0;288;240;;; +0;288;288;;; +0;288;384;;; +0;304;32;;; +0;304;128;;; +0;304;160;;; +0;304;240;;; +0;304;288;;; +0;304;368;;; +0;320;48;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +0;320;112;;; +0;320;176;;; +0;320;224;;; +0;320;304;;; +0;320;320;;; +0;320;336;;; +0;320;352;;; +0;336;176;;; +0;336;224;;; +0;352;160;;; +0;352;240;;; +0;368;160;;; +0;368;240;;; +0;384;160;;; +0;384;240;;; +0;400;160;;; +0;400;240;;; +0;416;160;;; +0;416;240;;; +0;432;160;;; +0;432;240;;; +0;448;160;;; +0;448;240;;; +0;464;160;;; +0;464;240;;; +0;480;176;;; +0;480;192;;; +0;480;208;;; +0;480;224;;; +14;240;80;;; +14;288;80;;; +1;160;208;;; +1;176;208;;; +1;320;208;;; +1;336;208;;; +3;240;128;;; +3;240;144;;; +3;240;256;;; +3;240;272;;; +4;256;128;;; +4;256;144;;; +4;256;256;;; +4;256;272;;; +2;160;192;;; +2;176;192;;; +2;320;192;;; +2;336;192;;; +15;208;80;;; +15;256;80;;; +16;240;48;;; +16;288;48;;; +17;208;48;;; +17;256;48;;; +289;48;224;d3k4 +289;208;96;d3k3 +289;208;304;d3k5 +261;160;200;;d3_door_3;; +261;176;200;1;d3_door_3;2;d3_door_3 +261;248;128;;d3_door_4;1;d3_lock_4 +261;248;144;1;d3_door_4;3;d3_door_4 +261;248;256;1;d3_door_6;1;d3_door_6 +261;248;272;;d3_door_6;3;d3_lock_6 +261;320;200;1;d3_door_5;;d3_door_5 +261;336;200;;d3_door_5;2;d3_lock_5 +153;272;192;;;d3_1;dungeon3_1.map;d3_1;;1;False +153;400;224;;;d3_2;dungeon3_3.map;d3_2;;1;False +245;48;416;three;;1 +62;368;192;;;;;; +62;368;208;;;;;; +62;368;224;;;;;; +62;384;192;;;;;; +62;400;192;;;;;; +62;416;192;;;;;; +62;416;224;;;;;; +62;432;192;;;;;; +62;432;224;;;;;; +62;448;192;;;;;; +62;448;224;;;;;; +62;464;224;;;;;; +284;16;416;;220;200;175 +248;16;144;d3_door_3;; +248;176;16;d3_door_4;; +248;176;272;d3_door_6;; +248;336;144;d3_door_5;; +350;224;64;d3_beak_1 +349;48;192;2 +349;48;208;2 +349;64;160;2 +349;64;176;2 +349;64;192;2 +349;64;208;2 +349;64;224;2 +349;64;240;2 +349;96;160; +349;96;176; +349;96;192; +349;96;208; +349;96;224; +349;96;240; +349;192;320;3 +349;192;336;3 +349;192;352;2 +349;208;320; +349;208;336;1 +349;208;352;2 +349;224;320;3 +349;224;336; +349;224;352;3 +349;224;368;2 +349;240;320; +349;240;368;2 +349;256;320;3 +349;256;368;2 +349;272;320; +349;272;336;1 +349;272;352;2 +349;272;368;1 +349;288;320;3 +349;288;336; +349;288;352;2 +349;304;320; +349;304;336;1 +349;304;352;1 +349;368;176; +349;384;176; +349;400;176; +349;400;208;2 +349;416;176; +349;416;208;2 +349;432;176; +349;432;208;2 +349;448;176; +349;448;208;2 +349;464;176; +349;464;192;1 +349;464;208;1 +330;272;62;d3_barrier +461;128;176 +461;128;224 +461;272;320 +461;432;176 +426;384;192 +426;448;224 +425;208;192 +423;32;208;; +423;112;192;; +423;192;336;; +423;240;320;; +423;256;176;; +423;256;208;; +423;272;352;; +423;288;176;; +423;288;208;; +252;144;200;d3_et_5 +252;248;112;d3_et_4 +252;248;288;d3_et_6 +341;80;160;;;;;; +341;80;176;;;;;; +341;80;192;;;;;; +341;80;208;;;;;; +341;80;224;;;;;; +341;80;240;;;;;; +341;240;336;;;;;; +341;256;336;;;;;; +200;48;208;w;;heart_3;; +168;128;120;d3_trigger_d3k4;d3_r4_entered&d3_et_5; +167;104;120;d3_r4_entered;0 +307;224;16;;;;; +307;224;144;;;;; +307;224;272;;;;; +307;272;16;;;;; +307;272;144;;;;; +307;272;272;;;;; +307;368;160;;;;; +307;448;160;;;;; +309;224;128;;;;; +309;224;256;;;;; +309;224;384;;;;; +309;272;128;;;;; +309;272;256;;;;; +309;272;384;;;;; +309;368;240;;;;; +309;448;240;;;;; +310;16;176;;;;; +310;16;224;;;;; +170;160;200;d3_r4_entered;;;; +287;80;416;21 +164;48;200;d3_trigger_d3k4;1;item;d.d3k4.smallkey.three;False +164;128;200;d3_trigger_d3k4;1;dialogBox;d3_spawn_4;False +164;208;64;d3_spawn_3;1;item;d.d3k3.smallkey.three;False +164;208;320;d3_spawn_5;1;item;d.d3k5.smallkey.three;False +164;248;96;d3_et_4;1;dialogBox;d3_spawn_3;False +164;248;304;d3_et_6;1;dialogBox;d3_spawn_5;False +231;192;48;;heart;;;; +231;240;352;;bomb_1;;;; +231;256;352;;bomb_1;;;; +231;304;48;;;;;; +413;192;80 +413;208;352 +437;304;80 diff --git a/bin/Data/Maps/dungeon3_2.map.data b/bin/Data/Maps/dungeon3_2.map.data new file mode 100644 index 0000000..cecf72c --- /dev/null +++ b/bin/Data/Maps/dungeon3_2.map.data @@ -0,0 +1,28 @@ +32 +26 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon3_2d.map b/bin/Data/Maps/dungeon3_2d.map new file mode 100644 index 0000000..6e3025d --- /dev/null +++ b/bin/Data/Maps/dungeon3_2d.map @@ -0,0 +1,660 @@ +3 +1 +1 +tileset 2d.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,15,104,15,15,15,15,15,15,15,15,58,15,15,15,15,15,15,15,15,15,, +,15,104,113,113,113,113,113,113,113,15,58,15,113,113,113,113,113,113,113,15,, +,15,104,15,15,15,113,113,15,104,15,15,15,113,113,113,113,113,113,113,15,, +,15,104,113,110,108,110,113,113,104,113,113,113,113,110,108,110,104,18,104,15,, +,15,104,113,108,113,108,113,113,104,113,113,113,113,108,113,108,104,18,104,15,, +,15,104,113,113,113,113,113,15,15,15,15,15,15,113,113,113,104,18,104,15,, +,15,15,15,99,99,99,99,15,58,58,58,58,15,99,99,99,99,18,104,15,, +,58,58,15,15,15,15,15,15,58,58,58,58,15,15,15,15,15,15,104,15,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +98 +0;16;16;;; +0;16;32;;; +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;32;112;;; +0;48;16;;; +0;48;48;;; +0;48;112;;; +0;64;16;;; +0;64;48;;; +0;64;128;;; +0;80;16;;; +0;80;48;;; +0;80;128;;; +0;96;16;;; +0;96;128;;; +0;112;16;;; +0;112;128;;; +0;128;16;;; +0;128;48;;; +0;128;96;;; +0;128;112;;; +0;144;16;;; +0;144;96;;; +0;160;32;;; +0;160;48;;; +0;160;96;;; +0;176;48;;; +0;176;96;;; +0;192;32;;; +0;192;48;;; +0;192;96;;; +0;208;16;;; +0;208;96;;; +0;208;112;;; +0;224;16;;; +0;224;128;;; +0;240;16;;; +0;240;128;;; +0;256;16;;; +0;256;128;;; +0;272;16;;; +0;272;128;;; +0;288;16;;; +0;288;64;;; +0;288;80;;; +0;288;96;;; +0;288;112;;; +0;304;16;;; +0;320;32;;; +0;320;48;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +0;320;112;;; +0;320;128;;; +286;-8;16;;;; +298;32;16;;;;;; +298;304;128;;;;;; +153;32;8;;;d3_2d_1;dungeon3_3.map;d3_2d_1;3;;False +153;304;136;;;d3_2d_2;dungeon3_4.map;d3_2d_2;1;;False +245;-8;88;three;False;-1 +258;32;16; +258;32;32; +258;32;48; +258;32;64; +258;32;80; +258;32;96; +258;144;48; +258;144;64; +258;144;80; +258;272;64; +258;272;80; +258;272;96; +258;304;64; +258;304;80; +258;304;96; +258;304;112; +258;304;128; +259;144;48; +259;272;64; +259;304;64; +490;96;32 +489;288;48 +303;80;80;;;;; +303;240;80;;;;; +257;-8;40 +287;-8;64;32 +348;64;112 +348;80;112 +348;96;112 +348;112;112 +348;224;112 +348;240;112 +348;256;112 +348;272;112 diff --git a/bin/Data/Maps/dungeon3_2d.map.data b/bin/Data/Maps/dungeon3_2d.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/dungeon3_2d.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon3_3.map b/bin/Data/Maps/dungeon3_3.map new file mode 100644 index 0000000..c920f4f --- /dev/null +++ b/bin/Data/Maps/dungeon3_3.map @@ -0,0 +1,1365 @@ +3 +1 +1 +dungeon 3.png +42 +34 +3 +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,28,44,44,44,44,29,,,28,44,44,44,44,44,44,44,44,29,28,44,44,44,44,44,44,44,44,29,28,44,44,44,44,44,29,,,,, +,,28,51,30,30,30,30,50,29,,43,30,30,30,30,30,30,30,30,46,43,30,30,0,0,0,30,30,30,46,43,30,30,30,30,30,50,44,29,,, +,28,51,30,30,30,30,30,30,50,29,43,30,30,30,25,25,25,25,30,46,43,30,30,0,0,0,30,30,30,33,36,30,30,30,30,30,30,30,50,29,, +,43,30,30,30,30,30,30,30,30,46,43,30,0,30,30,30,30,30,30,42,42,30,30,0,0,0,30,30,30,38,40,30,30,30,30,30,30,30,30,46,, +,43,30,30,30,30,30,30,30,30,46,43,30,30,30,30,30,30,30,30,46,43,30,30,30,30,30,30,30,30,46,43,30,30,30,30,30,30,30,30,46,, +,43,30,30,30,30,30,49,45,47,27,26,45,45,45,45,45,45,45,45,27,26,45,45,45,45,45,45,45,45,27,26,45,48,30,30,30,30,30,30,46,, +,43,30,30,30,30,30,46,24,30,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,17,43,30,30,30,30,49,45,27,, +,26,45,45,45,35,39,27,24,30,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,18,26,45,35,39,45,27,0,49,, +,28,44,44,44,34,37,29,18,30,16,30,28,44,44,44,44,44,44,44,29,28,44,44,44,44,44,44,29,30,30,28,44,44,44,34,37,44,29,0,46,, +,43,30,30,30,30,30,46,23,30,24,28,51,30,30,30,30,30,30,30,46,43,30,30,30,30,30,30,50,44,44,51,30,30,0,30,30,30,46,0,46,, +,43,30,30,30,30,30,46,23,30,24,43,30,30,30,30,30,30,30,30,33,36,30,30,30,30,30,30,30,30,30,30,30,30,0,30,30,30,46,0,46,, +,43,30,30,30,30,30,46,23,30,24,43,30,30,30,30,30,30,30,30,38,40,30,30,23,30,30,30,30,30,30,30,30,30,0,30,30,30,46,0,46,, +,43,30,30,30,30,30,46,23,30,24,43,30,30,30,30,30,30,30,30,50,51,25,25,23,30,30,30,30,30,30,30,0,0,0,0,0,30,46,54,46,, +,43,30,30,30,30,30,46,23,30,24,43,30,30,30,30,30,30,30,30,30,30,30,30,23,30,30,30,30,30,30,30,30,0,0,0,30,30,46,53,46,, +,43,30,30,30,30,30,46,23,30,24,26,45,45,47,48,30,30,30,30,49,45,48,30,23,30,30,30,30,30,30,30,30,30,0,30,30,30,46,0,46,, +,26,45,45,45,35,39,27,17,30,15,14,14,17,30,26,35,39,48,30,46,6,43,30,49,45,45,48,30,30,49,45,45,45,41,45,45,45,27,0,46,, +,28,44,44,44,34,37,29,24,30,14,14,14,30,30,28,34,37,51,30,46,6,43,30,50,44,44,51,30,30,46,28,44,44,41,44,44,44,29,0,46,, +,43,30,30,30,30,30,46,6,25,25,25,30,28,44,51,30,30,24,30,50,44,51,30,23,30,30,30,30,30,46,43,30,30,30,30,30,30,46,0,50,, +,43,30,30,30,30,30,50,44,44,29,28,47,51,30,30,30,30,24,30,30,30,7,30,23,30,30,30,30,30,46,43,30,30,30,30,30,30,50,47,29,, +,43,30,0,30,30,30,30,30,30,46,43,30,30,30,30,30,30,19,30,14,14,14,14,20,30,30,30,30,30,42,42,30,30,30,54,54,54,30,30,46,, +,43,30,30,30,30,30,30,30,30,33,36,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,46,43,30,30,30,53,53,53,30,30,46,, +,26,45,45,48,30,30,30,30,30,38,40,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,46,43,30,30,30,30,30,30,30,49,27,, +,,,6,43,30,30,30,30,30,46,43,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,46,43,30,30,30,30,30,30,30,46,,, +,,,,26,45,45,45,45,45,27,26,45,45,45,45,45,45,45,45,45,45,45,45,48,30,30,49,45,45,27,26,45,45,45,45,45,45,45,27,,, +,,,,,,,,,,,,,,,,,,,,,,28,44,51,30,30,50,44,29,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,28,51,30,30,30,30,30,30,50,29,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,43,30,30,30,30,30,30,30,30,46,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,43,30,0,49,45,47,48,30,30,46,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,43,30,30,46,7,30,43,30,30,46,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,43,30,30,50,44,44,51,30,30,46,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,43,30,30,30,30,30,30,30,30,46,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,26,45,45,45,45,45,45,45,45,27,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,, +,0,0,,,,,,,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,, +0,0,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0, +,,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +731 +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;16;160;;; +0;16;176;;; +0;16;192;;; +0;16;208;;; +0;16;224;;; +0;16;240;;; +0;16;288;;; +0;16;304;;; +0;16;320;;; +0;16;336;;; +0;32;48;;; +0;32;128;;; +0;32;144;;; +0;32;256;;; +0;32;272;;; +0;32;352;;; +0;48;32;;; +0;48;128;;; +0;48;144;;; +0;48;256;;; +0;48;272;;; +0;48;352;;; +0;64;16;;; +0;64;128;;; +0;64;144;;; +0;64;256;;; +0;64;272;;; +0;64;352;;; +0;64;368;;; +0;80;16;;; +0;80;384;;; +0;96;16;;; +0;96;384;;; +0;112;16;;; +0;112;288;;; +0;112;304;;; +0;112;384;;; +0;128;32;;; +0;128;304;;; +0;128;384;;; +0;144;48;;; +0;144;384;;; +0;160;64;;; +0;160;80;;; +0;160;320;;; +0;160;368;;; +0;176;32;;; +0;176;48;;; +0;176;64;;; +0;176;80;;; +0;176;320;;; +0;176;368;;; +0;192;16;;; +0;192;384;;; +0;208;16;;; +0;208;384;;; +0;224;16;;; +0;224;384;;; +0;240;16;;; +0;240;384;;; +0;256;16;;; +0;256;384;;; +0;272;16;;; +0;272;384;;; +0;288;16;;; +0;288;256;;; +0;288;272;;; +0;288;384;;; +0;304;16;;; +0;304;384;;; +0;320;32;;; +0;320;48;;; +0;320;80;;; +0;320;160;;; +0;320;208;;; +0;320;240;;; +0;320;256;;; +0;320;272;;; +0;320;288;;; +0;320;384;;; +0;336;32;;; +0;336;48;;; +0;336;80;;; +0;336;160;;; +0;336;208;;; +0;336;240;;; +0;336;288;;; +0;336;384;;; +0;336;432;;; +0;336;448;;; +0;336;464;;; +0;336;480;;; +0;336;496;;; +0;352;16;;; +0;352;240;;; +0;352;256;;; +0;352;272;;; +0;352;288;;; +0;352;384;;; +0;352;416;;; +0;352;512;;; +0;368;16;;; +0;368;384;;; +0;368;400;;; +0;368;512;;; +0;384;16;;; +0;384;256;;; +0;384;272;;; +0;384;384;;; +0;384;400;;; +0;384;512;;; +0;400;16;;; +0;400;256;;; +0;400;272;;; +0;400;512;;; +0;416;16;;; +0;416;256;;; +0;416;272;;; +0;416;512;;; +0;432;16;;; +0;432;256;;; +0;432;272;;; +0;432;384;;; +0;432;400;;; +0;432;512;;; +0;448;16;;; +0;448;384;;; +0;448;400;;; +0;448;512;;; +0;464;16;;; +0;464;384;;; +0;464;416;;; +0;464;512;;; +0;480;32;;; +0;480;80;;; +0;480;256;;; +0;480;272;;; +0;480;288;;; +0;480;304;;; +0;480;336;;; +0;480;352;;; +0;480;368;;; +0;480;432;;; +0;480;448;;; +0;480;464;;; +0;480;480;;; +0;480;496;;; +0;496;32;;; +0;496;80;;; +0;496;256;;; +0;496;288;;; +0;496;304;;; +0;496;336;;; +0;496;352;;; +0;496;368;;; +0;512;16;;; +0;512;256;;; +0;512;272;;; +0;512;384;;; +0;528;16;;; +0;528;144;;; +0;528;256;;; +0;528;272;;; +0;528;384;;; +0;544;16;;; +0;544;128;;; +0;544;144;;; +0;544;384;;; +0;560;16;;; +0;560;256;;; +0;560;272;;; +0;560;384;;; +0;576;16;;; +0;576;256;;; +0;576;272;;; +0;576;384;;; +0;592;32;;; +0;592;128;;; +0;592;144;;; +0;592;256;;; +0;592;272;;; +0;592;384;;; +0;608;32;;; +0;608;112;;; +0;608;384;;; +0;624;48;;; +0;624;352;;; +0;624;368;;; +0;640;64;;; +0;640;80;;; +0;640;96;;; +0;640;128;;; +0;640;144;;; +0;640;160;;; +0;640;176;;; +0;640;192;;; +0;640;208;;; +0;640;224;;; +0;640;240;;; +0;640;256;;; +0;640;272;;; +0;640;288;;; +0;640;304;;; +0;640;320;;; +0;640;336;;; +19;128;256;;; +19;208;256;;; +19;512;112;;; +20;160;144;;; +21;128;144;;; +21;512;128;;; +14;384;320;;; +1;160;352;;; +1;176;352;;; +1;320;192;;; +1;336;192;;; +1;480;64;;; +1;496;64;;; +3;80;128;;; +3;80;144;;; +3;80;256;;; +3;80;272;;; +3;256;256;;; +3;256;272;;; +3;560;128;;; +3;560;144;;; +4;272;256;;; +4;272;272;;; +4;576;128;;; +4;576;144;;; +2;160;336;;; +2;176;336;;; +2;320;176;;; +2;336;176;;; +2;480;48;;; +2;496;48;;; +15;288;320;;; +18;160;256;;; +199;400;48;compass;three;d3_compass;; +199;400;176;pegasusBoots;;d3_boots;; +199;624;160;nightmarekey;three;d3_nkey;; +289;32;320;d3k6 +289;224;64;d3k7 +289;352;464;d3k8 +289;584;168;d3_nkey +261;160;344;;d3_l3_door_1;; +261;176;344;;d3_l3_door_1;2; +261;264;256;;d3_l3_door_2;1; +261;264;272;;d3_l3_door_2;3; +261;320;184;;d3_l3_door_3;; +261;336;184;;d3_l3_door_3;2; +261;480;56;;d3_l3_door_5;; +261;496;56;;d3_l3_door_5;2; +261;568;128;;d3_l3_door_4;1; +261;568;144;;d3_l3_door_4;3; +153;352;304;;;d3_2d_1;dungeon3_2d.map;d3_2d_1;2;1;False +153;400;464;;;d3_2;dungeon3_2.map;d3_2;2;1;False +245;48;544;three;;2 +284;16;544;;220;200;175 +331;88;128 +331;88;256 +350;80;17;d3_beak_2 +350;544;145;d3_beak_3 +322;336;64;;d3_wall_3;2;; +322;480;320;;d3_wall_2;;; +322;544;256;;d3_wall_1;1;; +323;320;64;;d3_wall_3;;; +323;496;320;;d3_wall_2;2;; +323;544;272;;d3_wall_1;3;; +440;48;80 +440;96;32 +440;192;80 +440;224;80 +440;304;32 +441;528;32 +441;592;48 +441;608;80 +461;48;304 +461;112;352 +424;48;208 +424;96;192 +424;240;340 +425;224;336 +425;240;320 +425;240;352 +425;256;336 +423;64;320;; +423;112;320;; +423;352;432;; +423;368;416;; +423;384;48;; +423;416;64;; +423;432;80;; +423;432;432;; +423;464;432;; +423;464;496;; +423;528;192;; +423;544;64;; +423;608;64;; +252;48;336;d3_et_8 +252;64;192;d3_et_9 +252;200;360;d3_et_10 +252;208;48;d3_et_13 +252;208;176;d3_et_11 +252;368;464;d3_et_7 +252;520;72;d3_et_12 +22;224;242;;;; +22;320;184;;;; +341;560;320;;;;;; +341;560;336;;;;;; +341;576;320;;;;;; +341;576;336;;;;;; +341;592;320;;;;;; +341;592;336;;;;;; +341;624;208;;;;;; +341;624;224;;;;;; +274;416;238;;;; +274;432;238;;;; +200;80;64;w;;bomb_10;; +200;400;240;w;;heart_3;; +162;224;288;;18;;8;;;;; +162;416;480;;18;;8;;;;; +162;432;464;18;2;8;32;;;;; +162;616;160;-18;2;8;48;;;;; +162;616;240;-18;2;8;;;;;; +162;616;288;-18;2;8;;;;;; +162;624;120;;-18;;8;;;;; +168;256;416;d3_l3_door_1;d3_et_10; +168;272;240;d3_l3_door_2;d3_et_10&!d3_l3_enter_1|d3_et_10&d3_et_11; +168;304;192;d3_l3_door_3;!d3_l3_enter_1|d3_et_11; +168;488;-8;d3_l3_door_5;!d3_l3_enter_2|d3_et_12; +168;664;136;d3_l3_door_4;!d3_l3_enter_2|d3_et_12; +333;304;224;d3_lock_2 +333;304;304;d3_lock_1 +333;368;224;d3_lock_3 +333;368;304;d3_lock_4 +167;224;416;d3_et_10;0 +167;256;240;d3_l3_enter_1;0 +167;664;112;d3_et_12;0 +167;688;112;d3_l3_enter_2;0 +302;48;368;;;;; +302;128;288;;;;; +302;352;448;;;;; +302;384;416;;;;; +302;432;416;;;;; +302;464;448;;;;; +307;64;16;;;;; +307;112;16;;;;; +307;208;16;;;;; +307;224;144;;;;; +307;288;16;;;;; +307;288;144;;;;; +307;368;16;;;;; +307;368;144;;;;; +307;400;272;;;;; +307;416;144;;;;; +307;416;272;;;;; +307;448;16;;;;; +308;112;176;;;;; +308;112;224;;;;; +308;480;304;;;;; +308;480;336;;;;; +308;608;176;;;;; +308;608;224;;;;; +309;224;384;;;;; +309;272;384;;;;; +310;16;176;;;;; +310;16;224;;;;; +310;176;320;;;;; +310;176;368;;;;; +310;496;32;;;;; +310;496;80;;;;; +170;224;272;d3_l3_enter_1;3;;;True +170;264;256;d3_l3_enter_1;1;;; +170;336;184;d3_l3_reset_stone;;;; +170;448;256;d3_l3_reset_stone;3;32;; +170;568;128;d3_l3_enter_2;1;;; +10;144;288;;; +10;160;128;;; +10;160;288;;; +10;176;128;;; +10;176;288;;; +10;192;128;;; +10;208;128;;; +10;224;128;;; +10;240;48;;; +10;240;128;;; +10;256;48;;; +10;256;128;;; +10;272;48;;; +10;272;128;;; +10;288;48;;; +10;288;128;;; +10;304;128;;; +10;320;128;;; +10;336;128;;; +10;352;128;;; +10;352;208;;; +10;368;128;;; +10;368;208;;; +10;384;128;;; +10;400;128;;; +10;416;128;;; +10;432;128;;; +10;448;128;;; +10;464;128;;; +10;480;128;;; +10;496;128;;; +11;160;112;;; +11;160;272;;; +11;176;112;;; +11;176;256;;; +11;176;272;;; +11;192;112;;; +11;192;256;;; +11;192;272;;; +11;208;112;;; +11;224;112;;; +11;240;112;;; +11;256;112;;; +11;272;112;;; +11;288;112;;; +11;304;112;;; +11;320;112;;; +11;320;320;;; +11;336;112;;; +11;336;320;;; +11;352;112;;; +11;352;320;;; +11;368;112;;; +11;368;320;;; +11;384;112;;; +11;400;112;;; +11;416;112;;; +11;432;112;;; +11;448;112;;; +11;464;112;;; +11;480;112;;; +11;496;112;;; +12;128;160;;; +12;128;176;;; +12;128;192;;; +12;128;208;;; +12;128;224;;; +12;128;240;;; +12;384;192;;; +12;384;208;;; +12;384;224;;; +12;384;240;;; +12;384;288;;; +12;384;304;;; +13;128;112;;; +13;128;128;;; +13;128;272;;; +13;160;160;;; +13;160;176;;; +13;160;192;;; +13;160;208;;; +13;160;224;;; +13;160;240;;; +13;288;288;;; +13;288;304;;; +25;104;128;;;; +25;104;144;;;; +25;104;256;;;; +25;104;272;;;; +25;112;96;;;; +25;112;112;;;; +25;112;128;;;; +25;112;144;;;; +25;112;160;;;; +25;112;176;;;; +25;112;192;;;; +25;112;208;;;; +25;112;224;;;; +25;112;240;;;; +25;112;256;;;; +25;112;272;;;; +25;128;96;;;; +25;144;304;;;; +25;160;96;;;; +25;160;304;;;; +25;176;96;;;; +25;176;176;;;; +25;176;192;;;; +25;176;208;;;; +25;176;224;;;; +25;176;304;;;; +25;192;96;;;; +25;192;160;;;; +25;192;240;;;; +25;208;96;;;; +25;208;144;;;; +25;208;240;;;; +25;208;288;;;; +25;208;304;;;; +25;224;96;;;; +25;224;144;;;; +25;224;288;;;; +25;240;96;;;; +25;240;144;;;; +25;240;240;;;; +25;240;256;;;; +25;240;272;;;; +25;240;288;;;; +25;256;96;;;; +25;256;144;;;; +25;272;96;;;; +25;272;144;;;; +25;288;96;;;; +25;288;144;;;; +25;304;96;;;; +25;304;144;;;; +25;320;96;;;; +25;320;144;;;; +25;336;96;;;; +25;336;144;;;; +25;352;96;;;; +25;352;144;;;; +25;368;96;;;; +25;368;144;;;; +25;384;96;;;; +25;384;144;;;; +25;384;448;;;; +25;384;464;;;; +25;384;480;;;; +25;400;96;;;; +25;400;144;;;; +25;400;448;;;; +25;400;480;;;; +25;416;96;;;; +25;416;144;;;; +25;416;480;;;; +25;432;96;;;; +25;432;144;;;; +25;432;448;;;; +25;432;464;;;; +25;432;480;;;; +25;448;96;;;; +25;448;160;;;; +25;464;96;;;; +25;464;160;;;; +25;480;96;;;; +25;480;160;;;; +25;496;96;;;; +25;496;160;;;; +25;512;96;;;; +25;512;144;;;; +25;528;96;;;; +25;528;112;;;; +25;528;128;;;; +25;608;128;;;; +25;608;144;;;; +25;608;160;;;; +25;608;176;;;; +25;608;192;;;; +25;608;208;;;; +25;608;224;;;; +25;608;240;;;; +25;608;256;;;; +25;608;272;;;; +25;608;288;;;; +25;608;304;;;; +25;624;112;;;; +499;224;176;d3_snake0;; +499;256;176;d3_snake1;; +226;192;320;8;;;;;;; +226;208;272;0;;;;;;; +226;288;208;;;;;;;; +226;288;224;;;;;;;; +226;288;240;;;;;;;; +226;304;208;;;;;;;; +226;320;304;;;;;;;; +226;336;304;;;;;;;; +226;384;176;0;;;;;;; +226;416;176;0;;;;;;; +226;416;224;0;;;;;;; +226;432;192;;;;;;;;d3_l3_reset_stone +226;432;208;;;;;;;;d3_l3_reset_stone +226;432;224;0;;;;;;; +226;448;224;0;;;;;;; +226;448;240;;;;;;;;d3_l3_reset_stone +226;464;176;0;;;;;;; +226;464;192;0;;;;;;; +226;464;208;0;;;;;;; +226;464;224;0;;;;;;; +226;560;304;0;;;;;;; +226;560;352;0;;;;;;; +226;576;304;0;;;;;;; +226;576;352;0;;;;;;; +226;592;304;0;;;;;;; +226;592;352;0;;;;;;; +226;608;352;0;;;;;;; +287;80;544;21 +164;248;192;d3_et_11;1;dungeonTeleporter;dungeon3_1$map.d3_teleporter;False +164;288;416;d3_et_10;1;dialogBox;d3_sound;False +164;520;48;d3_et_12;1;dialogBox;sound_secrete; +166;48;320;d3_et_8;1;d3_spawn_7 +166;144;176;d3_et_9;1;d3_spawn_8 +166;208;64;d3_et_13;1;d3_spawn_9 +166;368;448;d3_et_7;1;d3_spawn_6 +231;64;64;;;;;; +231;80;48;;;;;; +231;80;80;;;;;; +231;96;48;;;;;; +231;96;80;;;;;; +231;112;64;;;;;; +231;240;64;;;;;; +231;240;80;;fairy;;;; +231;256;64;;;;;; +231;256;80;;;;;; +231;368;368;;;;;; +231;384;368;;;;;; +231;448;352;;;;;; +231;448;368;;heart;;;; +231;464;352;;;;;; +231;464;368;;bomb_1;;;; +231;592;368;;heart;;;; +231;608;368;;heart;;;; +413;368;64 +413;400;304 +413;448;336 +413;528;368 +413;560;368 +160;144;96; +160;192;304; +160;224;240; +160;416;448; +160;624;304; +437;64;176 +437;544;160 +437;592;208 +414;128;64 +246;128;160; +246;128;176; +246;128;192; +246;128;208; +246;128;224; +246;128;240; +246;144;96; +246;144;112; +246;144;128; +246;144;144; +246;144;160; +246;144;176; +246;144;192; +246;144;208; +246;144;224; +246;144;240; +246;144;256; +246;144;272; +246;144;288; +246;160;112; +246;160;128; +246;160;160; +246;160;176; +246;160;192; +246;160;208; +246;160;224; +246;160;240; +246;160;272; +246;160;288; +246;176;112; +246;176;128; +246;176;272; +246;176;288; +246;192;112; +246;192;128; +246;192;272; +246;192;288; +246;192;304; +246;208;112; +246;208;128; +246;224;112; +246;224;128; +246;224;240; +246;224;256; +246;224;272; +246;240;112; +246;240;128; +246;256;112; +246;256;128; +246;272;112; +246;272;128; +246;288;112; +246;288;128; +246;304;112; +246;304;128; +246;320;112; +246;320;128; +246;336;112; +246;336;128; +246;352;112; +246;352;128; +246;368;112; +246;368;128; +246;384;112; +246;384;128; +246;400;112; +246;400;128; +246;400;464; +246;416;112; +246;416;128; +246;416;448; +246;416;464; +246;432;112; +246;432;128; +246;448;112; +246;448;128; +246;464;112; +246;464;128; +246;480;112; +246;480;128; +246;496;112; +246;496;128; +246;512;112; +246;512;128; +246;624;128; +246;624;144; +246;624;160; +246;624;176; +246;624;192; +246;624;240; +246;624;256; +246;624;272; +246;624;288; +246;624;304; diff --git a/bin/Data/Maps/dungeon3_3.map.data b/bin/Data/Maps/dungeon3_3.map.data new file mode 100644 index 0000000..69f447c --- /dev/null +++ b/bin/Data/Maps/dungeon3_3.map.data @@ -0,0 +1,36 @@ +42 +34 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon3_4.map b/bin/Data/Maps/dungeon3_4.map new file mode 100644 index 0000000..a931988 --- /dev/null +++ b/bin/Data/Maps/dungeon3_4.map @@ -0,0 +1,873 @@ +3 +1 +2 +dungeon 3.png +22 +27 +3 +,,,,,,,,,,,,,,,,,,,,,, +,,,,46,30,30,43,,,,,,,,,,,,,,, +,28,44,29,50,44,44,51,28,44,29,,,,,,,,,,,, +,43,30,46,0,0,0,0,43,30,46,,,,,,,,,,,, +,43,30,46,0,0,0,0,43,30,46,,,,,,,,,,,, +,43,30,46,0,0,0,0,43,30,46,,,,,,,,,,,, +,43,30,50,44,47,47,44,51,30,46,,,,,,,,,,,, +,43,30,30,30,0,0,30,30,30,46,,,,,,,,,,,, +,43,30,30,30,0,0,30,30,30,46,,,,,,,,,,,, +,26,45,45,45,35,39,45,45,45,27,,,,,,,,,,,, +,28,44,44,44,34,37,44,44,44,29,,,,,,,,,,,, +,43,30,30,30,30,30,30,30,30,46,,,,,,,,,,,, +,43,30,30,30,30,30,30,30,30,46,,,,,,,,,,,, +,43,30,30,30,30,30,30,30,30,46,,,,,,,,,,,, +,43,30,30,30,30,30,30,30,30,46,,,,,,,,,,,, +,43,30,30,30,30,30,30,30,30,46,,,,,,,,,,,, +,43,30,30,30,30,30,30,30,30,46,,,,,,,,,,,, +,26,45,45,45,35,39,45,45,45,27,,,,,,,,,,,, +,28,44,44,44,34,37,44,44,44,29,28,44,44,44,44,44,44,44,44,29,, +,43,30,30,30,30,30,30,30,30,46,43,30,30,30,30,30,30,30,8,46,, +,43,30,30,30,30,30,30,30,30,46,43,30,30,30,30,30,30,30,30,46,, +,43,30,30,30,30,30,30,30,30,33,36,30,30,30,30,30,30,30,30,46,, +,43,30,30,30,30,30,30,30,30,38,40,30,30,30,30,30,30,30,30,46,, +,43,30,30,30,30,30,30,30,30,46,43,30,30,30,30,30,30,30,30,46,, +,43,30,30,30,30,30,30,30,30,46,43,30,30,30,30,30,30,30,30,46,, +,26,45,45,45,45,45,45,45,45,27,26,45,45,45,45,45,45,45,45,27,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,0,0,0,0,0,0,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,,,,,,,,,,, +0,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +524 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +waterfallSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +259 +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;16;128;;; +0;16;176;;; +0;16;192;;; +0;16;208;;; +0;16;224;;; +0;16;240;;; +0;16;256;;; +0;16;304;;; +0;16;320;;; +0;16;336;;; +0;16;352;;; +0;16;368;;; +0;16;384;;; +0;32;32;;; +0;32;144;;; +0;32;160;;; +0;32;272;;; +0;32;288;;; +0;32;400;;; +0;48;48;;; +0;48;144;;; +0;48;160;;; +0;48;272;;; +0;48;288;;; +0;48;400;;; +0;64;32;;; +0;64;144;;; +0;64;160;;; +0;64;272;;; +0;64;288;;; +0;64;400;;; +0;80;32;;; +0;80;400;;; +0;96;32;;; +0;96;400;;; +0;112;32;;; +0;112;144;;; +0;112;160;;; +0;112;272;;; +0;112;288;;; +0;112;400;;; +0;128;48;;; +0;128;144;;; +0;128;160;;; +0;128;272;;; +0;128;288;;; +0;128;400;;; +0;144;32;;; +0;144;144;;; +0;144;160;;; +0;144;272;;; +0;144;288;;; +0;144;400;;; +0;160;48;;; +0;160;64;;; +0;160;80;;; +0;160;96;;; +0;160;112;;; +0;160;128;;; +0;160;176;;; +0;160;192;;; +0;160;208;;; +0;160;224;;; +0;160;240;;; +0;160;256;;; +0;160;304;;; +0;160;320;;; +0;160;368;;; +0;160;384;;; +0;176;304;;; +0;176;320;;; +0;176;368;;; +0;176;384;;; +0;192;288;;; +0;192;400;;; +0;208;288;;; +0;208;400;;; +0;224;288;;; +0;224;400;;; +0;240;288;;; +0;240;400;;; +0;256;288;;; +0;256;400;;; +0;272;288;;; +0;272;400;;; +0;288;288;;; +0;288;400;;; +0;304;288;;; +0;304;400;;; +0;320;304;;; +0;320;320;;; +0;320;336;;; +0;320;352;;; +0;320;368;;; +0;320;384;;; +1;160;352;;; +1;176;352;;; +3;80;144;;; +3;80;160;;; +3;80;272;;; +3;80;288;;; +4;96;144;;; +4;96;160;;; +4;96;272;;; +4;96;288;;; +2;160;336;;; +2;176;336;;; +289;48;320;d3_spawn_10 +261;88;144;2;d3_ndoor_2;1; +261;88;160;2;d3_ndoor_2;3; +261;88;272;2;d3_ndoor_1;1; +261;88;288;3;d3_ndoor_1;3;d3_ndoor_keyhole +261;160;344;;d3_l4_door;;d3_ndoor_keyhole +261;176;344;;d3_l4_door;2;d3_ndoor_keyhole +153;304;304;;;d3_2d_2;dungeon3_2d.map;d3_2d_2;;1;False +245;48;432;three;;3 +62;32;384;;;;;; +62;48;352;;;;;; +62;48;384;;;;;; +62;64;48;;;;;; +62;64;80;;;;;; +62;64;304;;;;;; +62;80;336;;;;;; +62;80;368;;;;;; +62;96;320;;;;;; +62;96;368;;;;;; +62;112;48;;;;;; +62;112;80;;;;;; +62;112;352;;;;;; +62;128;320;;;;;; +62;128;336;;;;;; +62;128;384;;;;;; +62;144;368;;;;;; +62;144;384;;;;;; +284;16;432;;220;200;175 +350;32;304;3 +350;32;320;2 +350;32;336;2 +350;32;352;1 +350;32;368;1 +350;48;304; +350;48;320;1 +350;48;336;1 +350;48;368; +350;64;320;2 +350;64;336;3 +350;64;352;2 +350;64;368;1 +350;64;384;1 +350;80;304;2 +350;80;320;1 +350;80;352;2 +350;80;384; +350;96;304;2 +350;96;336;2 +350;96;352;1 +350;96;384; +350;112;304;2 +350;112;320;1 +350;112;336;1 +350;112;368;3 +350;112;384; +350;128;304;2 +350;128;352;3 +350;128;368; +350;144;304;3 +350;144;320;3 +350;144;336;3 +350;144;352; +462;208;336 +462;256;304 +462;288;384 +427;48;352 +427;64;304 +427;96;320 +427;96;368 +427;128;384 +252;16;288;d3_et_15 +252;272;344;d3_et_14 +274;192;304;;;; +274;192;320;;;; +274;192;368;;;; +274;192;384;;;; +274;208;320;;;; +274;224;336;;;; +274;224;368;;;; +274;224;384;;;; +274;240;336;;;; +274;240;368;;;; +274;256;320;;;; +274;272;304;;;; +274;272;320;;;; +274;272;368;;;; +274;272;384;;;; +274;304;336;;;; +274;304;352;;;; +253;24;168;512;d3_nwall_hit;144;112;;; +200;88;72;;d3_instrument;instrument2;; +200;240;336;w;;heart_3;; +162;56;64;-18;2;8;;;;;; +162;128;64;18;2;8;;;;;; +168;160;424;d3_l4_door;d3_et_14; +168;184;152;d3_ndoor_2;d3_heartMeter&(!d3_enter_Instrument|d3_instrument); +168;184;192;d3_heart;d3_nightmare&!d3_ndoor_enter; +168;184;264;d3_ndoor_1;d3_ndoor_keyhole&!d3_ndoor_enter|d3_heartMeter; +167;-16;160;d3_nwall_hit;0 +167;176;424;d3_et_14;0 +167;208;128;d3_enter_Instrument;0 +167;208;264;d3_ndoor_enter;0 +303;32;48;;;;; +303;32;128;;;;; +303;32;176;;;;; +303;32;256;;;;; +303;144;48;;;;; +303;144;128;;;;; +303;144;176;;;;; +303;144;256;;;;; +308;64;160;;;;; +308;64;288;;;;; +308;112;160;;;;; +308;112;288;;;;; +310;64;144;;;;; +310;112;144;;;;; +311;176;320;;;;; +311;176;368;;;;; +170;88;144;d3_enter_Instrument;1;;; +170;88;272;d3_ndoor_enter;1;;; +25;48;64;;;; +25;48;80;;;; +25;48;96;;;; +25;64;96;;;; +25;112;96;;;; +25;128;64;;;; +25;128;80;;;; +25;128;96;;;; +287;80;432;21 +516;80;208;d3_ndoor_enter;d3_nwall_hit;d3_nightmare +164;0;336;d3_et_15;1;dialogBox;d3_spawn_10;False +164;48;336;d3_spawn_10;1;item;d.d3k9.smallkey.three;False +164;88;200;d3_heart;1;item;j.d3_heartMeter.heartMeterFull.;False +164;184;128;d3_enter_Instrument;1;dialogBox;d3_instrument_music; +164;200;424;d3_et_14;1;dialogBox;sound_secrete; +160;80;96; +160;96;96; +246;64;64; +246;80;48; +246;80;64; +246;80;80; +246;80;96; +246;96;48; +246;96;64; +246;96;80; +246;96;96; +246;112;64; diff --git a/bin/Data/Maps/dungeon3_4.map.data b/bin/Data/Maps/dungeon3_4.map.data new file mode 100644 index 0000000..e0cd223 --- /dev/null +++ b/bin/Data/Maps/dungeon3_4.map.data @@ -0,0 +1,29 @@ +22 +27 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon4.map b/bin/Data/Maps/dungeon4.map new file mode 100644 index 0000000..9d7dbb1 --- /dev/null +++ b/bin/Data/Maps/dungeon4.map @@ -0,0 +1,3323 @@ +3 +1 +1 +dungeon 4.png +62 +58 +3 +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,15,23,14,3,3,3,15,23,14,,15,23,23,23,23,23,23,23,23,14,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,22,36,20,47,43,46,22,36,20,,22,36,36,36,36,36,36,2,36,20,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,22,36,20,41,36,42,22,36,34,14,22,36,36,36,36,36,36,2,36,20,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,22,36,20,44,36,45,22,36,36,30,31,2,36,36,36,36,36,2,36,20,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,22,36,34,23,48,23,33,36,36,27,26,2,36,36,36,36,36,2,36,20,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,22,36,36,36,36,36,36,36,35,13,22,36,36,36,36,36,36,36,36,20,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,22,36,36,36,36,36,36,36,20,3,22,36,36,36,2,2,36,36,36,20,,,,,,,,,,,,,,,,,,,,,, +,,,,20,3,3,22,,,,,,,,,,,,,,12,21,21,21,24,28,21,21,13,3,12,21,21,21,24,28,21,21,21,13,,,,,,,,,,,,,,,,,,,,,, +,15,23,14,34,23,23,33,15,23,14,,,,,,,,,,,15,23,23,23,25,29,23,23,23,14,15,23,23,23,25,29,23,23,23,14,,,,,,,,,,,,15,23,23,23,23,23,23,23,14,, +,22,36,20,2,2,2,2,22,36,20,,,,,,,,,,,22,36,36,36,36,36,36,36,36,20,22,,,,,,,,,20,,,,,,,,,,,,22,,,,,,,,20,, +,22,36,20,2,2,2,2,22,36,20,,,,,,,,,,,22,36,16,36,36,36,36,16,36,20,22,,,,,,,,,20,,,,,,,,,,,,22,,,,36,,,,20,, +,22,36,20,2,2,2,2,22,36,20,,,,,,,,,,,22,36,36,36,36,16,36,36,36,20,22,,,35,21,21,32,,,20,,,,,,,,,,,,22,,,,,,,,20,, +,22,36,34,23,48,48,23,33,36,20,,,,,,,,,,,22,36,16,36,36,36,36,16,36,20,22,,,34,23,23,33,,,20,,,,,,,,,,,,22,,,,36,,,,20,, +,22,36,36,36,2,2,36,36,36,20,,,,,,,,,,,22,36,36,36,36,36,36,36,36,20,22,,,,,,,,,20,,,,,,,,,,,,22,,,,,,,,20,, +,22,36,36,36,2,2,36,36,36,20,,,,,,,,,,,22,43,43,35,21,21,32,36,36,20,22,,,,,,,,,20,,,,,,,,,,,,22,,,,,,,,20,, +,12,21,21,21,24,28,21,21,21,13,,,,,,,,,,,22,36,36,20,3,3,22,36,36,20,12,21,21,21,24,28,21,21,21,13,,,,,,,,,,,,12,21,21,32,,35,21,21,13,, +,,,,15,25,29,14,,,,15,23,23,23,23,23,23,23,23,14,22,36,36,20,3,3,22,36,36,20,15,23,23,23,25,29,23,23,23,23,23,23,23,23,23,23,23,23,23,14,,15,23,23,33,,34,23,23,14,, +,,,,22,36,36,20,,,,22,,,,,,,,,20,22,2,2,20,3,3,22,36,36,20,22,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,2,2,2,20,,22,,,,,,,,20,, +,,,15,33,36,36,34,14,,,22,,16,,,,,16,,34,33,2,2,20,3,3,22,36,36,20,22,36,40,36,36,36,36,40,36,36,36,36,36,36,36,36,2,4,2,20,,22,,,,,,,,20,, +,,,22,2,2,2,2,20,,,22,,,,,16,,,,36,36,2,2,20,3,3,22,36,36,20,22,42,51,41,36,36,42,51,41,36,36,36,36,36,36,36,2,2,2,20,,22,,,,,,,,20,, +,,,22,2,4,2,2,20,,,22,,16,,,,,16,,36,36,36,36,34,14,3,22,36,36,34,33,36,43,36,36,36,36,43,36,35,21,21,21,32,36,36,36,36,36,20,15,33,,,,,,,,20,, +,,,22,2,2,2,2,20,,,22,,,,,,,,36,35,32,36,36,36,34,23,33,36,36,,,,36,36,36,36,36,36,36,20,47,43,46,22,36,36,36,36,36,20,22,,,,,,,,36,20,, +,,,12,32,36,36,35,13,,,22,,,,,,,,36,20,22,36,36,36,36,36,36,36,,,,,36,36,36,36,36,36,36,20,41,36,42,22,36,36,36,36,36,20,22,,,,,,,,36,20,, +,,,,12,24,28,13,,,,12,21,21,21,21,32,36,35,21,13,12,21,21,21,21,21,21,21,21,21,32,36,36,36,36,36,36,35,21,13,41,36,42,22,36,36,36,36,36,20,22,,,,,,,,36,20,, +,15,23,23,23,25,29,23,23,23,14,15,23,14,3,15,33,36,34,23,14,15,23,23,23,23,23,23,23,23,23,33,36,36,36,36,36,36,20,47,43,38,36,42,22,36,36,36,36,36,20,22,,,,,,,,,20,, +,22,53,52,52,36,36,52,52,52,34,33,4,20,3,22,36,36,36,36,20,22,4,36,36,36,,,,,,,36,36,,,,,20,41,37,40,36,45,22,36,36,36,36,36,20,22,,36,,,,,,,20,, +,22,53,36,36,36,36,36,36,36,36,36,36,20,3,22,2,2,2,36,20,22,36,36,36,,,,,,,,,,,36,36,,20,41,42,15,48,23,33,36,50,36,36,36,34,33,36,36,,,,,,,20,, +,22,53,36,36,36,36,36,36,50,35,21,21,13,3,22,2,2,2,36,20,22,36,36,35,21,32,36,,,,,,,,,36,,20,41,42,22,36,36,36,49,53,49,36,36,36,36,36,36,,,,,36,,20,, +,22,53,36,36,36,36,36,36,53,20,3,3,3,3,22,2,2,2,36,20,22,36,36,20,3,22,,,,,,,,36,,,,20,41,42,22,50,50,36,36,52,36,36,36,35,32,36,36,,,,36,36,,20,, +,22,53,36,36,36,36,36,36,53,34,23,23,23,23,33,36,36,36,36,20,22,36,36,20,3,22,,,,,,,36,36,36,,,20,41,42,22,53,53,50,36,36,36,36,36,20,22,36,,,,,,,,20,, +,22,53,50,50,50,50,50,50,52,36,36,36,36,36,36,36,36,36,36,20,22,36,36,20,3,22,,,,,,,36,36,36,,,20,41,42,22,52,52,52,36,36,36,36,36,20,22,36,,,,,,,,20,, +,12,21,21,21,21,21,21,21,21,21,32,36,36,36,36,36,36,36,36,20,12,24,28,13,3,22,,,,36,36,,36,36,36,,,20,41,42,12,21,21,32,36,36,36,36,36,20,12,21,21,21,21,21,21,21,21,13,, +,,,,,,,,,,,22,36,36,36,36,36,36,36,36,20,15,25,29,14,3,22,,,,36,36,36,36,36,36,,,20,41,42,15,23,23,33,36,36,36,36,36,20,,,,,,,,,,,, +,,,,,,,,,,,22,36,36,,,,,,,20,22,36,36,20,3,22,,,,,,,,36,36,36,,20,41,42,22,,,,36,36,36,36,,20,,,,,,,,,,,, +,,,,,,,,,,,22,36,36,,,,,,,34,33,,,34,23,33,,,,,,,,,,,,20,41,42,22,36,,,,,,36,,20,,,,,,,,,,,, +,,,,,,,,,,,12,21,21,21,21,32,,,,,,,,,,,,,,,,,,,,,,20,41,42,22,2,2,,,,,,,20,,,,,,,,,,,, +,,,,,,,,,,,47,43,43,36,42,22,,,,,,,,,,,,,,,,,,,,,,20,41,42,22,2,2,,,,,,,20,,,,,,,,,,,, +,,,,,,,,,,,41,2,2,2,42,22,,,,,,,,,,35,21,21,21,21,21,21,21,21,21,21,21,13,41,42,22,,,,,,,,,20,,,,,,,,,,,, +,,,,,,,,,,,41,2,4,2,42,22,,,,,,,,,,20,47,43,43,43,43,43,43,43,43,43,43,43,38,42,22,,,,,,,,,20,,,,,,,,,,,, +,,,,,,,,,,,41,2,2,2,42,12,21,21,21,21,21,21,21,21,21,13,41,36,36,36,36,36,36,36,36,36,36,36,36,42,12,21,21,21,21,21,24,28,21,13,,,,,,,,,,,, +,,,,,,,,,,,41,2,2,2,42,43,43,43,43,43,43,43,43,43,43,43,38,36,36,36,36,36,36,36,36,36,36,36,36,39,43,43,46,15,23,23,25,29,23,14,,,,,,,,,,,, +,,,,,,,,,,,41,2,2,2,42,40,40,40,40,40,40,40,40,40,40,36,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,36,45,22,2,36,,,,20,,,,,,,,,,,, +,,,,,,,,,,,41,2,2,2,42,15,23,23,23,23,23,23,23,23,23,48,23,23,23,14,15,23,23,23,23,23,23,23,23,14,15,48,23,33,2,36,,,,20,,,,,,,,,,,, +,,,,,,,,,,,44,40,40,40,45,22,,,,,,,,,,,,,,20,22,,,,,2,2,2,36,20,22,2,2,2,2,36,,,,20,,,,,,,,,,,, +,,,,,,,,,,,15,23,23,23,23,33,,,36,,,36,,,36,,,36,,30,31,,,36,,,2,2,36,20,22,36,36,36,36,,,,,20,,,,,,,,,,,, +,,,,,,,,,,,22,36,,,,,,,,,,,,,,,,,,27,26,,,,,2,,2,36,30,31,36,,,,,,,,20,,,,,,,,,,,, +,,,,,,,,,,,22,36,,,,,,,,,,,,,,,,,,20,22,,,,,,,,,27,26,36,,,,,,,,20,,,,,,,,,,,, +,,,,,,,,,,,12,21,21,21,21,21,21,21,21,21,21,21,21,32,,,35,21,21,13,12,21,21,21,24,28,21,21,21,13,12,21,21,21,21,21,21,21,21,13,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,15,23,23,33,,,34,23,23,14,15,23,23,23,25,29,23,23,23,14,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,22,,,,,,,,,20,22,,,,,,,,,20,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,22,,,36,,,36,,,20,22,,,,,,,,,20,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,22,,,36,,,36,,,20,22,,,36,36,36,36,36,,20,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,22,,,36,36,36,36,,,20,22,,,36,36,36,36,36,,20,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,22,,36,11,9,9,10,36,,20,22,,,36,36,36,36,36,,20,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,22,,36,18,8,7,17,36,,20,22,,,,,,,,,20,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,12,21,21,6,1,0,5,21,21,13,12,21,21,21,21,21,21,21,21,13,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,0,0,0,0,0,0,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0, +0,,,,,,,,,,,0,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,0,,,,,,,,,,0, +0,,,,,,,,,,,0,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,0,,,,,,,,,,0, +0,,,,,,,,,,,0,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,0,,,,,,,,,,0, +0,,,,,,,,,,,0,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,0,,,,,,,,,,0, +0,,,,,,,,,,,0,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,0,,,,,,,,,,0, +0,,,,,,,,,,,0,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,0,,,,,,,,,,0, +0,,,,,,,,,,,0,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,0,,,,,,,,,,0, +0,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,0, +0,0,0,0,,,,,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,0, +,,0,0,,,,,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,0, +,,0,,,,,,,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,0, +,,0,,,,,,,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,0, +,,0,,,,,,,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,0,,,,,,,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,0,,,,,,,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,0,0,0,,,,,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +2617 +169;368;544;d4_door_11 +172;208;304;3;d4_order_2;; +172;208;336;1;d4_order_2;; +172;256;320;;d4_order_2;; +172;288;304;2;d4_order_2;; +172;288;336;4;d4_order_2;d4_o2; +172;368;176;3;d4_order_1;;True +172;368;208;1;d4_order_1;;True +172;416;192;;d4_order_1;;True +172;448;176;2;d4_order_1;;True +172;448;208;4;d4_order_1;d4_bo1;True +0;16;160;;; +0;16;176;;; +0;16;192;;; +0;16;208;;; +0;16;224;;; +0;16;240;;; +0;16;416;;; +0;16;432;;; +0;16;448;;; +0;16;464;;; +0;16;480;;; +0;16;496;;; +0;32;144;;; +0;32;256;;; +0;32;400;;; +0;32;512;;; +0;48;160;;; +0;48;256;;; +0;48;320;;; +0;48;336;;; +0;48;352;;; +0;48;400;;; +0;48;512;;; +0;64;144;;; +0;64;256;;; +0;64;288;;; +0;64;304;;; +0;64;368;;; +0;64;384;;; +0;64;400;;; +0;64;512;;; +0;80;144;;; +0;80;512;;; +0;96;144;;; +0;96;512;;; +0;112;144;;; +0;112;256;;; +0;112;288;;; +0;112;304;;; +0;112;368;;; +0;112;384;;; +0;112;400;;; +0;112;512;;; +0;128;160;;; +0;128;256;;; +0;128;320;;; +0;128;336;;; +0;128;352;;; +0;128;400;;; +0;128;512;;; +0;144;144;;; +0;144;256;;; +0;144;400;;; +0;144;512;;; +0;160;160;;; +0;160;176;;; +0;160;192;;; +0;160;208;;; +0;160;224;;; +0;160;240;;; +0;160;416;;; +0;160;448;;; +0;160;464;;; +0;160;480;;; +0;160;512;;; +0;176;288;;; +0;176;304;;; +0;176;320;;; +0;176;336;;; +0;176;352;;; +0;176;368;;; +0;176;416;;; +0;176;448;;; +0;176;480;;; +0;176;512;;; +0;176;528;;; +0;176;544;;; +0;176;560;;; +0;176;736;;; +0;176;752;;; +0;192;272;;; +0;192;384;;; +0;192;400;;; +0;192;448;;; +0;192;480;;; +0;192;768;;; +0;208;272;;; +0;208;384;;; +0;208;416;;; +0;208;432;;; +0;208;480;;; +0;208;768;;; +0;224;272;;; +0;224;384;;; +0;224;480;;; +0;224;768;;; +0;240;272;;; +0;240;384;;; +0;240;416;;; +0;240;432;;; +0;240;448;;; +0;240;464;;; +0;240;480;;; +0;240;768;;; +0;256;272;;; +0;256;384;;; +0;256;400;;; +0;256;768;;; +0;272;272;;; +0;272;768;;; +0;288;272;;; +0;288;384;;; +0;288;400;;; +0;288;768;;; +0;304;272;;; +0;304;384;;; +0;304;400;;; +0;304;768;;; +0;320;288;;; +0;320;304;;; +0;320;352;;; +0;320;368;;; +0;320;416;;; +0;320;432;;; +0;320;448;;; +0;320;464;;; +0;320;480;;; +0;320;496;;; +0;320;512;;; +0;320;528;;; +0;320;544;;; +0;320;560;;; +0;320;768;;; +0;336;32;;; +0;336;48;;; +0;336;64;;; +0;336;80;;; +0;336;96;;; +0;336;112;;; +0;336;160;;; +0;336;176;;; +0;336;192;;; +0;336;208;;; +0;336;224;;; +0;336;240;;; +0;336;256;;; +0;336;272;;; +0;336;288;;; +0;336;304;;; +0;336;352;;; +0;336;368;;; +0;336;416;;; +0;336;432;;; +0;336;448;;; +0;336;464;;; +0;336;480;;; +0;336;496;;; +0;336;544;;; +0;336;560;;; +0;336;768;;; +0;336;800;;; +0;336;816;;; +0;336;832;;; +0;336;848;;; +0;336;864;;; +0;336;880;;; +0;352;16;;; +0;352;128;;; +0;352;144;;; +0;352;384;;; +0;352;400;;; +0;352;768;;; +0;352;784;;; +0;352;896;;; +0;368;128;;; +0;368;144;;; +0;368;384;;; +0;368;400;;; +0;368;768;;; +0;368;784;;; +0;368;896;;; +0;384;128;;; +0;384;144;;; +0;384;240;;; +0;384;256;;; +0;384;272;;; +0;384;288;;; +0;384;304;;; +0;384;320;;; +0;384;336;;; +0;384;384;;; +0;384;400;;; +0;384;448;;; +0;384;464;;; +0;384;480;;; +0;384;496;;; +0;384;544;;; +0;384;560;;; +0;384;768;;; +0;384;784;;; +0;384;896;;; +0;400;240;;; +0;400;352;;; +0;400;384;;; +0;400;400;;; +0;400;448;;; +0;400;560;;; +0;408;912;;; +0;416;240;;; +0;416;352;;; +0;416;384;;; +0;416;400;;; +0;416;448;;; +0;416;464;;; +0;416;480;;; +0;416;496;;; +0;416;512;;; +0;416;528;;; +0;416;544;;; +0;416;560;;; +0;432;128;;; +0;432;144;;; +0;432;240;;; +0;432;256;;; +0;432;272;;; +0;432;288;;; +0;432;304;;; +0;432;320;;; +0;432;336;;; +0;432;352;;; +0;432;384;;; +0;432;400;;; +0;432;768;;; +0;432;784;;; +0;432;896;;; +0;448;16;;; +0;448;128;;; +0;448;144;;; +0;448;384;;; +0;448;400;;; +0;448;768;;; +0;448;784;;; +0;448;896;;; +0;464;32;;; +0;464;48;;; +0;464;96;;; +0;464;112;;; +0;464;144;;; +0;464;384;;; +0;464;400;;; +0;464;768;;; +0;464;784;;; +0;464;896;;; +0;480;48;;; +0;480;160;;; +0;480;176;;; +0;480;192;;; +0;480;208;;; +0;480;224;;; +0;480;240;;; +0;480;256;;; +0;480;272;;; +0;480;288;;; +0;480;304;;; +0;480;320;;; +0;480;336;;; +0;480;384;;; +0;480;400;;; +0;480;704;;; +0;480;752;;; +0;480;800;;; +0;480;816;;; +0;480;832;;; +0;480;848;;; +0;480;864;;; +0;480;880;;; +0;496;32;;; +0;496;48;;; +0;496;96;;; +0;496;112;;; +0;496;160;;; +0;496;176;;; +0;496;192;;; +0;496;208;;; +0;496;224;;; +0;496;240;;; +0;496;288;;; +0;496;304;;; +0;496;320;;; +0;496;336;;; +0;496;384;;; +0;496;400;;; +0;496;704;;; +0;496;752;;; +0;496;800;;; +0;496;816;;; +0;496;832;;; +0;496;848;;; +0;496;864;;; +0;496;880;;; +0;512;16;;; +0;512;128;;; +0;512;144;;; +0;512;256;;; +0;512;272;;; +0;512;768;;; +0;512;784;;; +0;512;896;;; +0;528;16;;; +0;528;128;;; +0;528;144;;; +0;528;256;;; +0;528;272;;; +0;528;768;;; +0;528;784;;; +0;528;896;;; +0;544;16;;; +0;544;128;;; +0;544;144;;; +0;544;192;;; +0;544;208;;; +0;544;256;;; +0;544;272;;; +0;544;768;;; +0;544;784;;; +0;544;896;;; +0;560;16;;; +0;560;192;;; +0;560;208;;; +0;560;896;;; +0;576;16;;; +0;576;192;;; +0;576;208;;; +0;576;896;;; +0;592;16;;; +0;592;128;;; +0;592;144;;; +0;592;192;;; +0;592;208;;; +0;592;256;;; +0;592;272;;; +0;592;768;;; +0;592;784;;; +0;592;896;;; +0;608;16;;; +0;608;128;;; +0;608;144;;; +0;608;256;;; +0;608;272;;; +0;608;768;;; +0;608;784;;; +0;608;896;;; +0;624;16;;; +0;624;128;;; +0;624;144;;; +0;624;256;;; +0;624;272;;; +0;624;768;;; +0;624;784;;; +0;624;896;;; +0;640;32;;; +0;640;48;;; +0;640;64;;; +0;640;80;;; +0;640;96;;; +0;640;112;;; +0;640;160;;; +0;640;176;;; +0;640;192;;; +0;640;208;;; +0;640;224;;; +0;640;240;;; +0;640;272;;; +0;640;704;;; +0;640;720;;; +0;640;768;;; +0;640;800;;; +0;640;816;;; +0;640;832;;; +0;640;848;;; +0;640;864;;; +0;640;880;;; +0;656;272;;; +0;656;704;;; +0;656;720;;; +0;656;768;;; +0;672;272;;; +0;672;512;;; +0;672;528;;; +0;672;768;;; +0;688;272;;; +0;688;512;;; +0;688;528;;; +0;688;768;;; +0;704;272;;; +0;704;512;;; +0;704;528;;; +0;704;768;;; +0;720;272;;; +0;720;640;;; +0;720;656;;; +0;720;768;;; +0;736;272;;; +0;736;640;;; +0;736;656;;; +0;736;768;;; +0;752;272;;; +0;752;768;;; +0;768;272;;; +0;768;768;;; +0;784;272;;; +0;784;640;;; +0;784;656;;; +0;784;768;;; +0;800;288;;; +0;800;304;;; +0;800;320;;; +0;800;336;;; +0;800;352;;; +0;800;368;;; +0;800;384;;; +0;800;400;;; +0;800;416;;; +0;800;432;;; +0;800;464;;; +0;800;480;;; +0;800;496;;; +0;800;512;;; +0;800;528;;; +0;800;544;;; +0;800;560;;; +0;800;576;;; +0;800;592;;; +0;800;608;;; +0;800;624;;; +0;800;640;;; +0;800;656;;; +0;800;672;;; +0;800;688;;; +0;800;704;;; +0;800;720;;; +0;800;736;;; +0;800;752;;; +0;816;352;;; +0;816;368;;; +0;816;384;;; +0;816;400;;; +0;816;416;;; +0;816;432;;; +0;816;464;;; +0;816;480;;; +0;816;496;;; +0;832;160;;; +0;832;176;;; +0;832;192;;; +0;832;208;;; +0;832;224;;; +0;832;240;;; +0;832;288;;; +0;832;304;;; +0;832;320;;; +0;832;336;;; +0;832;512;;; +0;848;144;;; +0;848;256;;; +0;848;272;;; +0;848;512;;; +0;864;144;;; +0;864;256;;; +0;864;272;;; +0;864;512;;; +0;880;144;;; +0;880;256;;; +0;880;272;;; +0;880;512;;; +0;896;144;;; +0;896;512;;; +0;912;144;;; +0;912;256;;; +0;912;272;;; +0;912;512;;; +0;928;144;;; +0;928;256;;; +0;928;272;;; +0;928;512;;; +0;944;144;;; +0;944;256;;; +0;944;272;;; +0;944;512;;; +0;960;160;;; +0;960;176;;; +0;960;192;;; +0;960;208;;; +0;960;224;;; +0;960;240;;; +0;960;288;;; +0;960;304;;; +0;960;320;;; +0;960;336;;; +0;960;352;;; +0;960;368;;; +0;960;384;;; +0;960;400;;; +0;960;416;;; +0;960;432;;; +0;960;448;;; +0;960;464;;; +0;960;480;;; +0;960;496;;; +19;416;32;;; +19;688;352;;; +19;688;656;;; +20;176;704;;; +20;384;64;;; +21;240;704;;; +21;416;64;;; +21;688;416;;; +21;688;672;;; +14;432;656;;; +14;624;624;;; +14;656;400;;; +1;392;880;;; +1;424;880;;; +1;480;80;;; +1;480;736;;; +1;496;80;;; +1;496;736;;; +1;640;752;;; +1;656;752;;; +3;80;256;;; +3;80;272;;; +3;80;384;;; +3;80;400;;; +3;352;512;;; +3;352;528;;; +3;400;128;;; +3;400;144;;; +3;400;896;;; +3;560;128;;; +3;560;144;;; +3;560;256;;; +3;560;272;;; +3;560;768;;; +3;560;784;;; +3;752;640;;; +3;752;656;;; +4;96;256;;; +4;96;272;;; +4;96;384;;; +4;96;400;;; +4;368;512;;; +4;368;528;;; +4;416;128;;; +4;416;144;;; +4;416;896;;; +4;576;128;;; +4;576;144;;; +4;576;256;;; +4;576;272;;; +4;576;768;;; +4;576;784;;; +4;768;640;;; +4;768;656;;; +2;480;64;;; +2;480;720;;; +2;496;64;;; +2;496;720;;; +2;640;736;;; +2;656;736;;; +2;672;352;;; +15;640;656;;; +17;640;416;;; +18;176;592;;; +18;384;32;;; +18;432;624;;; +18;624;400;;; +18;656;352;;; +298;408;896;;;;;; +199;208;672;nightmarekey;four;d4_nkey;; +199;272;448;greenZol;;d4_chest_zol;; +199;368;304;smallkeyChest;four;d4_key_4;; +199;400;48;flippers;;d4_flippers;; +199;432;448;ruby50;;d4_r50_2;; +199;560;848;smallkeyChest;four;d4_key_1;; +199;592;720;compass;four;d4_compass;; +199;672;352;dmap;four;d4_map;; +199;688;576;ruby50;;d4_r50_1;; +199;720;688;stonebeak;four;d4_beak;; +199;896;176;smallkeyChest;four;d4_key_3;; +199;928;448;smallkeyChest;four;d4_key_2;; +289;368;288;d4_key_4 +289;528;784;d4_key_1 +289;568;320;d4_et_5 +289;840;152;d4_key_3 +289;848;448;d4_key_2 +273;544;864;;;; +273;560;832;;;; +273;560;864;;;; +273;576;832;;;; +273;576;864;;;; +273;592;864;;;; +273;608;832;;;; +273;608;848;;;; +273;608;864;;;; +261;88;256;2;d4_door_10;1; +261;88;272;2;d4_door_10;3; +261;88;384;2;d4_door_9;1; +261;88;400;3;d4_door_9;3;d4_door_9 +261;360;512;;d4_door_11;1;d4_door_11 +261;360;528;;d4_door_11;3;d4_door_11 +261;408;128;;d4_door_8;1;d4_door_8 +261;408;144;;d4_door_8;3;d4_door_8 +261;480;72;;d4_door_7;;d4_door_7 +261;480;728;;d4_door_1;; +261;496;72;;d4_door_7;2;d4_door_7 +261;496;728;;d4_door_1;2; +261;568;128;;d4_door_6;1;d4_door_6 +261;568;144;;d4_door_6;3;d4_door_6 +261;568;256;;d4_door_5;1;d4_door_5 +261;568;272;1;d4_door_5;3;d4_door_5_key +261;568;768;;d4_door_2;1; +261;568;784;;d4_door_2;3; +261;640;744;1;d4_door_3;;d4_door_3 +261;656;744;;d4_door_3;2; +261;760;640;;d4_door_4;1; +261;760;656;1;d4_door_4;3;d4_door_4 +174;408;928;dungeon_4 +153;80;336;;;d4_2d_4;dungeon4_2d_4.map;d4_2d_4;2;1;False +153;192;416;;;d4_2d_2l;dungeon4_2d_2.map;d4_2d_2l;-1;1;False +153;208;624;;;d4_2d_3l;dungeon4_2d_3.map;d4_2d_3l;2;1;False +153;352;416;;;d4_2d_2r;dungeon4_2d_2.map;d4_2d_2r;2;1;False +153;408;904;;;d4;overworld.map;d4;1;; +153;768;304;;;d4_2d_1;dungeon4_2d_1.map;d4_2d_1;2;1;False +23;208;304;;;; +23;208;336;;;; +23;256;320;;;; +23;432;464;;;; +23;432;480;;;; +245;48;928;four;; +324;896;208;;d4_dblock_2;;; +324;912;464;;d4_dblock_1;;; +284;16;928;;;; +350;544;464;d4_beak_1 +260;608;22;;d4_lever_open +52;64;160;;;;;; +52;64;192;;;;;; +52;112;160;;;;;; +52;112;192;;;;;; +52;352;32;;;;;; +52;384;16;;;;;; +52;384;816;;;;;; +52;384;832;;;;;; +52;400;12;;;;;; +52;400;272;;;;;; +52;416;16;;;;;; +52;416;272;;;;;; +52;432;816;;;;;; +52;432;832;;;;;; +52;448;32;;;;;; +52;544;832;;;;;; +52;544;848;;;;;; +52;576;432;;;;;; +52;592;832;;;;;; +52;592;848;;;;;; +52;672;720;;;;;; +52;688;720;;;;;; +52;704;720;;;;;; +52;720;720;;;;;; +52;736;672;;;;;; +52;736;688;;;;;; +52;736;704;;;;;; +428;864;160 +428;896;448 +428;928;160 +466;384;192 +466;432;192 +465;224;544 +465;272;576 +465;304;560 +465;576;576 +465;688;592 +465;896;320 +465;928;352 +467;704;288 +464;224;304 +464;256;352 +464;256;752 +464;272;320 +464;368;560 +464;400;576 +464;432;464 +464;432;560 +464;448;448 +464;512;816 +464;528;560 +464;528;864 +464;560;592 +464;624;816 +464;624;880 +464;720;736 +464;736;560 +464;752;704 +464;768;592 +464;784;560 +464;784;720 +464;864;336 +464;864;464 +464;896;192 +464;944;304 +427;352;372;1;False; +427;544;92;1;False; +427;544;732;;; +424;64;432 +424;64;480 +424;112;480 +424;304;464 +424;384;96 +424;416;96 +424;416;208 +424;416;736 +424;560;336 +424;576;336 +424;592;736 +424;736;480 +424;784;352 +424;784;480 +423;448;320;; +423;464;352;; +423;544;448;; +423;720;304;; +252;392;688;d4_et_1 +252;400;104;d4_et_4 +252;496;784;d4_et_3 +252;560;304;d4_et_5 +252;616;708;d4_et_2 +22;320;320;;;; +22;320;336;;;; +22;408;128;;;; +22;408;144;;;; +22;448;256;;;; +22;464;256;;;; +341;32;416;;;;;; +341;32;432;;;;;; +341;32;448;;;;;; +341;32;464;;;;;; +341;32;480;;;;;; +341;32;496;;;;;; +341;48;416;;;;;; +341;48;496;;;;;; +341;64;416;;;;;; +341;64;496;;;;;; +341;80;496;;;;;; +341;96;496;;;;;; +341;112;416;;;;;; +341;112;496;;;;;; +341;128;416;;;;;; +341;128;496;;;;;; +341;144;416;;;;;; +341;144;448;;;;;; +341;144;464;;;;;; +341;144;480;;;;;; +341;144;496;;;;;; +341;528;320;;;;;; +341;608;320;;;;;; +341;672;464;;;;;; +341;672;480;;;;;; +341;672;496;;;;;; +341;688;464;;;;;; +341;688;480;;;;;; +341;688;496;;;;;; +341;704;480;;;;;; +341;704;496;;;;;; +341;720;448;;;;;; +341;736;432;;;;;; +341;736;448;;;;;; +341;736;464;;;;;; +341;752;448;;;;;; +342;568;800;1 +342;672;744; +342;760;624;3 +342;760;672;1 +200;88;184;;d4_instrument;instrument3;; +200;272;704;w;;bomb_10;; +200;368;480;w;;heart_3;; +200;400;208;w;;heart_3;; +200;848;192;w;;heart_3;; +162;56;176;-18;2;8;;;;;; +162;128;176;18;2;8;;;;;; +162;224;584;;-18;24;8;;;;; +168;-8;264;d4_door_10;d4_nightmare_killed&(!d4_enter_I|d4_instrument); +168;432;136;d4_door_8;(d4_et_4|!d4_enter_5)&(!d4_enter_4|d4_bo1); +168;488;48;d4_door_7;d4_et_4|!d4_enter_5; +168;488;708;d4_door_1;(!d4_enter_1|d4_et_1)&(!d4_enter_2|d4_et_2); +168;592;776;d4_door_2;(!d4_enter_2|d4_et_2)&(!d4_enter_3|d4_et_3); +168;664;136;d4_door_6;d4_mboss_killed; +168;664;248;d4_door_5;d4_door_5_key&(!d4_mboss_enter|d4_mboss_killed); +333;368;432;d4_keyblock_2 +333;736;352;d4_keyblock_1 +167;-8;216;d4_enter_I;0 +167;248;248;d4_order_2;0 +167;312;104;d4_et_4;0 +167;312;136;d4_enter_4;0 +167;376;776;d4_et_1;0 +167;388;168;d4_order_1;0 +167;408;168;d4_bo1;0 +167;440;776;d4_enter_1;0 +167;488;24;d4_enter_5;0 +167;488;752;d4_enter_2;0 +167;616;728;d4_et_2;0 +167;664;224;d4_mboss_enter;0 +167;664;816;d4_et_3;0 +167;664;840;d4_enter_3;0 +302;32;160;;;;; +302;32;240;;;;; +302;64;320;;;;; +302;64;352;;;;; +302;112;320;;;;; +302;112;352;;;;; +302;144;160;;;;; +302;144;240;;;;; +170;88;256;d4_enter_I;1;;; +170;400;784;d4_enter_1;1;;; +170;408;128;d4_enter_5;1;;; +170;408;144;d4_enter_4;3;;; +170;416;672;d4_enter_1;3;;; +170;416;784;d4_enter_1;1;;; +170;448;256;d4_enter_4;3;32;;True +170;448;256;d4_enter_4;1;32;; +170;480;72;d4_enter_5;;;; +170;496;728;d4_enter_2;2;;; +170;512;72;d4_lever_open;;;; +170;568;112;d4_lever_open;3;;; +170;568;256;d4_mboss_enter;1;;; +170;568;784;d4_enter_3;3;;; +227;512;64;1 +227;512;80;3 +227;560;112; +227;576;112;2 +297;568;184;160;;;;125; +10;192;704;;; +10;208;704;;; +10;224;704;;; +10;256;672;;; +10;272;672;;; +10;288;672;;; +10;304;672;;; +10;320;672;;; +10;336;672;;; +10;352;672;;; +10;368;672;;; +10;384;672;;; +10;400;672;;; +10;432;672;;; +10;448;672;;; +10;464;672;;; +10;480;672;;; +10;496;672;;; +10;512;672;;; +10;528;304;;; +10;528;672;;; +10;544;672;;; +10;560;672;;; +10;576;672;;; +10;592;672;;; +10;608;304;;; +10;608;672;;; +10;624;672;;; +10;640;672;;; +10;656;416;;; +10;656;672;;; +11;192;592;;; +11;208;592;;; +11;256;656;;; +11;272;656;;; +11;288;656;;; +11;304;656;;; +11;320;656;;; +11;336;656;;; +11;352;240;;; +11;352;656;;; +11;368;240;;; +11;368;656;;; +11;384;656;;; +11;400;32;;; +11;400;656;;; +11;416;656;;; +11;448;624;;; +11;464;624;;; +11;480;624;;; +11;496;624;;; +11;512;624;;; +11;528;336;;; +11;528;624;;; +11;544;624;;; +11;560;624;;; +11;576;624;;; +11;592;624;;; +11;608;336;;; +11;608;624;;; +11;640;400;;; +11;656;656;;; +11;672;656;;; +12;176;608;;; +12;176;624;;; +12;176;640;;; +12;176;656;;; +12;176;672;;; +12;176;688;;; +12;384;48;;; +12;432;640;;; +12;544;320;;; +12;624;320;;; +12;624;416;;; +12;624;432;;; +12;624;448;;; +12;624;464;;; +12;624;480;;; +12;624;496;;; +12;624;512;;; +12;624;528;;; +12;624;544;;; +12;624;560;;; +12;624;576;;; +12;624;592;;; +12;624;608;;; +12;656;368;;; +12;656;384;;; +13;240;592;;; +13;240;608;;; +13;240;624;;; +13;240;640;;; +13;240;656;;; +13;240;672;;; +13;240;688;;; +13;416;48;;; +13;512;320;;; +13;592;320;;; +13;640;432;;; +13;640;448;;; +13;640;464;;; +13;640;480;;; +13;640;496;;; +13;640;512;;; +13;640;528;;; +13;640;544;;; +13;640;560;;; +13;640;576;;; +13;640;592;;; +13;640;608;;; +13;640;624;;; +13;640;640;;; +13;688;368;;; +13;688;384;;; +13;688;400;;; +25;48;176;;;; +25;48;192;;;; +25;48;208;;;; +25;64;208;;;; +25;112;208;;;; +25;128;176;;;; +25;128;192;;;; +25;128;208;;;; +25;176;576;;;; +25;176;720;;;; +25;192;576;;;; +25;192;720;;;; +25;208;576;;;; +25;208;720;;;; +25;224;576;;;; +25;224;720;;;; +25;240;576;;;; +25;240;720;;;; +25;256;576;;;; +25;256;592;;;; +25;256;608;;;; +25;256;624;;;; +25;256;640;;;; +25;256;688;;;; +25;256;704;;;; +25;256;720;;;; +25;272;640;;;; +25;272;688;;;; +25;288;640;;;; +25;288;688;;;; +25;304;640;;;; +25;304;688;;;; +25;320;640;;;; +25;320;688;;;; +25;336;640;;;; +25;336;688;;;; +25;352;640;;;; +25;352;688;;;; +25;368;32;;;; +25;368;48;;;; +25;368;64;;;; +25;368;80;;;; +25;368;640;;;; +25;368;688;;;; +25;384;80;;;; +25;384;640;;;; +25;384;688;;;; +25;400;640;;;; +25;400;688;;;; +25;416;80;;;; +25;416;608;;;; +25;416;624;;;; +25;416;640;;;; +25;432;32;;;; +25;432;48;;;; +25;432;64;;;; +25;432;80;;;; +25;432;608;;;; +25;432;688;;;; +25;448;608;;;; +25;448;688;;;; +25;464;608;;;; +25;464;688;;;; +25;480;608;;;; +25;480;688;;;; +25;496;608;;;; +25;496;688;;;; +25;512;608;;;; +25;512;688;;;; +25;528;608;;;; +25;528;688;;;; +25;544;608;;;; +25;544;688;;;; +25;560;608;;;; +25;560;688;;;; +25;576;608;;;; +25;576;688;;;; +25;592;608;;;; +25;592;688;;;; +25;608;384;;;; +25;608;400;;;; +25;608;416;;;; +25;608;432;;;; +25;608;448;;;; +25;608;464;;;; +25;608;480;;;; +25;608;496;;;; +25;608;512;;;; +25;608;528;;;; +25;608;544;;;; +25;608;560;;;; +25;608;576;;;; +25;608;592;;;; +25;608;608;;;; +25;608;688;;;; +25;624;384;;;; +25;624;688;;;; +25;640;336;;;; +25;640;352;;;; +25;640;368;;;; +25;640;384;;;; +25;640;688;;;; +25;656;336;;;; +25;656;432;;;; +25;656;448;;;; +25;656;464;;;; +25;656;480;;;; +25;656;496;;;; +25;656;512;;;; +25;656;528;;;; +25;656;544;;;; +25;656;560;;;; +25;656;576;;;; +25;656;592;;;; +25;656;608;;;; +25;656;624;;;; +25;656;640;;;; +25;656;688;;;; +25;672;336;;;; +25;672;640;;;; +25;688;336;;;; +25;688;432;;;; +25;688;640;;;; +25;688;688;;;; +25;704;336;;;; +25;704;352;;;; +25;704;368;;;; +25;704;384;;;; +25;704;400;;;; +25;704;416;;;; +25;704;432;;;; +25;704;640;;;; +25;704;656;;;; +25;704;672;;;; +25;704;688;;;; +501;512;160;d4_mboss_killed;d4_mboss_enter +223;48;432;;;;;;;; +223;48;480;;;;;;;; +223;128;432;;;;;;;; +223;128;480;;;;;;;; +223;304;720;0;;;;;;; +223;352;432;0;;;;;;; +223;352;720;0;;;;;;; +223;384;368;;;;;;;; +223;384;432;;;;;;;; +223;400;416;;;;;;;; +223;400;720;0;;;;;;; +223;448;720;0;;;;;;; +223;528;48;0;;;;;;; +223;544;80;0;;;;;;; +223;544;720;0;;;;;;; +223;560;48;0;;;;;;; +223;576;80;0;;;;;;; +223;704;464;0;;;;;;; +223;720;352;8;;;;;;; +223;720;432;0;;;;;;; +223;720;464;0;;;;;;; +223;736;288;0;;;;;;; +223;736;336;2;;;;;;; +223;752;336;0;;;;;;; +223;752;352;0;;;;;;; +223;752;432;0;;;;;;; +223;752;464;0;;;;;;; +223;768;336;0;;;;;;; +223;768;432;0;;;;;;; +223;768;464;0;;;;;;; +223;784;336;0;;;;;;; +223;784;432;0;;;;;;; +223;784;464;0;;;;;;; +223;928;464;;;;;;;; +287;80;928;22 +164;-8;240;d4_enter_I;1;dialogBox;d4_instrument_music; +164;304;288;d4_o2;;water;; +164;304;288;d4_o2;;water4;; +164;400;688;d4_et_1;1;dialogBox;sound_secrete; +164;408;848;d4_mboss_killed;1;dungeonTeleporter;.d2teleport; +164;428;168;d4_bo1;1;dialogBox;sound_secrete; +164;512;784;d4_et_3;1;dialogBox;sound_secrete; +164;528;320;d4k4spawn;1;item;d.d4_key_5.smallkey.four; +164;568;168;d4_mboss_killed;1;dungeonTeleporter;.d2teleport; +164;576;304;d4_et_5;1;dialogBox;d4k4spawn; +164;596;708;d4_et_2;1;dialogBox;sound_secrete; +166;304;288;d4_o2;1;d4_spawn_stairs +231;80;480;;heart;;;; +231;96;480;;;;;; +231;191;736;;heart;;;; +231;191;752;;heart;;;; +231;192;544;;;;;; +231;192;560;;;;;; +231;256;416;;;;;; +231;288;416;;;;;; +231;304;416;;heart;;;; +231;608;368;;ruby;;;; +231;624;352;;;;;; +231;624;368;;heart;;;; +231;672;560;;fairy;;;; +231;832;480;;ruby;;;; +231;832;496;;ruby;;;; +231;944;352;;bomb_1;;;; +231;944;368;;;;;; +413;256;480 +454;368;720 +454;432;720 +454;528;464 +454;528;752 +454;576;704 +454;592;448 +160;80;208; +160;96;208; +160;400;80; +160;416;688; +160;672;432; +160;672;688; +414;288;448 +414;688;320 +319;48;400;;;;; +319;64;256;;2;;; +319;112;256;;2;;; +319;128;400;;;;; +319;176;544;;3;;; +319;208;272;;;;; +319;208;480;;;;; +319;208;576;;2;;; +319;208;720;;;;; +319;288;272;;;;; +319;288;640;;2;;; +319;288;688;;;;; +319;320;432;;1;;; +319;320;480;;1;;; +319;336;176;;3;;; +319;336;288;;3;;; +319;336;368;;3;;; +319;336;432;;3;;; +319;336;480;;3;;; +319;368;144;;;;; +319;368;400;;;;; +319;368;688;;;;; +319;368;784;;;;; +319;384;80;;;;; +319;384;480;;1;;; +319;416;80;;;;; +319;416;480;;3;;; +319;448;144;;;;; +319;448;400;;;;; +319;448;608;;2;;; +319;448;688;;;;; +319;448;784;;;;; +319;480;304;;1;;; +319;496;304;;3;;; +319;528;272;;;;; +319;528;608;;2;;; +319;528;688;;;;; +319;544;16;;;;; +319;544;784;;;;; +319;576;16;;;;; +319;592;784;;;;; +319;608;272;;;;; +319;608;432;;1;;; +319;608;480;;1;;; +319;608;560;;1;;; +319;608;688;;;;; +319;656;480;;3;;; +319;656;560;;3;;; +319;656;608;;3;;; +319;688;272;;;;; +319;736;656;;;;; +319;768;272;;;;; +319;784;656;;;;; +319;800;336;;1;;; +319;800;480;;1;;; +319;800;560;;1;;; +319;800;608;;1;;; +319;800;720;;1;;; +319;816;416;;3;;; +319;816;480;;3;;; +319;864;144;;;;; +319;864;272;;;;; +319;928;144;;;;; +319;928;272;;;;; +460;352;32;d4_et_4 +460;400;272; +460;416;272; +460;448;32;d4_et_4 +246;64;176; +246;64;192; +246;80;160; +246;80;176; +246;80;192; +246;80;208; +246;96;160; +246;96;176; +246;96;192; +246;96;208; +246;112;176; +246;112;192; +246;176;592; +246;176;608; +246;176;624; +246;176;640; +246;176;656; +246;176;672; +246;176;688; +246;176;704; +246;192;592; +246;192;608; +246;192;624; +246;192;640; +246;192;656; +246;192;672; +246;192;688; +246;192;704; +246;208;592; +246;208;608; +246;208;640; +246;208;656; +246;208;672; +246;208;688; +246;208;704; +246;224;592; +246;224;608; +246;224;624; +246;224;640; +246;224;656; +246;224;672; +246;224;688; +246;224;704; +246;240;592; +246;240;608; +246;240;624; +246;240;640; +246;240;656; +246;240;672; +246;240;688; +246;240;704; +246;256;656; +246;256;672; +246;272;656; +246;272;672; +246;288;656; +246;288;672; +246;304;656; +246;304;672; +246;320;656; +246;320;672; +246;336;656; +246;336;672; +246;352;656; +246;352;672; +246;368;656; +246;368;672; +246;384;32; +246;384;48; +246;384;64; +246;384;656; +246;384;672; +246;400;32; +246;400;48; +246;400;64; +246;400;80; +246;400;656; +246;400;672; +246;416;32; +246;416;48; +246;416;64; +246;416;656; +246;416;672; +246;416;688; +246;432;624; +246;432;640; +246;432;656; +246;432;672; +246;448;624; +246;448;640; +246;448;656; +246;448;672; +246;464;624; +246;464;640; +246;464;656; +246;464;672; +246;480;624; +246;480;640; +246;480;656; +246;480;672; +246;496;624; +246;496;640; +246;496;656; +246;496;672; +246;512;624; +246;512;640; +246;512;656; +246;512;672; +246;528;624; +246;528;640; +246;528;656; +246;528;672; +246;544;624; +246;544;640; +246;544;656; +246;544;672; +246;560;624; +246;560;640; +246;560;656; +246;560;672; +246;576;624; +246;576;640; +246;576;656; +246;576;672; +246;592;624; +246;592;640; +246;592;656; +246;592;672; +246;608;624; +246;608;640; +246;608;656; +246;608;672; +246;624;400; +246;624;416; +246;624;432; +246;624;448; +246;624;464; +246;624;480; +246;624;496; +246;624;512; +246;624;528; +246;624;544; +246;624;560; +246;624;576; +246;624;592; +246;624;608; +246;624;624; +246;624;640; +246;624;656; +246;624;672; +246;640;400; +246;640;416; +246;640;432; +246;640;448; +246;640;464; +246;640;480; +246;640;496; +246;640;528; +246;640;544; +246;640;560; +246;640;576; +246;640;592; +246;640;608; +246;640;624; +246;640;640; +246;640;656; +246;640;672; +246;656;352; +246;656;368; +246;656;384; +246;656;400; +246;656;416; +246;656;656; +246;656;672; +246;672;368; +246;672;384; +246;672;400; +246;672;416; +246;672;432; +246;672;656; +246;672;672; +246;672;688; +246;688;352; +246;688;368; +246;688;384; +246;688;400; +246;688;416; +246;688;656; +246;688;672; +157;192;368; +157;208;368; +157;208;752; +157;224;368; +157;224;544; +157;224;560; +157;240;352; +157;240;368; +157;240;544; +157;240;560; +157;256;352; +157;256;368; +157;256;544; +157;256;560; +157;272;288; +157;272;336; +157;272;352; +157;272;368; +157;272;544; +157;272;560; +157;272;576; +157;272;592; +157;272;608; +157;272;624; +157;272;704; +157;272;752; +157;288;288; +157;288;320; +157;288;352; +157;288;368; +157;288;544; +157;288;624; +157;288;704; +157;288;752; +157;304;304; +157;304;320; +157;304;336; +157;304;544; +157;304;624; +157;304;704; +157;304;736; +157;304;752; +157;320;624; +157;320;704; +157;320;720; +157;320;736; +157;320;752; +157;336;624; +157;336;704; +157;336;720; +157;336;736; +157;336;752; +157;352;624; +157;352;704; +157;352;736; +157;352;752; +157;352;800; +157;352;816; +157;352;832; +157;352;848; +157;352;864; +157;352;880; +157;368;624; +157;368;704; +157;368;720; +157;368;736; +157;368;752; +157;368;800; +157;368;816; +157;368;832; +157;368;848; +157;384;624; +157;384;704; +157;384;720; +157;384;736; +157;384;752; +157;384;800; +157;400;432; +157;400;592; +157;400;608; +157;400;624; +157;400;704; +157;400;736; +157;400;752; +157;400;768; +157;400;784; +157;400;800; +157;400;816; +157;400;832; +157;416;416; +157;416;432; +157;416;576; +157;416;592; +157;416;704; +157;416;720; +157;416;736; +157;416;752; +157;416;768; +157;416;784; +157;416;800; +157;416;816; +157;416;832; +157;432;464; +157;432;480; +157;432;560; +157;432;576; +157;432;592; +157;432;704; +157;432;720; +157;432;736; +157;432;752; +157;432;800; +157;448;576; +157;448;592; +157;448;704; +157;448;736; +157;448;752; +157;448;800; +157;448;816; +157;448;832; +157;448;848; +157;464;592; +157;464;704; +157;464;720; +157;464;736; +157;464;752; +157;464;800; +157;464;816; +157;464;832; +157;464;848; +157;464;864; +157;464;880; +157;480;416; +157;480;432; +157;480;592; +157;496;416; +157;496;432; +157;496;592; +157;512;160; +157;512;176; +157;512;192; +157;512;208; +157;512;224; +157;512;240; +157;512;432; +157;512;464; +157;512;480; +157;512;496; +157;512;512; +157;512;592; +157;512;704; +157;512;720; +157;512;736; +157;512;752; +157;512;800; +157;512;816; +157;512;832; +157;512;848; +157;512;864; +157;512;880; +157;528;160; +157;528;176; +157;528;192; +157;528;208; +157;528;224; +157;528;240; +157;528;432; +157;528;448; +157;528;464; +157;528;704; +157;528;720; +157;528;736; +157;528;752; +157;528;800; +157;528;816; +157;528;832; +157;544;160; +157;544;176; +157;544;224; +157;544;240; +157;544;416; +157;544;432; +157;544;448; +157;544;592; +157;544;704; +157;544;736; +157;544;752; +157;544;800; +157;544;880; +157;560;160; +157;560;176; +157;560;224; +157;560;248; +157;560;416; +157;560;448; +157;560;464; +157;560;592; +157;560;704; +157;560;720; +157;560;736; +157;560;752; +157;560;800; +157;576;160; +157;576;176; +157;576;224; +157;576;240; +157;576;416; +157;576;464; +157;576;576; +157;576;592; +157;576;720; +157;576;752; +157;576;800; +157;592;160; +157;592;176; +157;592;224; +157;592;240; +157;592;416; +157;592;432; +157;592;448; +157;592;464; +157;592;480; +157;592;496; +157;592;576; +157;592;592; +157;592;736; +157;592;752; +157;592;800; +157;608;160; +157;608;176; +157;608;192; +157;608;208; +157;608;224; +157;608;240; +157;608;752; +157;608;800; +157;608;816; +157;624;160; +157;624;176; +157;624;192; +157;624;208; +157;624;224; +157;624;240; +157;624;752; +157;624;800; +157;624;816; +157;624;864; +157;624;880; +157;688;736; +157;688;752; +157;704;752; +157;736;624; +157;736;752; +157;752;608; +157;752;624; +157;752;672; +157;752;688; +157;752;752; +157;768;576; +157;768;592; +157;768;608; +157;768;624; +157;768;672; +157;768;688; +157;768;752; +157;784;544; +157;784;560; +157;784;576; +157;784;592; +157;784;608; +157;784;624; +157;784;672; +157;784;688; +157;784;720; +157;784;736; +157;784;752; +157;832;368; +157;832;384; +157;832;400; +157;832;416; +157;848;192; +157;848;368; +157;848;384; +157;848;400; +157;848;480; +157;848;496; +157;864;368; +157;864;384; +157;864;400; +157;864;416; +157;864;432; +157;864;448; +157;864;464; +157;864;480; +157;864;496; +157;880;160; +157;880;176; +157;880;192; +157;880;352; +157;880;368; +157;880;384; +157;880;400; +157;880;416; +157;880;432; +157;880;448; +157;880;464; +157;896;160; +157;896;192; +157;896;224; +157;896;240; +157;896;256; +157;896;272; +157;896;288; +157;896;352; +157;896;368; +157;896;384; +157;896;400; +157;896;416; +157;896;432; +157;896;448; +157;896;464; +157;912;160; +157;912;176; +157;912;192; +157;912;288; +157;912;336; +157;912;352; +157;912;368; +157;912;384; +157;912;400; +157;912;416; +157;912;432; +157;928;288; +157;928;304; +157;928;320; +157;928;336; +157;928;352; +157;928;368; +157;928;384; +157;928;400; +157;944;288; +157;944;304; +157;944;320; +157;944;336; +157;944;400; +108;192;368;;;;;; +108;208;368;;;;;; +108;208;752;;;;;; +108;224;368;;;;;; +108;224;544;;;;;; +108;224;560;;;;;; +108;240;352;;;;;; +108;240;368;;;;;; +108;240;544;;;;;; +108;240;560;;;;;; +108;256;352;;;;;; +108;256;368;;;;;; +108;256;544;;;;;; +108;256;560;;;;;; +108;272;288;;;;;; +108;272;336;;;;;; +108;272;352;;;;;; +108;272;368;;;;;; +108;272;544;;;;;; +108;272;560;;;;;; +108;272;576;;;;;; +108;272;592;;;;;; +108;272;608;;;;;; +108;272;624;;;;;; +108;272;704;;;;;; +108;272;752;;;;;; +108;288;288;;;;;; +108;288;320;;;;;; +108;288;352;;;;;; +108;288;368;;;;;; +108;288;544;;;;;; +108;288;624;;;;;; +108;288;704;;;;;; +108;288;752;;;;;; +108;304;304;;;;;; +108;304;320;;;;;; +108;304;336;;;;;; +108;304;544;;;;;; +108;304;624;;;;;; +108;304;704;;;;;; +108;304;736;;;;;; +108;304;752;;;;;; +108;320;624;;;;;; +108;320;704;;;;;; +108;320;720;;;;;; +108;320;736;;;;;; +108;320;752;;;;;; +108;336;624;;;;;; +108;336;704;;;;;; +108;336;720;;;;;; +108;336;736;;;;;; +108;336;752;;;;;; +108;352;624;;;;;; +108;352;704;;;;;; +108;352;736;;;;;; +108;352;752;;;;;; +108;352;800;;;;;; +108;352;816;;;;;; +108;352;832;;;;;; +108;352;848;;;;;; +108;352;864;;;;;; +108;352;880;;;;;; +108;368;624;;;;;; +108;368;704;;;;;; +108;368;720;;;;;; +108;368;736;;;;;; +108;368;752;;;;;; +108;368;800;;;;;; +108;368;816;;;;;; +108;368;832;;;;;; +108;368;848;;;;;; +108;384;624;;;;;; +108;384;704;;;;;; +108;384;720;;;;;; +108;384;736;;;;;; +108;384;752;;;;;; +108;384;800;;;;;; +108;400;432;;;;;; +108;400;592;;;;;; +108;400;608;;;;;; +108;400;624;;;;;; +108;400;704;;;;;; +108;400;736;;;;;; +108;400;752;;;;;; +108;400;768;;;;;; +108;400;784;;;;;; +108;400;800;;;;;; +108;400;816;;;;;; +108;400;832;;;;;; +108;416;416;;;;;; +108;416;432;;;;;; +108;416;576;;;;;; +108;416;592;;;;;; +108;416;704;;;;;; +108;416;720;;;;;; +108;416;736;;;;;; +108;416;752;;;;;; +108;416;768;;;;;; +108;416;784;;;;;; +108;416;800;;;;;; +108;416;816;;;;;; +108;416;832;;;;;; +108;432;448;;;;;; +108;432;464;;;;;; +108;432;480;;;;;; +108;432;560;;;;;; +108;432;576;;;;;; +108;432;592;;;;;; +108;432;704;;;;;; +108;432;720;;;;;; +108;432;736;;;;;; +108;432;752;;;;;; +108;432;800;;;;;; +108;448;576;;;;;; +108;448;592;;;;;; +108;448;704;;;;;; +108;448;736;;;;;; +108;448;752;;;;;; +108;448;800;;;;;; +108;448;816;;;;;; +108;448;832;;;;;; +108;448;848;;;;;; +108;464;592;;;;;; +108;464;704;;;;;; +108;464;720;;;;;; +108;464;736;;;;;; +108;464;752;;;;;; +108;464;800;;;;;; +108;464;816;;;;;; +108;464;832;;;;;; +108;464;848;;;;;; +108;464;864;;;;;; +108;464;880;;;;;; +108;480;416;;;;;; +108;480;432;;;;;; +108;480;592;;;;;; +108;496;416;;;;;; +108;496;432;;;;;; +108;496;592;;;;;; +108;512;160;;;;;; +108;512;176;;;;;; +108;512;192;;;;;; +108;512;208;;;;;; +108;512;224;;;;;; +108;512;240;;;;;; +108;512;432;;;;;; +108;512;464;;;;;; +108;512;480;;;;;; +108;512;496;;;;;; +108;512;512;;;;;; +108;512;592;;;;;; +108;512;704;;;;;; +108;512;720;;;;;; +108;512;736;;;;;; +108;512;752;;;;;; +108;512;800;;;;;; +108;512;816;;;;;; +108;512;832;;;;;; +108;512;848;;;;;; +108;512;864;;;;;; +108;512;880;;;;;; +108;528;160;;;;;; +108;528;176;;;;;; +108;528;192;;;;;; +108;528;208;;;;;; +108;528;224;;;;;; +108;528;240;;;;;; +108;528;432;;;;;; +108;528;448;;;;;; +108;528;464;;;;;; +108;528;704;;;;;; +108;528;720;;;;;; +108;528;736;;;;;; +108;528;752;;;;;; +108;528;800;;;;;; +108;528;816;;;;;; +108;528;832;;;;;; +108;544;160;;;;;; +108;544;176;;;;;; +108;544;224;;;;;; +108;544;240;;;;;; +108;544;416;;;;;; +108;544;432;;;;;; +108;544;448;;;;;; +108;544;592;;;;;; +108;544;704;;;;;; +108;544;736;;;;;; +108;544;752;;;;;; +108;544;800;;;;;; +108;544;880;;;;;; +108;560;160;;;;;; +108;560;176;;;;;; +108;560;224;;;;;; +108;560;240;;;;;; +108;560;416;;;;;; +108;560;448;;;;;; +108;560;464;;;;;; +108;560;592;;;;;; +108;560;704;;;;;; +108;560;720;;;;;; +108;560;736;;;;;; +108;560;752;;;;;; +108;560;800;;;;;; +108;576;160;;;;;; +108;576;176;;;;;; +108;576;224;;;;;; +108;576;240;;;;;; +108;576;416;;;;;; +108;576;464;;;;;; +108;576;576;;;;;; +108;576;592;;;;;; +108;576;720;;;;;; +108;576;752;;;;;; +108;576;800;;;;;; +108;592;160;;;;;; +108;592;176;;;;;; +108;592;224;;;;;; +108;592;240;;;;;; +108;592;416;;;;;; +108;592;432;;;;;; +108;592;448;;;;;; +108;592;464;;;;;; +108;592;480;;;;;; +108;592;496;;;;;; +108;592;576;;;;;; +108;592;592;;;;;; +108;592;736;;;;;; +108;592;752;;;;;; +108;592;800;;;;;; +108;608;160;;;;;; +108;608;176;;;;;; +108;608;192;;;;;; +108;608;208;;;;;; +108;608;224;;;;;; +108;608;240;;;;;; +108;608;752;;;;;; +108;608;800;;;;;; +108;608;816;;;;;; +108;624;160;;;;;; +108;624;176;;;;;; +108;624;192;;;;;; +108;624;208;;;;;; +108;624;224;;;;;; +108;624;240;;;;;; +108;624;752;;;;;; +108;624;800;;;;;; +108;624;816;;;;;; +108;624;864;;;;;; +108;624;880;;;;;; +108;688;736;;;;;; +108;688;752;;;;;; +108;704;752;;;;;; +108;736;624;;;;;; +108;736;752;;;;;; +108;752;608;;;;;; +108;752;624;;;;;; +108;752;672;;;;;; +108;752;688;;;;;; +108;752;752;;;;;; +108;768;576;;;;;; +108;768;592;;;;;; +108;768;608;;;;;; +108;768;624;;;;;; +108;768;672;;;;;; +108;768;688;;;;;; +108;768;752;;;;;; +108;784;544;;;;;; +108;784;560;;;;;; +108;784;576;;;;;; +108;784;592;;;;;; +108;784;608;;;;;; +108;784;624;;;;;; +108;784;672;;;;;; +108;784;688;;;;;; +108;784;720;;;;;; +108;784;736;;;;;; +108;784;752;;;;;; +108;832;368;;;;;; +108;832;384;;;;;; +108;832;400;;;;;; +108;832;416;;;;;; +108;848;192;;;;;; +108;848;368;;;;;; +108;848;384;;;;;; +108;848;400;;;;;; +108;848;480;;;;;; +108;848;496;;;;;; +108;864;368;;;;;; +108;864;384;;;;;; +108;864;400;;;;;; +108;864;416;;;;;; +108;864;432;;;;;; +108;864;448;;;;;; +108;864;464;;;;;; +108;864;480;;;;;; +108;864;496;;;;;; +108;880;160;;;;;; +108;880;176;;;;;; +108;880;192;;;;;; +108;880;352;;;;;; +108;880;368;;;;;; +108;880;384;;;;;; +108;880;400;;;;;; +108;880;416;;;;;; +108;880;432;;;;;; +108;880;448;;;;;; +108;880;464;;;;;; +108;896;160;;;;;; +108;896;176;;;;;; +108;896;192;;;;;; +108;896;224;;;;;; +108;896;240;;;;;; +108;896;256;;;;;; +108;896;272;;;;;; +108;896;288;;;;;; +108;896;352;;;;;; +108;896;368;;;;;; +108;896;384;;;;;; +108;896;400;;;;;; +108;896;416;;;;;; +108;896;432;;;;;; +108;896;448;;;;;; +108;896;464;;;;;; +108;912;160;;;;;; +108;912;176;;;;;; +108;912;192;;;;;; +108;912;288;;;;;; +108;912;336;;;;;; +108;912;352;;;;;; +108;912;368;;;;;; +108;912;384;;;;;; +108;912;400;;;;;; +108;912;416;;;;;; +108;912;432;;;;;; +108;928;288;;;;;; +108;928;304;;;;;; +108;928;320;;;;;; +108;928;336;;;;;; +108;928;352;;;;;; +108;928;368;;;;;; +108;928;384;;;;;; +108;928;400;;;;;; +108;944;288;;;;;; +108;944;304;;;;;; +108;944;320;;;;;; +108;944;336;;;;;; +108;944;400;;;;;; +109;192;288;;;;;; +109;192;304;;;;;; +109;192;320;;;;;; +109;192;336;;;;;; +109;192;352;;;;;; +109;208;288;;;;;; +109;208;320;;;;;; +109;208;352;;;;;; +109;208;736;;;;;; +109;224;288;;;;;; +109;224;304;;;;;; +109;224;320;;;;;; +109;224;336;;;;;; +109;224;352;;;;;; +109;224;736;;;;;; +109;224;752;;;;;; +109;240;288;;;;;; +109;240;304;;;;;; +109;240;320;;;;;; +109;240;336;;;;;; +109;240;736;;;;;; +109;240;752;;;;;; +109;256;288;;;;;; +109;256;304;;;;;; +109;256;336;;;;;; +109;256;736;;;;;; +109;256;752;;;;;; +109;272;304;;;;;; +109;272;320;;;;;; +109;272;720;;;;;; +109;272;736;;;;;; +109;288;560;;;;;; +109;288;576;;;;;; +109;288;592;;;;;; +109;288;608;;;;;; +109;288;720;;;;;; +109;288;736;;;;;; +109;304;560;;;;;; +109;304;576;;;;;; +109;304;592;;;;;; +109;304;608;;;;;; +109;320;576;;;;;; +109;320;592;;;;;; +109;320;608;;;;;; +109;336;576;;;;;; +109;336;592;;;;;; +109;336;608;;;;;; +109;352;560;;;;;; +109;352;576;;;;;; +109;352;592;;;;;; +109;352;608;;;;;; +109;368;560;;;;;; +109;368;576;;;;;; +109;368;592;;;;;; +109;368;608;;;;;; +109;384;576;;;;;; +109;384;592;;;;;; +109;384;608;;;;;; +109;400;576;;;;;; +109;432;416;;;;;; +109;432;432;;;;;; +109;432;496;;;;;; +109;432;512;;;;;; +109;432;528;;;;;; +109;432;544;;;;;; +109;448;416;;;;;; +109;448;432;;;;;; +109;448;448;;;;;; +109;448;464;;;;;; +109;448;480;;;;;; +109;448;496;;;;;; +109;448;512;;;;;; +109;448;528;;;;;; +109;448;544;;;;;; +109;448;560;;;;;; +109;464;368;;;;;; +109;464;416;;;;;; +109;464;432;;;;;; +109;464;448;;;;;; +109;464;464;;;;;; +109;464;480;;;;;; +109;464;496;;;;;; +109;464;512;;;;;; +109;464;528;;;;;; +109;464;544;;;;;; +109;464;560;;;;;; +109;464;576;;;;;; +109;480;352;;;;;; +109;480;368;;;;;; +109;480;448;;;;;; +109;480;464;;;;;; +109;480;480;;;;;; +109;480;496;;;;;; +109;480;544;;;;;; +109;480;560;;;;;; +109;480;576;;;;;; +109;496;352;;;;;; +109;496;368;;;;;; +109;496;448;;;;;; +109;496;464;;;;;; +109;496;480;;;;;; +109;496;496;;;;;; +109;496;544;;;;;; +109;496;560;;;;;; +109;496;576;;;;;; +109;512;352;;;;;; +109;512;368;;;;;; +109;512;448;;;;;; +109;512;544;;;;;; +109;512;560;;;;;; +109;512;576;;;;;; +109;528;544;;;;;; +109;528;560;;;;;; +109;528;576;;;;;; +109;528;592;;;;;; +109;528;848;;;;;; +109;528;864;;;;;; +109;528;880;;;;;; +109;544;560;;;;;; +109;544;576;;;;;; +109;544;816;;;;;; +109;560;560;;;;;; +109;560;576;;;;;; +109;560;816;;;;;; +109;560;880;;;;;; +109;576;480;;;;;; +109;576;496;;;;;; +109;576;512;;;;;; +109;576;528;;;;;; +109;576;560;;;;;; +109;576;816;;;;;; +109;576;880;;;;;; +109;592;512;;;;;; +109;592;528;;;;;; +109;592;544;;;;;; +109;592;560;;;;;; +109;592;816;;;;;; +109;592;880;;;;;; +109;608;880;;;;;; +109;624;832;;;;;; +109;624;848;;;;;; +109;672;544;;;;;; +109;672;608;;;;;; +109;672;624;;;;;; +109;688;544;;;;;; +109;688;560;;;;;; +109;688;608;;;;;; +109;688;624;;;;;; +109;704;544;;;;;; +109;704;560;;;;;; +109;704;576;;;;;; +109;704;592;;;;;; +109;704;608;;;;;; +109;704;624;;;;;; +109;704;736;;;;;; +109;720;560;;;;;; +109;720;576;;;;;; +109;720;592;;;;;; +109;720;608;;;;;; +109;720;624;;;;;; +109;720;736;;;;;; +109;720;752;;;;;; +109;736;560;;;;;; +109;736;576;;;;;; +109;736;592;;;;;; +109;736;608;;;;;; +109;736;720;;;;;; +109;736;736;;;;;; +109;752;560;;;;;; +109;752;576;;;;;; +109;752;592;;;;;; +109;752;704;;;;;; +109;752;720;;;;;; +109;752;736;;;;;; +109;768;704;;;;;; +109;768;720;;;;;; +109;768;736;;;;;; +109;784;704;;;;;; +109;832;352;;;;;; +109;848;160;;;;;; +109;848;176;;;;;; +109;848;208;;;;;; +109;848;224;;;;;; +109;848;240;;;;;; +109;848;288;;;;;; +109;848;304;;;;;; +109;848;320;;;;;; +109;848;336;;;;;; +109;848;352;;;;;; +109;864;160;;;;;; +109;864;176;;;;;; +109;864;192;;;;;; +109;864;208;;;;;; +109;864;224;;;;;; +109;864;240;;;;;; +109;864;288;;;;;; +109;864;304;;;;;; +109;864;320;;;;;; +109;864;336;;;;;; +109;864;352;;;;;; +109;880;208;;;;;; +109;880;224;;;;;; +109;880;240;;;;;; +109;880;288;;;;;; +109;880;304;;;;;; +109;880;320;;;;;; +109;880;336;;;;;; +109;880;480;;;;;; +109;880;496;;;;;; +109;896;304;;;;;; +109;896;320;;;;;; +109;896;336;;;;;; +109;896;480;;;;;; +109;896;496;;;;;; +109;912;208;;;;;; +109;912;224;;;;;; +109;912;240;;;;;; +109;912;304;;;;;; +109;912;320;;;;;; +109;912;448;;;;;; +109;912;480;;;;;; +109;912;496;;;;;; +109;928;160;;;;;; +109;928;176;;;;;; +109;928;192;;;;;; +109;928;208;;;;;; +109;928;224;;;;;; +109;928;240;;;;;; +109;928;416;;;;;; +109;928;432;;;;;; +109;928;480;;;;;; +109;928;496;;;;;; +109;944;160;;;;;; +109;944;176;;;;;; +109;944;192;;;;;; +109;944;208;;;;;; +109;944;224;;;;;; +109;944;240;;;;;; +109;944;416;;;;;; +109;944;432;;;;;; +109;944;448;;;;;; +109;944;464;;;;;; +109;944;480;;;;;; +109;944;496;;;;;; +158;192;288 +158;192;304 +158;192;320 +158;192;336 +158;192;352 +158;208;288 +158;208;320 +158;208;352 +158;208;736 +158;224;288 +158;224;304 +158;224;320 +158;224;336 +158;224;352 +158;224;736 +158;224;752 +158;240;288 +158;240;304 +158;240;320 +158;240;336 +158;240;736 +158;240;752 +158;256;288 +158;256;304 +158;256;336 +158;256;736 +158;256;752 +158;272;304 +158;272;320 +158;272;720 +158;272;736 +158;288;560 +158;288;576 +158;288;592 +158;288;608 +158;288;720 +158;288;736 +158;304;560 +158;304;576 +158;304;592 +158;304;608 +158;320;576 +158;320;592 +158;320;608 +158;336;576 +158;336;592 +158;336;608 +158;352;560 +158;352;576 +158;352;592 +158;352;608 +158;368;560 +158;368;576 +158;368;592 +158;368;608 +158;384;576 +158;384;592 +158;384;608 +158;400;576 +158;432;416 +158;432;432 +158;432;496 +158;432;512 +158;432;528 +158;432;544 +158;448;416 +158;448;432 +158;448;448 +158;448;464 +158;448;480 +158;448;496 +158;448;512 +158;448;528 +158;448;544 +158;448;560 +158;464;368 +158;464;416 +158;464;432 +158;464;448 +158;464;464 +158;464;480 +158;464;496 +158;464;512 +158;464;528 +158;464;544 +158;464;560 +158;464;576 +158;480;352 +158;480;368 +158;480;448 +158;480;464 +158;480;480 +158;480;496 +158;480;544 +158;480;560 +158;480;576 +158;496;352 +158;496;368 +158;496;448 +158;496;464 +158;496;480 +158;496;496 +158;496;544 +158;496;560 +158;496;576 +158;512;352 +158;512;368 +158;512;448 +158;512;544 +158;512;560 +158;512;576 +158;528;544 +158;528;560 +158;528;576 +158;528;592 +158;528;848 +158;528;864 +158;528;880 +158;544;560 +158;544;576 +158;544;816 +158;560;560 +158;560;576 +158;560;816 +158;560;880 +158;576;480 +158;576;496 +158;576;512 +158;576;528 +158;576;560 +158;576;816 +158;576;880 +158;592;512 +158;592;528 +158;592;544 +158;592;560 +158;592;816 +158;592;880 +158;608;880 +158;624;832 +158;624;848 +158;672;544 +158;672;608 +158;672;624 +158;688;544 +158;688;560 +158;688;608 +158;688;624 +158;704;544 +158;704;560 +158;704;576 +158;704;592 +158;704;608 +158;704;624 +158;704;736 +158;720;560 +158;720;576 +158;720;592 +158;720;608 +158;720;624 +158;720;736 +158;720;752 +158;736;560 +158;736;576 +158;736;592 +158;736;608 +158;736;720 +158;736;736 +158;752;560 +158;752;576 +158;752;592 +158;752;704 +158;752;720 +158;752;736 +158;768;704 +158;768;720 +158;768;736 +158;784;704 +158;832;352 +158;848;160 +158;848;176 +158;848;208 +158;848;224 +158;848;240 +158;848;288 +158;848;304 +158;848;320 +158;848;336 +158;848;352 +158;864;160 +158;864;176 +158;864;192 +158;864;208 +158;864;224 +158;864;240 +158;864;288 +158;864;304 +158;864;320 +158;864;336 +158;864;352 +158;880;208 +158;880;224 +158;880;240 +158;880;288 +158;880;304 +158;880;320 +158;880;336 +158;880;480 +158;880;496 +158;896;304 +158;896;320 +158;896;336 +158;896;480 +158;896;496 +158;912;208 +158;912;224 +158;912;240 +158;912;304 +158;912;320 +158;912;448 +158;912;480 +158;912;496 +158;928;160 +158;928;176 +158;928;192 +158;928;208 +158;928;224 +158;928;240 +158;928;416 +158;928;432 +158;928;480 +158;928;496 +158;944;160 +158;944;176 +158;944;192 +158;944;208 +158;944;224 +158;944;240 +158;944;416 +158;944;432 +158;944;448 +158;944;464 +158;944;480 +158;944;496 diff --git a/bin/Data/Maps/dungeon4.map.data b/bin/Data/Maps/dungeon4.map.data new file mode 100644 index 0000000..7d11c6a --- /dev/null +++ b/bin/Data/Maps/dungeon4.map.data @@ -0,0 +1,60 @@ +62 +58 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon4_2d_1.map b/bin/Data/Maps/dungeon4_2d_1.map new file mode 100644 index 0000000..8ad9455 --- /dev/null +++ b/bin/Data/Maps/dungeon4_2d_1.map @@ -0,0 +1,648 @@ +3 +1 +1 +tileset 2d.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,33,113,109,107,109,113,109,107,109,113,113,113,113,109,107,109,113,113,76,33,, +,33,113,107,113,107,113,107,113,107,113,113,113,113,107,113,107,113,113,76,33,, +,33,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,76,33,, +,62,62,62,113,113,62,62,66,62,62,62,76,113,113,113,113,113,62,62,62,, +,46,113,113,113,113,113,113,66,48,49,46,76,113,113,113,113,113,113,48,49,, +,46,23,23,23,23,23,23,21,48,49,46,76,113,113,113,113,113,113,48,49,, +,46,23,23,23,23,23,23,21,48,49,46,45,45,45,83,83,83,83,48,49,, +,46,42,42,42,42,42,42,42,49,49,49,49,49,49,49,49,49,49,49,49,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,1,,,,,,,,,,,,,,,,,,,2,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +86 +124;32;96;;;;; +124;48;96;;;;; +124;64;96;;;;; +124;80;96;;;;; +124;96;96;;;;; +124;112;96;;;;; +0;16;16;;; +0;16;32;;; +0;16;48;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;32;64;;; +0;32;128;;; +0;48;64;;; +0;48;128;;; +0;64;128;;; +0;80;128;;; +0;96;64;;; +0;96;128;;; +0;112;64;;; +0;112;128;;; +0;128;128;;; +0;144;64;;; +0;144;80;;; +0;144;96;;; +0;144;112;;; +0;160;64;;; +0;176;64;;; +0;176;80;;; +0;176;96;;; +0;192;112;;; +0;208;112;;; +0;224;112;;; +0;240;128;;; +0;256;128;;; +0;272;128;;; +0;288;64;;; +0;288;128;;; +0;304;64;;; +0;304;80;;; +0;304;96;;; +0;304;112;;; +0;320;16;;; +0;320;32;;; +0;320;48;;; +0;320;64;;; +286;16;160;;;; +298;304;16;;;;;; +153;304;8;;;d4_2d_1;dungeon4.map;d4_2d_1;3;;False +245;80;160;four;False; +258;128;64; +258;128;80; +258;192;64; +258;192;80; +258;192;96; +258;304;16; +258;304;32; +258;304;48; +259;128;64; +259;192;64; +257;48;160 +346;208;64;48;;;1750; +287;112;160;32 +164;64;112;d4k4spawn;1;item;.d4_key_5.smallkey.four; +348;240;112 +348;256;112 +348;272;112 +348;288;112 +305;64;32;;;;; +305;128;32;;;;; +305;240;32;;;;; +158;32;96 +158;32;112 +158;48;96 +158;48;112 +158;64;96 +158;64;112 +158;80;96 +158;80;112 +158;96;96 +158;96;112 +158;112;96 +158;112;112 +158;128;96 +158;128;112 diff --git a/bin/Data/Maps/dungeon4_2d_1.map.data b/bin/Data/Maps/dungeon4_2d_1.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/dungeon4_2d_1.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon4_2d_2.map b/bin/Data/Maps/dungeon4_2d_2.map new file mode 100644 index 0000000..de2a19c --- /dev/null +++ b/bin/Data/Maps/dungeon4_2d_2.map @@ -0,0 +1,716 @@ +3 +1 +1 +tileset 2d.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,62,76,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,76,62,, +,46,76,113,113,33,33,113,113,113,113,113,113,33,113,113,113,113,113,76,48,, +,46,76,113,113,33,33,113,113,113,113,113,113,33,113,113,113,113,113,76,48,, +,46,23,23,23,33,33,23,23,23,23,23,23,33,23,23,23,23,23,23,48,, +,46,23,23,23,62,62,23,23,23,23,23,23,33,23,23,23,23,23,23,48,, +,46,23,23,23,23,23,23,23,23,23,23,23,62,23,23,23,23,41,42,49,, +,46,23,23,23,41,40,23,23,23,23,23,23,23,23,23,23,23,48,49,49,, +,49,42,42,42,49,49,42,42,42,42,42,42,42,42,42,42,42,49,49,49,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,1,,,,,,,,,,,,,,,,,,,2,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +154 +124;32;64;;;;; +124;48;64;;;;; +124;64;64;;;;; +124;112;64;;;;; +124;128;64;;;;; +124;144;64;;;;; +124;160;64;;;;; +124;176;64;;;;; +124;192;64;;;;; +124;224;64;;;;; +124;240;64;;;;; +124;256;64;;;;; +124;272;64;;;;; +124;288;64;;;;; +124;304;64;;;;; +0;16;16;;; +0;16;32;;; +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;32;128;;; +0;48;16;;; +0;48;128;;; +0;64;16;;; +0;64;128;;; +0;80;32;;; +0;80;48;;; +0;80;64;;; +0;80;80;;; +0;80;112;;; +0;96;32;;; +0;96;48;;; +0;96;64;;; +0;96;80;;; +0;96;112;;; +0;112;16;;; +0;112;128;;; +0;128;16;;; +0;128;128;;; +0;144;16;;; +0;144;128;;; +0;160;16;;; +0;160;128;;; +0;176;16;;; +0;176;128;;; +0;192;16;;; +0;192;128;;; +0;208;32;;; +0;208;48;;; +0;208;64;;; +0;208;80;;; +0;208;96;;; +0;208;128;;; +0;224;16;;; +0;224;128;;; +0;240;16;;; +0;240;128;;; +0;256;16;;; +0;256;128;;; +0;272;16;;; +0;272;128;;; +0;288;16;;; +0;288;96;;; +0;288;112;;; +0;304;96;;; +0;320;16;;; +0;320;32;;; +0;320;48;;; +0;320;64;;; +0;320;80;;; +286;16;160;;;; +298;32;16;;;;;; +298;304;16;;;;;; +153;32;8;;;d4_2d_2l;dungeon4.map;d4_2d_2l;3;1;False +153;304;8;;;d4_2d_2r;dungeon4.map;d4_2d_2r;3;1;False +245;80;160;four;False; +258;32;16; +258;32;32; +258;32;48; +258;304;16; +258;304;32; +258;304;48; +485;64;96;2; +485;128;64;3; +485;208;112;2; +485;240;64;3; +22;48;96;;;; +22;128;48;;;; +22;144;96;;;; +22;192;112;;;; +22;240;48;;;; +257;48;160 +287;112;160;32 +158;32;64 +158;32;80 +158;32;96 +158;32;112 +158;48;64 +158;48;80 +158;48;96 +158;48;112 +158;64;64 +158;64;80 +158;64;96 +158;64;112 +158;80;96 +158;96;96 +158;112;64 +158;112;80 +158;112;96 +158;112;112 +158;128;64 +158;128;80 +158;128;96 +158;128;112 +158;144;64 +158;144;80 +158;144;96 +158;144;112 +158;160;64 +158;160;80 +158;160;96 +158;160;112 +158;176;64 +158;176;80 +158;176;96 +158;176;112 +158;192;64 +158;192;80 +158;192;96 +158;192;112 +158;208;112 +158;224;64 +158;224;80 +158;224;96 +158;224;112 +158;240;64 +158;240;80 +158;240;96 +158;240;112 +158;256;64 +158;256;80 +158;256;96 +158;256;112 +158;272;64 +158;272;80 +158;272;96 +158;272;112 +158;288;64 +158;288;80 +158;304;64 +158;304;80 diff --git a/bin/Data/Maps/dungeon4_2d_2.map.data b/bin/Data/Maps/dungeon4_2d_2.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/dungeon4_2d_2.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon4_2d_3.map b/bin/Data/Maps/dungeon4_2d_3.map new file mode 100644 index 0000000..9207290 --- /dev/null +++ b/bin/Data/Maps/dungeon4_2d_3.map @@ -0,0 +1,648 @@ +3 +1 +1 +tileset 2d.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,62,66,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,66,62,, +,33,66,113,113,113,81,81,109,107,109,113,109,107,33,113,113,33,113,66,48,, +,33,66,113,62,113,113,113,107,113,107,113,107,113,33,113,113,33,113,66,48,, +,62,62,62,113,113,113,113,113,113,113,113,113,113,33,113,113,33,113,66,48,, +,49,46,113,76,113,113,113,113,62,62,62,62,113,62,113,113,62,113,66,48,, +,49,46,113,76,113,113,113,113,113,113,113,113,113,113,113,113,113,113,66,48,, +,49,46,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,66,48,, +,49,49,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,49,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,1,,,,,,,,,,,,,,,,,,,2,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +86 +0;16;16;;; +0;16;32;;; +0;16;48;;; +0;32;64;;; +0;32;80;;; +0;32;96;;; +0;32;112;;; +0;48;16;;; +0;48;64;;; +0;48;128;;; +0;64;16;;; +0;64;48;;; +0;64;128;;; +0;80;16;;; +0;80;128;;; +0;96;16;;; +0;96;128;;; +0;112;16;;; +0;112;128;;; +0;128;16;;; +0;128;128;;; +0;144;16;;; +0;144;80;;; +0;144;128;;; +0;160;16;;; +0;160;80;;; +0;160;128;;; +0;176;16;;; +0;176;80;;; +0;176;128;;; +0;192;16;;; +0;192;80;;; +0;192;128;;; +0;208;16;;; +0;208;128;;; +0;224;32;;; +0;224;48;;; +0;224;64;;; +0;224;80;;; +0;224;128;;; +0;240;16;;; +0;240;128;;; +0;256;16;;; +0;256;128;;; +0;272;32;;; +0;272;48;;; +0;272;64;;; +0;272;80;;; +0;272;128;;; +0;288;16;;; +0;288;128;;; +0;304;128;;; +0;320;16;;; +0;320;32;;; +0;320;48;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +0;320;112;;; +286;352;48;;;; +298;32;16;;;;;; +298;304;16;;;;;; +153;32;8;;;d4_2d_3l;dungeon4.map;d4_2d_3l;3;1;False +153;304;8;;;d4_2d_3r;dungeon4.map;d4_2d_3r;3;1;False +245;352;80;four;False; +258;32;16; +258;32;32; +258;32;48; +258;64;80; +258;64;96; +258;304;16; +258;304;32; +258;304;48; +258;304;64; +258;304;80; +258;304;96; +258;304;112; +259;64;80; +491;96;48 +491;240;32 +22;96;32;;;; +22;112;32;;;; +257;352;16 +287;352;112;32 +305;144;48;;;;; +305;208;48;;;;; diff --git a/bin/Data/Maps/dungeon4_2d_3.map.data b/bin/Data/Maps/dungeon4_2d_3.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/dungeon4_2d_3.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon4_2d_4.map b/bin/Data/Maps/dungeon4_2d_4.map new file mode 100644 index 0000000..49e3ab8 --- /dev/null +++ b/bin/Data/Maps/dungeon4_2d_4.map @@ -0,0 +1,887 @@ +3 +1 +1 +tileset 2d.png +12 +18 +3 +,,,,,,,,,,,, +,62,76,62,62,62,62,62,62,62,62,, +,33,76,109,107,109,113,109,107,109,33,, +,33,76,107,113,107,113,107,113,107,33,, +,33,76,113,113,113,113,113,113,113,33,, +,62,62,62,76,113,113,113,62,62,62,, +,113,113,113,113,113,113,113,113,113,113,, +,97,97,113,113,113,113,113,113,97,97,, +,97,97,113,113,113,113,113,113,97,97,, +,97,97,113,113,113,113,113,113,97,97,, +,97,113,113,113,113,113,113,113,113,97,, +,113,113,113,113,113,113,113,113,113,113,, +,113,113,113,113,113,113,113,113,113,113,, +,113,113,113,113,113,113,113,113,113,113,, +,113,113,113,113,113,113,113,113,113,113,, +,55,98,113,113,113,113,113,113,85,55,, +,55,55,55,98,85,55,38,55,55,55,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,1,,,,,,,,,2,0, +0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +301 +125;16;96;;;;; +125;32;96;;;;; +125;48;96;;;;; +125;64;96;;;;; +125;80;96;;;;; +125;96;96;;;;; +125;112;96;;;;; +125;128;96;;;;; +125;144;96;;;;; +125;160;96;;;;; +0;0;96;;; +0;0;112;;; +0;0;128;;; +0;0;144;;; +0;0;160;;; +0;0;176;;; +0;0;192;;; +0;0;208;;; +0;0;224;;; +0;0;240;;; +0;0;256;;; +0;0;272;;; +0;0;288;;; +0;16;16;;; +0;16;32;;; +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;272;;; +0;16;288;;; +0;32;80;;; +0;32;272;;; +0;32;288;;; +0;48;16;;; +0;48;80;;; +0;48;272;;; +0;48;288;;; +0;64;16;;; +0;64;272;;; +0;64;288;;; +0;80;16;;; +0;80;272;;; +0;80;288;;; +0;96;16;;; +0;96;272;;; +0;96;288;;; +0;112;16;;; +0;112;272;;; +0;112;288;;; +0;128;16;;; +0;128;80;;; +0;128;272;;; +0;128;288;;; +0;144;16;;; +0;144;80;;; +0;144;272;;; +0;144;288;;; +0;160;32;;; +0;160;48;;; +0;160;64;;; +0;160;80;;; +0;160;272;;; +0;160;288;;; +0;176;96;;; +0;176;112;;; +0;176;128;;; +0;176;144;;; +0;176;160;;; +0;176;176;;; +0;176;192;;; +0;176;208;;; +0;176;224;;; +0;176;240;;; +0;176;256;;; +0;176;272;;; +0;176;288;;; +286;192;16;;;; +298;32;16;;;;;; +153;32;8;;;d4_2d_4;dungeon4.map;d4_2d_4;3;1;False +245;224;48;four;False; +258;32;16; +258;32;32; +258;32;48; +258;32;64; +258;64;80; +259;64;80; +22;128;96;;;; +22;128;256;;;; +257;192;48 +287;224;16;32 +516;112;192;d4_nightmare_killed +305;64;48;;;;; +305;128;48;;;;; +158;-32;96 +158;-32;112 +158;-32;128 +158;-32;144 +158;-32;160 +158;-32;176 +158;-32;192 +158;-32;208 +158;-32;224 +158;-32;240 +158;-32;256 +158;-32;272 +158;-32;288 +158;-16;96 +158;-16;112 +158;-16;128 +158;-16;144 +158;-16;160 +158;-16;176 +158;-16;192 +158;-16;208 +158;-16;224 +158;-16;240 +158;-16;256 +158;-16;272 +158;-16;288 +158;0;96 +158;0;112 +158;0;128 +158;0;144 +158;0;160 +158;0;176 +158;0;192 +158;0;208 +158;0;224 +158;0;240 +158;0;256 +158;0;272 +158;0;288 +158;16;96 +158;16;112 +158;16;128 +158;16;144 +158;16;160 +158;16;176 +158;16;192 +158;16;208 +158;16;224 +158;16;240 +158;16;256 +158;16;272 +158;16;288 +158;32;96 +158;32;112 +158;32;128 +158;32;144 +158;32;160 +158;32;176 +158;32;192 +158;32;208 +158;32;224 +158;32;240 +158;32;256 +158;32;272 +158;32;288 +158;48;96 +158;48;112 +158;48;128 +158;48;144 +158;48;160 +158;48;176 +158;48;192 +158;48;208 +158;48;224 +158;48;240 +158;48;256 +158;48;272 +158;48;288 +158;64;96 +158;64;112 +158;64;128 +158;64;144 +158;64;160 +158;64;176 +158;64;192 +158;64;208 +158;64;224 +158;64;240 +158;64;256 +158;64;272 +158;64;288 +158;80;96 +158;80;112 +158;80;128 +158;80;144 +158;80;160 +158;80;176 +158;80;192 +158;80;208 +158;80;224 +158;80;240 +158;80;256 +158;80;272 +158;80;288 +158;96;96 +158;96;112 +158;96;128 +158;96;144 +158;96;160 +158;96;176 +158;96;192 +158;96;208 +158;96;224 +158;96;240 +158;96;256 +158;96;272 +158;96;288 +158;112;96 +158;112;112 +158;112;128 +158;112;144 +158;112;160 +158;112;176 +158;112;192 +158;112;208 +158;112;224 +158;112;240 +158;112;256 +158;112;272 +158;112;288 +158;128;96 +158;128;112 +158;128;128 +158;128;144 +158;128;160 +158;128;176 +158;128;192 +158;128;208 +158;128;224 +158;128;240 +158;128;256 +158;128;272 +158;128;288 +158;144;96 +158;144;112 +158;144;128 +158;144;144 +158;144;160 +158;144;176 +158;144;192 +158;144;208 +158;144;224 +158;144;240 +158;144;256 +158;144;272 +158;144;288 +158;160;96 +158;160;112 +158;160;128 +158;160;144 +158;160;160 +158;160;176 +158;160;192 +158;160;208 +158;160;224 +158;160;240 +158;160;256 +158;160;272 +158;160;288 +158;176;96 +158;176;112 +158;176;128 +158;176;144 +158;176;160 +158;176;176 +158;176;192 +158;176;208 +158;176;224 +158;176;240 +158;176;256 +158;176;272 +158;176;288 +158;192;96 +158;192;112 +158;192;128 +158;192;144 +158;192;160 +158;192;176 +158;192;192 +158;192;208 +158;192;224 +158;192;240 +158;192;256 +158;192;272 +158;192;288 +158;208;96 +158;208;112 +158;208;128 +158;208;144 +158;208;160 +158;208;176 +158;208;192 +158;208;208 +158;208;224 +158;208;240 +158;208;256 +158;208;272 +158;208;288 diff --git a/bin/Data/Maps/dungeon4_2d_4.map.data b/bin/Data/Maps/dungeon4_2d_4.map.data new file mode 100644 index 0000000..8f7cae4 --- /dev/null +++ b/bin/Data/Maps/dungeon4_2d_4.map.data @@ -0,0 +1,20 @@ +12 +18 +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon5.map b/bin/Data/Maps/dungeon5.map new file mode 100644 index 0000000..3e156c7 --- /dev/null +++ b/bin/Data/Maps/dungeon5.map @@ -0,0 +1,2453 @@ +3 +1 +2 +dungeon 5.png +72 +67 +3 +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,14,2,2,16,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,11,13,13,13,13,13,13,13,13,12,11,13,13,13,13,13,13,13,13,12,11,13,12,22,13,13,23,11,13,12,,,11,13,13,13,12,,,,11,13,13,13,13,13,13,13,13,12,,,,,,,,,,,,,,,,,,,,,, +,16,36,36,36,36,36,36,36,36,14,16,36,36,36,36,36,36,36,36,14,16,36,14,36,17,17,36,16,36,14,,,16,17,17,17,14,,,,16,36,36,36,36,36,36,36,36,14,,,,,,,,,,,,,,,,,,,,,, +,16,36,17,17,17,17,17,17,36,14,16,36,36,36,36,36,36,36,36,14,16,36,14,17,17,17,17,16,36,14,,,16,17,36,17,14,,,,16,36,17,17,17,17,17,17,36,14,,,,,,,,,,,,,,,,,,,,,, +,16,36,17,36,17,17,36,17,36,26,27,36,36,36,36,36,36,36,36,14,16,36,14,36,17,17,36,16,36,14,,,16,17,17,17,14,,,,16,36,17,36,17,17,36,17,36,14,,,,,,,,,,,,,,,,,,,,,, +,16,36,17,17,17,17,17,17,36,32,33,36,36,36,36,36,36,36,36,14,16,36,22,13,38,38,13,23,36,14,,,16,36,36,36,22,13,13,12,16,36,17,17,17,17,17,17,36,14,,,,,,,,,,,,,,,,,,,,,, +,16,36,36,17,36,36,17,36,36,14,16,36,36,36,36,36,36,36,36,14,16,36,36,36,17,17,36,36,36,14,,,16,36,36,36,36,36,36,26,27,36,36,17,36,36,17,36,36,14,,,,,,,,,,,,,,,,,,,,,, +,16,36,36,36,36,36,36,36,36,14,16,36,36,36,36,36,36,36,3,14,16,36,36,36,17,17,36,36,36,14,,,16,36,36,36,36,36,36,32,33,36,36,36,36,36,36,36,36,14,,,,,,,,,,,,,,,,,,,,,, +,9,15,15,15,15,15,15,15,15,10,9,15,15,15,15,15,15,15,15,10,9,15,15,15,28,31,15,15,15,10,,,9,15,15,15,15,15,15,10,9,15,15,15,28,31,15,15,15,10,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,11,13,41,42,29,30,41,42,13,12,11,13,13,13,12,11,13,13,13,12,11,13,13,13,29,30,13,13,13,12,11,13,13,13,13,13,13,13,13,12,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,16,36,36,36,36,36,36,36,36,14,16,17,17,17,14,16,36,36,3,14,16,36,36,36,36,36,36,36,36,14,16,36,36,37,37,37,37,17,36,14,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,16,36,17,17,17,17,17,17,36,14,16,17,36,17,14,16,35,35,35,14,16,36,36,36,36,36,36,36,36,22,23,36,36,36,36,36,36,17,35,14,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,16,36,17,36,35,35,36,17,36,14,16,17,17,17,22,23,40,40,40,14,16,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,35,40,14,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,16,36,17,36,37,37,36,17,36,14,16,35,36,35,40,40,40,40,40,14,16,36,36,36,36,36,36,36,36,20,21,36,36,36,36,36,36,40,40,14,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,16,36,17,17,17,17,17,17,36,14,16,40,36,37,37,37,37,40,40,14,16,36,36,36,36,36,36,36,36,14,16,36,36,36,36,36,36,40,40,14,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,16,36,36,36,36,36,36,36,36,14,16,40,36,36,36,36,36,37,37,14,16,36,36,36,36,36,36,36,36,14,16,36,36,36,36,36,36,37,37,14,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,9,15,43,44,28,31,43,44,15,10,9,15,15,15,15,15,15,15,15,10,9,21,36,20,15,15,15,15,15,10,16,36,36,36,36,36,36,36,36,14,,,,,,,,,,,, +,11,13,13,13,13,13,13,13,13,12,,,11,13,13,13,13,13,12,,11,13,13,13,29,30,13,13,13,13,13,13,13,13,13,13,13,13,13,12,11,23,36,22,13,13,13,13,13,12,16,36,36,36,36,36,36,17,17,22,13,13,13,13,13,13,13,13,13,12,, +,16,3,36,36,36,36,36,36,36,14,,,16,36,36,36,36,36,14,,16,36,36,36,17,17,36,36,36,36,36,36,40,40,40,40,36,36,36,14,16,,,,,,,,,14,16,36,36,36,36,36,36,36,17,36,36,36,40,40,40,40,36,36,36,14,, +,16,36,36,36,36,36,36,36,36,14,,,16,36,36,36,36,36,14,,9,15,15,15,15,15,15,15,21,36,36,36,40,40,40,40,36,36,36,14,16,,,,,,,,,14,16,34,36,36,36,36,36,17,17,36,36,36,37,37,37,37,36,17,17,14,, +,16,36,36,36,36,36,36,36,36,14,,,16,36,36,36,36,36,14,,,,,,,,,,9,15,15,21,40,40,40,40,36,36,36,14,16,,,,,,,,,14,16,34,36,36,36,34,36,35,20,15,21,36,36,36,36,36,36,17,36,14,, +,16,36,36,36,36,36,36,36,36,14,11,13,23,36,36,36,36,36,22,12,11,13,13,13,13,13,12,,,,,16,40,40,40,40,36,36,36,14,16,,,,,,,,,14,16,36,36,36,36,36,36,40,22,13,23,36,36,36,34,36,36,17,17,14,, +,16,36,36,36,36,36,36,36,36,26,27,36,36,36,36,36,36,36,36,26,27,36,36,36,36,36,22,13,13,13,13,23,37,37,37,37,36,3,36,14,16,,,,,,,,,14,16,36,36,36,36,36,36,37,36,36,36,36,36,36,36,36,36,36,36,14,, +,16,36,36,36,36,36,36,36,36,32,33,36,36,36,36,36,36,36,36,32,33,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,14,16,,,,,,,,,14,16,36,36,35,34,34,35,36,36,20,21,34,36,36,36,36,36,34,36,14,, +,9,15,15,15,15,15,15,15,15,10,9,15,15,15,15,15,15,15,15,10,9,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,10,9,21,,20,15,15,15,15,15,10,9,15,15,21,36,36,20,15,15,10,9,15,15,15,15,15,15,15,15,10,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,11,23,,22,13,13,13,13,13,12,,,,16,36,36,14,,,,11,13,13,13,13,13,13,13,13,12,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16,36,,,36,36,36,36,36,14,,,,16,36,36,14,,,,16,36,36,36,36,36,36,36,36,14,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16,36,36,,36,36,36,36,36,22,13,13,13,23,36,36,14,,,,16,36,17,17,17,17,17,17,36,14,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16,36,36,,36,36,36,36,36,36,36,36,36,36,17,36,22,13,13,12,16,36,17,36,17,17,36,17,36,14,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16,36,36,,36,36,36,36,36,36,36,36,36,17,36,17,36,36,36,26,27,36,17,17,17,17,17,17,36,14,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16,36,36,,36,36,36,36,36,20,15,15,21,36,17,36,36,36,36,32,33,36,36,17,36,36,17,36,36,14,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16,36,36,36,36,36,36,36,36,14,,,16,36,36,20,15,15,15,10,16,36,36,36,36,36,36,36,36,14,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,15,15,15,15,15,15,15,15,10,,,16,36,36,14,,,,,9,15,15,15,15,15,15,15,15,10,, +,,,,,,,,,,,,,,,,,,,,,11,13,13,13,13,13,13,13,13,12,11,13,13,13,13,13,13,13,13,12,11,13,13,13,13,13,13,13,13,12,11,13,23,36,36,14,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,16,36,36,36,36,36,36,36,36,26,27,36,36,36,36,36,17,3,17,14,16,36,36,36,36,36,36,36,36,14,16,17,17,17,34,22,13,12,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,16,36,17,17,17,17,17,17,36,32,33,36,36,36,36,36,17,17,17,14,16,36,17,17,17,17,17,17,36,14,16,17,36,17,36,36,36,14,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,16,36,17,36,17,17,36,17,36,14,9,21,36,36,36,36,36,36,36,14,16,36,17,36,17,17,36,17,36,14,16,17,17,17,36,36,36,22,13,12,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,16,36,17,17,17,17,17,17,36,14,,16,36,36,36,36,36,36,36,14,16,36,17,17,17,17,17,17,36,26,27,36,36,36,36,36,36,17,3,14,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,16,36,36,17,36,36,17,36,36,22,13,23,36,36,36,36,36,36,36,14,16,36,36,17,36,36,17,36,36,32,33,36,34,36,36,36,36,17,17,14,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,16,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,14,16,36,36,36,36,36,36,36,36,14,9,15,15,15,15,15,15,15,15,10,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,9,15,15,15,15,15,15,15,15,15,15,15,28,31,15,15,21,36,36,14,9,15,15,15,28,31,15,15,15,10,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,11,13,13,13,13,13,13,13,13,12,11,13,13,13,13,13,13,12,2,2,11,13,29,30,13,13,23,36,36,14,11,13,13,13,29,30,13,13,13,12,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,16,36,17,17,17,40,40,40,40,22,23,36,36,36,36,36,36,14,2,2,16,36,36,36,36,36,36,35,35,14,16,36,36,36,36,36,36,36,36,14,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,16,36,17,36,17,40,40,40,40,36,36,36,36,36,36,36,36,22,13,13,23,36,36,36,36,36,36,37,40,14,16,36,36,36,36,36,36,36,36,14,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,16,36,17,17,17,40,40,40,40,20,21,34,36,35,36,35,36,35,36,36,36,36,36,36,36,36,36,36,40,14,16,36,36,36,36,36,,36,36,14,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,16,36,36,36,36,37,37,37,37,14,16,36,36,37,36,37,36,37,36,36,36,36,36,36,36,36,36,35,40,14,16,36,36,36,36,36,,36,36,14,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,16,36,36,36,36,36,36,36,36,26,27,36,36,36,36,36,36,20,15,15,21,36,36,36,36,36,36,37,37,14,16,36,36,36,36,,,36,36,14,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,16,36,36,36,36,36,36,36,36,32,33,36,36,36,36,36,36,14,2,2,16,36,36,36,36,36,36,36,36,14,16,36,36,36,36,,,36,36,14,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,9,15,15,15,15,15,15,15,15,10,9,15,15,15,15,15,15,10,2,2,9,15,15,15,28,31,15,15,15,10,16,36,36,36,36,,,36,36,14,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,11,13,13,13,13,13,13,13,13,12,11,13,13,13,29,30,13,13,13,13,23,36,36,36,36,,,36,36,14,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,16,36,36,36,36,36,36,36,36,14,16,36,36,36,36,36,36,36,36,36,36,36,36,36,36,,36,36,36,14,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,16,36,36,36,36,36,36,36,36,14,16,36,36,36,36,36,36,36,36,36,36,36,36,36,36,,36,36,36,14,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,16,36,36,36,36,36,36,36,36,26,27,36,36,36,36,36,36,36,36,36,36,36,36,36,36,,36,36,36,14,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,16,36,36,36,36,36,36,36,36,32,33,36,36,36,36,36,36,36,36,36,36,36,36,36,36,,36,36,36,14,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,16,36,36,36,36,36,36,36,36,14,16,36,36,36,36,36,36,36,36,36,36,36,36,,,,36,36,36,14,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,16,36,36,36,36,36,36,36,36,14,16,36,36,36,36,36,36,36,36,36,36,36,36,,36,36,36,36,36,14,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,9,15,15,15,15,15,15,15,15,10,9,15,15,15,15,15,15,15,15,15,15,15,15,15,28,31,15,15,15,10,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,11,13,13,13,12,11,13,13,13,12,11,13,13,13,29,30,13,13,13,13,13,13,13,13,13,13,13,13,13,12,11,13,13,13,12,11,13,13,13,12,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16,17,17,17,14,16,17,17,17,14,16,36,36,,36,36,36,17,17,17,17,17,40,40,40,40,17,36,17,14,16,17,17,17,14,16,17,17,17,14,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16,17,3,17,22,23,17,36,17,14,16,36,36,36,,36,36,17,36,36,36,17,37,37,37,37,17,17,17,14,16,17,36,17,22,23,17,36,17,14,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16,17,17,17,36,36,17,17,17,26,27,17,17,17,,17,17,17,36,36,36,36,36,36,36,36,36,36,36,14,16,17,17,17,36,36,17,17,17,14,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16,36,36,36,36,36,36,36,36,32,33,17,36,36,,,36,36,36,36,36,36,36,36,36,36,36,36,36,14,16,36,36,36,36,36,36,36,36,14,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16,36,36,36,20,21,36,36,36,14,16,36,36,36,36,,36,36,36,20,21,36,36,36,36,36,36,36,36,22,23,36,36,6,5,5,4,36,36,14,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16,36,36,36,14,16,36,36,36,14,16,36,36,36,36,,36,36,36,14,16,36,36,36,36,36,36,36,36,36,36,36,36,19,25,24,18,36,36,14,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,15,15,15,10,9,15,15,15,10,9,15,15,15,15,15,15,15,15,10,9,15,15,15,15,15,15,15,15,15,15,15,15,7,1,0,8,15,15,10,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,,,,,,0,,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,,,,,,0,,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,,,,,,0,,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,,,,,,0,0,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0, +0,,,,,,,,,,,0,0,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,0,0,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,0,0,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,0,0,,,,,,,,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,0,0,0,,,,,0,0,0,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,0,0,,,,,0,,0,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,0,0,0,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,0,,,,,,,,,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,0,0,,,,,0,0,0,0,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,0,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,0,0,0,0,0, +524 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +waterfallSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +1719 +169;896;448;d5_button_d13 +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;16;128;;; +0;16;304;;; +0;16;320;;; +0;16;336;;; +0;16;352;;; +0;16;368;;; +0;16;384;;; +0;32;32;;; +0;32;144;;; +0;32;288;;; +0;32;400;;; +0;48;32;;; +0;48;144;;; +0;48;288;;; +0;48;400;;; +0;64;32;;; +0;64;144;;; +0;64;288;;; +0;64;400;;; +0;80;32;;; +0;80;144;;; +0;80;288;;; +0;80;400;;; +0;96;32;;; +0;96;144;;; +0;96;288;;; +0;96;400;;; +0;112;32;;; +0;112;144;;; +0;112;288;;; +0;112;400;;; +0;128;32;;; +0;128;144;;; +0;128;288;;; +0;128;400;;; +0;144;32;;; +0;144;144;;; +0;144;288;;; +0;144;400;;; +0;160;48;;; +0;160;64;;; +0;160;112;;; +0;160;128;;; +0;160;304;;; +0;160;320;;; +0;160;336;;; +0;160;352;;; +0;176;48;;; +0;176;64;;; +0;176;112;;; +0;176;128;;; +0;176;352;;; +0;176;688;;; +0;176;704;;; +0;176;720;;; +0;176;736;;; +0;176;752;;; +0;176;768;;; +0;192;32;;; +0;192;144;;; +0;192;352;;; +0;192;400;;; +0;192;672;;; +0;192;784;;; +0;208;32;;; +0;208;144;;; +0;208;304;;; +0;208;320;;; +0;208;336;;; +0;208;352;;; +0;208;400;;; +0;208;672;;; +0;208;784;;; +0;224;32;;; +0;224;144;;; +0;224;288;;; +0;224;400;;; +0;224;672;;; +0;224;784;;; +0;240;32;;; +0;240;144;;; +0;240;288;;; +0;240;400;;; +0;240;672;;; +0;240;784;;; +0;256;32;;; +0;256;144;;; +0;256;288;;; +0;256;400;;; +0;256;672;;; +0;256;784;;; +0;272;32;;; +0;272;144;;; +0;272;288;;; +0;272;400;;; +0;272;672;;; +0;272;784;;; +0;288;32;;; +0;288;144;;; +0;288;288;;; +0;288;400;;; +0;288;672;;; +0;288;784;;; +0;304;32;;; +0;304;144;;; +0;304;304;;; +0;304;320;;; +0;304;336;;; +0;304;352;;; +0;304;400;;; +0;304;672;;; +0;304;784;;; +0;320;48;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +0;320;112;;; +0;320;128;;; +0;320;688;;; +0;320;720;;; +0;320;736;;; +0;336;48;;; +0;336;64;;; +0;336;80;;; +0;336;96;;; +0;336;112;;; +0;336;128;;; +0;336;176;;; +0;336;192;;; +0;336;208;;; +0;336;224;;; +0;336;240;;; +0;336;256;;; +0;336;304;;; +0;336;560;;; +0;336;576;;; +0;336;592;;; +0;336;608;;; +0;336;624;;; +0;336;640;;; +0;336;688;;; +0;336;720;;; +0;336;736;;; +0;336;816;;; +0;336;832;;; +0;336;848;;; +0;336;864;;; +0;336;880;;; +0;336;896;;; +0;352;32;;; +0;352;144;;; +0;352;160;;; +0;352;272;;; +0;352;288;;; +0;352;320;;; +0;352;352;;; +0;352;400;;; +0;352;544;;; +0;352;656;;; +0;352;672;;; +0;352;784;;; +0;352;800;;; +0;352;912;;; +0;368;48;;; +0;368;144;;; +0;368;160;;; +0;368;272;;; +0;368;288;;; +0;368;320;;; +0;368;352;;; +0;368;400;;; +0;368;544;;; +0;368;656;;; +0;368;672;;; +0;368;784;;; +0;368;800;;; +0;368;912;;; +0;384;32;;; +0;384;144;;; +0;384;160;;; +0;384;272;;; +0;384;288;;; +0;384;320;;; +0;384;352;;; +0;384;400;;; +0;384;544;;; +0;384;656;;; +0;384;672;;; +0;384;784;;; +0;384;800;;; +0;384;912;;; +0;400;32;;; +0;400;320;;; +0;400;352;;; +0;400;400;;; +0;400;544;;; +0;400;656;;; +0;400;672;;; +0;400;784;;; +0;400;800;;; +0;400;912;;; +0;416;32;;; +0;416;320;;; +0;416;352;;; +0;416;400;;; +0;416;544;;; +0;416;656;;; +0;416;672;;; +0;416;784;;; +0;416;800;;; +0;416;912;;; +0;432;32;;; +0;432;144;;; +0;432;160;;; +0;432;272;;; +0;432;288;;; +0;432;320;;; +0;432;368;;; +0;432;400;;; +0;432;544;;; +0;432;656;;; +0;432;672;;; +0;432;784;;; +0;432;800;;; +0;432;912;;; +0;448;48;;; +0;448;144;;; +0;448;160;;; +0;448;272;;; +0;448;288;;; +0;448;320;;; +0;448;368;;; +0;448;400;;; +0;448;544;;; +0;448;656;;; +0;448;688;;; +0;448;704;;; +0;448;752;;; +0;448;768;;; +0;448;800;;; +0;448;912;;; +0;464;32;;; +0;464;144;;; +0;464;160;;; +0;464;272;;; +0;464;288;;; +0;464;320;;; +0;464;368;;; +0;464;400;;; +0;464;544;;; +0;464;656;;; +0;464;704;;; +0;464;752;;; +0;464;800;;; +0;464;912;;; +0;480;48;;; +0;480;64;;; +0;480;80;;; +0;480;96;;; +0;480;112;;; +0;480;128;;; +0;480;176;;; +0;480;192;;; +0;480;208;;; +0;480;224;;; +0;480;240;;; +0;480;256;;; +0;480;288;;; +0;480;336;;; +0;480;368;;; +0;480;400;;; +0;480;592;;; +0;480;608;;; +0;480;624;;; +0;480;656;;; +0;480;704;;; +0;480;752;;; +0;480;816;;; +0;480;832;;; +0;480;880;;; +0;480;896;;; +0;496;176;;; +0;496;192;;; +0;496;208;;; +0;496;224;;; +0;496;240;;; +0;496;256;;; +0;496;288;;; +0;496;336;;; +0;496;368;;; +0;496;400;;; +0;496;592;;; +0;496;624;;; +0;496;656;;; +0;496;672;;; +0;496;688;;; +0;496;704;;; +0;496;752;;; +0;496;768;;; +0;496;816;;; +0;496;832;;; +0;496;880;;; +0;496;896;;; +0;496;944;;; +0;496;960;;; +0;496;976;;; +0;496;992;;; +0;496;1008;;; +0;496;1024;;; +0;512;160;;; +0;512;272;;; +0;512;288;;; +0;512;336;;; +0;512;352;;; +0;512;368;;; +0;512;400;;; +0;512;544;;; +0;512;592;;; +0;512;608;;; +0;512;624;;; +0;512;656;;; +0;512;672;;; +0;512;784;;; +0;512;800;;; +0;512;912;;; +0;512;928;;; +0;512;1040;;; +0;528;48;;; +0;528;64;;; +0;528;80;;; +0;528;96;;; +0;528;112;;; +0;528;128;;; +0;528;160;;; +0;528;272;;; +0;528;288;;; +0;528;400;;; +0;528;544;;; +0;528;784;;; +0;528;800;;; +0;528;912;;; +0;528;928;;; +0;528;1040;;; +0;544;32;;; +0;544;144;;; +0;544;160;;; +0;544;272;;; +0;544;288;;; +0;544;400;;; +0;544;544;;; +0;544;784;;; +0;544;800;;; +0;544;912;;; +0;544;928;;; +0;544;1040;;; +0;560;32;;; +0;560;144;;; +0;560;176;;; +0;560;192;;; +0;560;208;;; +0;560;272;;; +0;560;288;;; +0;560;400;;; +0;560;544;;; +0;560;656;;; +0;560;672;;; +0;560;912;;; +0;560;944;;; +0;560;960;;; +0;560;1008;;; +0;560;1024;;; +0;576;32;;; +0;576;144;;; +0;576;176;;; +0;576;192;;; +0;576;208;;; +0;576;272;;; +0;576;288;;; +0;576;400;;; +0;576;544;;; +0;576;656;;; +0;576;672;;; +0;576;912;;; +0;576;944;;; +0;576;960;;; +0;576;1008;;; +0;576;1024;;; +0;592;48;;; +0;592;64;;; +0;592;80;;; +0;592;96;;; +0;592;144;;; +0;592;160;;; +0;592;272;;; +0;592;288;;; +0;592;400;;; +0;592;544;;; +0;592;656;;; +0;592;672;;; +0;592;784;;; +0;592;800;;; +0;592;912;;; +0;592;928;;; +0;592;1040;;; +0;608;96;;; +0;608;144;;; +0;608;160;;; +0;608;272;;; +0;608;288;;; +0;608;400;;; +0;608;544;;; +0;608;784;;; +0;608;800;;; +0;608;912;;; +0;608;928;;; +0;608;1040;;; +0;624;96;;; +0;624;144;;; +0;624;160;;; +0;624;272;;; +0;624;288;;; +0;624;400;;; +0;624;544;;; +0;624;784;;; +0;624;800;;; +0;624;912;;; +0;624;928;;; +0;624;1040;;; +0;640;96;;; +0;640;176;;; +0;640;192;;; +0;640;208;;; +0;640;224;;; +0;640;240;;; +0;640;256;;; +0;640;304;;; +0;640;320;;; +0;640;336;;; +0;640;352;;; +0;640;368;;; +0;640;384;;; +0;640;560;;; +0;640;576;;; +0;640;592;;; +0;640;608;;; +0;640;624;;; +0;640;640;;; +0;640;656;;; +0;640;672;;; +0;640;688;;; +0;640;704;;; +0;640;720;;; +0;640;736;;; +0;640;752;;; +0;640;768;;; +0;640;784;;; +0;640;800;;; +0;640;944;;; +0;640;960;;; +0;640;1008;;; +0;640;1024;;; +0;656;48;;; +0;656;64;;; +0;656;80;;; +0;656;96;;; +0;656;176;;; +0;656;192;;; +0;656;208;;; +0;656;224;;; +0;656;240;;; +0;656;256;;; +0;656;304;;; +0;656;320;;; +0;656;336;;; +0;656;352;;; +0;656;368;;; +0;656;384;;; +0;656;432;;; +0;656;448;;; +0;656;464;;; +0;656;480;;; +0;656;496;;; +0;656;512;;; +0;656;560;;; +0;656;576;;; +0;656;592;;; +0;656;608;;; +0;656;624;;; +0;656;640;;; +0;656;688;;; +0;656;704;;; +0;656;720;;; +0;656;736;;; +0;656;752;;; +0;656;768;;; +0;656;784;;; +0;656;800;;; +0;656;944;;; +0;656;960;;; +0;656;1008;;; +0;656;1024;;; +0;672;32;;; +0;672;144;;; +0;672;160;;; +0;672;272;;; +0;672;288;;; +0;672;400;;; +0;672;416;;; +0;672;528;;; +0;672;544;;; +0;672;656;;; +0;672;672;;; +0;672;912;;; +0;672;928;;; +0;672;1040;;; +0;688;32;;; +0;688;144;;; +0;688;160;;; +0;688;528;;; +0;688;544;;; +0;688;656;;; +0;688;672;;; +0;688;912;;; +0;688;928;;; +0;688;1040;;; +0;704;32;;; +0;704;144;;; +0;704;160;;; +0;704;272;;; +0;704;288;;; +0;704;400;;; +0;704;416;;; +0;704;528;;; +0;704;544;;; +0;704;656;;; +0;704;672;;; +0;704;912;;; +0;704;928;;; +0;704;1040;;; +0;720;32;;; +0;720;272;;; +0;720;288;;; +0;720;400;;; +0;720;416;;; +0;720;528;;; +0;720;544;;; +0;720;1040;;; +0;736;32;;; +0;736;272;;; +0;736;288;;; +0;736;400;;; +0;736;416;;; +0;736;528;;; +0;736;544;;; +0;736;1040;;; +0;752;32;;; +0;752;144;;; +0;752;160;;; +0;752;272;;; +0;752;288;;; +0;752;400;;; +0;752;416;;; +0;752;528;;; +0;752;544;;; +0;752;656;;; +0;752;672;;; +0;752;912;;; +0;752;928;;; +0;752;1040;;; +0;768;32;;; +0;768;144;;; +0;768;160;;; +0;768;272;;; +0;768;288;;; +0;768;400;;; +0;768;416;;; +0;768;528;;; +0;768;544;;; +0;768;656;;; +0;768;672;;; +0;768;912;;; +0;768;928;;; +0;768;1040;;; +0;784;32;;; +0;784;144;;; +0;784;160;;; +0;784;272;;; +0;784;288;;; +0;784;400;;; +0;784;416;;; +0;784;528;;; +0;784;544;;; +0;784;656;;; +0;784;672;;; +0;784;912;;; +0;784;928;;; +0;784;1040;;; +0;800;48;;; +0;800;64;;; +0;800;80;;; +0;800;96;;; +0;800;112;;; +0;800;128;;; +0;800;176;;; +0;800;192;;; +0;800;224;;; +0;800;240;;; +0;800;256;;; +0;800;304;;; +0;800;320;;; +0;800;336;;; +0;800;352;;; +0;800;368;;; +0;800;384;;; +0;800;432;;; +0;800;448;;; +0;800;496;;; +0;800;512;;; +0;800;560;;; +0;800;576;;; +0;800;592;;; +0;800;640;;; +0;800;688;;; +0;800;704;;; +0;800;720;;; +0;800;736;;; +0;800;752;;; +0;800;768;;; +0;800;784;;; +0;800;800;;; +0;800;816;;; +0;800;832;;; +0;800;848;;; +0;800;864;;; +0;800;880;;; +0;800;896;;; +0;800;928;;; +0;800;1008;;; +0;800;1024;;; +0;816;176;;; +0;816;192;;; +0;816;224;;; +0;816;240;;; +0;816;256;;; +0;816;272;;; +0;816;288;;; +0;816;304;;; +0;816;320;;; +0;816;336;;; +0;816;352;;; +0;816;368;;; +0;816;384;;; +0;816;448;;; +0;816;496;;; +0;816;560;;; +0;816;576;;; +0;816;592;;; +0;816;928;;; +0;816;1008;;; +0;816;1024;;; +0;832;160;;; +0;832;400;;; +0;832;448;;; +0;832;496;;; +0;832;544;;; +0;832;640;;; +0;832;928;;; +0;832;1040;;; +0;848;160;;; +0;848;400;;; +0;848;448;;; +0;848;496;;; +0;848;512;;; +0;848;528;;; +0;848;544;;; +0;848;640;;; +0;848;928;;; +0;848;1040;;; +0;864;160;;; +0;864;400;;; +0;864;416;;; +0;864;432;;; +0;864;448;;; +0;864;640;;; +0;864;928;;; +0;864;1040;;; +0;880;160;;; +0;880;640;;; +0;880;928;;; +0;880;1040;;; +0;896;160;;; +0;896;512;;; +0;896;528;;; +0;896;544;;; +0;896;560;;; +0;896;640;;; +0;896;928;;; +0;896;1040;;; +0;912;160;;; +0;912;400;;; +0;912;416;;; +0;912;432;;; +0;912;448;;; +0;912;464;;; +0;912;512;;; +0;912;560;;; +0;912;640;;; +0;912;928;;; +0;912;1040;;; +0;928;160;;; +0;928;400;;; +0;928;464;;; +0;928;512;;; +0;928;576;;; +0;928;592;;; +0;928;640;;; +0;928;928;;; +0;928;1040;;; +0;944;160;;; +0;944;336;;; +0;944;352;;; +0;944;464;;; +0;944;512;;; +0;944;592;;; +0;944;640;;; +0;944;928;;; +0;944;1040;;; +0;960;176;;; +0;960;192;;; +0;960;208;;; +0;960;224;;; +0;960;240;;; +0;960;256;;; +0;960;272;;; +0;960;288;;; +0;960;336;;; +0;960;352;;; +0;960;384;;; +0;960;608;;; +0;960;624;;; +0;960;944;;; +0;960;960;;; +0;960;976;;; +0;960;992;;; +0;960;1008;;; +0;960;1040;;; +0;976;288;;; +0;976;336;;; +0;976;352;;; +0;976;384;;; +0;976;448;;; +0;976;464;;; +0;976;512;;; +0;976;944;;; +0;976;960;;; +0;976;976;;; +0;976;992;;; +0;976;1008;;; +0;976;1040;;; +0;992;288;;; +0;992;400;;; +0;992;528;;; +0;992;928;;; +0;992;1040;;; +0;1008;288;;; +0;1008;400;;; +0;1008;416;;; +0;1008;528;;; +0;1008;928;;; +0;1008;1040;;; +0;1024;288;;; +0;1024;400;;; +0;1024;416;;; +0;1024;528;;; +0;1024;928;;; +0;1024;1040;;; +0;1040;288;;; +0;1040;400;;; +0;1040;416;;; +0;1040;528;;; +0;1040;944;;; +0;1040;960;;; +0;1048;1056;;; +0;1056;288;;; +0;1056;400;;; +0;1056;416;;; +0;1056;528;;; +0;1056;944;;; +0;1056;960;;; +0;1072;288;;; +0;1072;400;;; +0;1072;416;;; +0;1072;528;;; +0;1072;928;;; +0;1072;1040;;; +0;1088;288;;; +0;1088;400;;; +0;1088;416;;; +0;1088;528;;; +0;1088;928;;; +0;1088;1040;;; +0;1104;288;;; +0;1104;400;;; +0;1104;416;;; +0;1104;528;;; +0;1104;928;;; +0;1104;1040;;; +0;1120;304;;; +0;1120;320;;; +0;1120;336;;; +0;1120;352;;; +0;1120;368;;; +0;1120;384;;; +0;1120;432;;; +0;1120;448;;; +0;1120;464;;; +0;1120;480;;; +0;1120;496;;; +0;1120;512;;; +0;1120;944;;; +0;1120;960;;; +0;1120;976;;; +0;1120;992;;; +0;1120;1008;;; +0;1120;1024;;; +1;160;96;;; +1;160;384;;; +1;176;96;;; +1;176;384;;; +1;320;384;;; +1;320;768;;; +1;336;360;;; +1;336;768;;; +1;480;576;;; +1;480;864;;; +1;496;576;;; +1;496;864;;; +1;640;128;;; +1;640;992;;; +1;656;128;;; +1;656;992;;; +1;800;624;;; +1;816;624;;; +1;960;496;;; +1;976;496;;; +1;1032;1024;;; +1;1064;1024;;; +3;400;144;;; +3;400;160;;; +3;400;272;;; +3;400;288;;; +3;528;656;;; +3;528;672;;; +3;560;784;;; +3;560;800;;; +3;720;144;;; +3;720;160;;; +3;720;656;;; +3;720;672;;; +3;720;912;;; +3;720;928;;; +3;1040;1040;;; +4;416;144;;; +4;416;160;;; +4;416;272;;; +4;416;288;;; +4;544;656;;; +4;544;672;;; +4;576;784;;; +4;576;800;;; +4;736;144;;; +4;736;160;;; +4;736;656;;; +4;736;672;;; +4;736;912;;; +4;736;928;;; +4;1056;1040;;; +2;160;80;;; +2;160;368;;; +2;176;80;;; +2;176;368;;; +2;320;368;;; +2;320;752;;; +2;336;392;;; +2;336;752;;; +2;480;560;;; +2;480;848;;; +2;496;560;;; +2;496;848;;; +2;640;112;;; +2;640;976;;; +2;656;112;;; +2;656;976;;; +2;800;608;;; +2;816;608;;; +2;960;480;;; +2;976;480;;; +199;224;704;smallkeyChest;;d5_key_3;; +199;528;192;nightmarekey;five;d5_nkey;; +199;560;64;dmap;five;d5_dmap;; +199;608;960;compass;five;d5_compass;; +199;848;576;dialog:master_stalfos_chest;;d5_ms_chest;; +199;928;304;ruby50;;d5_ruby50_0;; +199;928;944;ruby200;;d5_200_rupees;; +199;944;176;ruby50;;d5_ruby50_1;; +199;1104;336;smallkeyChest;;d5_key_2;; +289;224;688;d5_key_3 +289;248;48;d5_key_1 +289;528;176;d5_nkey +289;1104;320;d5_key_2 +273;208;80;;;; +273;208;96;;;; +273;224;64;;;; +273;224;96;;;; +273;224;112;;;; +273;240;64;;;; +273;240;80;;;; +273;240;112;;;; +273;256;64;;;; +273;256;80;;;; +273;256;112;;;; +273;272;64;;;; +273;272;96;;;; +273;272;112;;;; +273;272;128;;;; +273;288;80;;;; +273;288;96;;;; +273;304;96;;;; +273;672;704;;;; +273;672;752;;;; +273;672;768;;;; +273;672;832;;;; +273;672;896;;;; +273;688;768;;;; +273;688;880;;;; +273;704;816;;;; +273;720;736;;;; +273;720;752;;;; +273;720;816;;;; +273;720;864;;;; +273;736;736;;;; +273;752;816;;;; +273;768;768;;;; +273;768;880;;;; +273;784;704;;;; +273;784;752;;;; +273;784;768;;;; +273;784;832;;;; +273;784;896;;;; +261;160;88;;d5_door_16;; +261;160;376;;d5_door_8;; +261;176;88;;d5_door_16;2; +261;176;376;;d5_door_8;2; +261;320;376;;d5_door_9;; +261;320;760;;d5_door_5;; +261;336;376;;d5_door_9;2; +261;336;760;;d5_door_5;2; +261;408;144;2;d5_door_15;1; +261;408;160;2;d5_door_15;3; +261;408;272;2;d5_door_14;1; +261;408;288;3;d5_door_14;3;d5_ndoor +261;480;568;;d5_door_10;; +261;480;856;;d5_door_4;; +261;496;568;;d5_door_10;2; +261;496;856;;d5_door_4;2; +261;536;656;;d5_door_17;1; +261;536;672;;d5_door_17;3; +261;568;784;;d5_door_3;1; +261;568;800;;d5_door_3;3; +261;640;120;;d5_door_12;; +261;640;984;;d5_door_2;; +261;656;120;;d5_door_12;2; +261;656;984;;d5_door_2;2; +261;728;144;;d5_door_11;1; +261;728;160;;d5_door_11;3; +261;728;656;;d5_door_6;1; +261;728;672;;d5_door_6;3; +261;728;912;;d5_door_1;1; +261;728;928;1;d5_door_1;3;d5_door_1 +261;800;616;;d5_door_7;; +261;816;616;;d5_door_7;2; +261;960;488;;d5_door_13;; +261;976;488;;d5_door_13;2; +174;1056;1088;dungeon_5 +153;32;304;;;d5_2d_2L;dungeon5_2d_2.map;d5_2d_2L;2;1;False +153;304;128;;;d5_2d_1L;dungeon5_2d_1.map;d5_2d_1L;;1;False +153;528;960;;;d5_2d_1R;dungeon5_2d_1.map;d5_2d_1R;2;1;False +153;608;368;;;d5_2d_3L;dungeon5_2d_3.map;d5_2d_3L;2;1;False +153;608;560;;;d5_2d_3R;dungeon5_2d_3.map;d5_2d_3R;2;1;False +153;624;176;;;d5_2d_4L;dungeon5_2d_4.map;d5_2d_4L;;1;False +153;720;336;48;48;d5_2d_4R;dungeon5_2d_4.map;d5_2d_4R;-1;3;False +153;944;608;;;d5_2d_2R;dungeon5_2d_2.map;d5_2d_2R;;1;False +153;1048;1048;;;d5;overworld.map;d5;1;; +245;1024;1088;five;; +280;832;320; +280;832;336; +280;848;624; +280;880;560; +280;896;336; +280;992;384; +280;1040;352; +280;1088;384; +284;1088;1088;;;; +351;256;289;beak_d5_2 +351;768;673;beak_d5_1 +52;80;320;;;;;; +52;80;368;;;;;; +52;96;320;;;;;; +52;96;368;;;;;; +52;384;48;;;;;; +52;384;80;;;;;; +52;432;48;;;;;; +52;432;80;;;;;; +52;464;688;;;;;; +52;464;768;;;;;; +52;528;1008;;;;;; +52;576;688;;;;;; +52;608;1008;;;;;; +52;704;960;;;;;; +52;704;992;;;;;; +52;752;960;;;;;; +52;752;992;;;;;; +52;864;1008;;;;;; +52;912;1008;;;;;; +52;1008;960;;;;;; +52;1088;960;;;;;; +429;272;320 +429;576;624 +467;208;736 +467;224;752 +467;272;768 +467;384;848 +467;416;880 +467;544;848 +467;560;992 +467;576;880 +467;576;976 +467;688;848 +467;720;976 +467;880;992 +468;240;320 +468;240;384 +468;272;384 +468;704;448 +468;864;352 +468;880;224 +465;672;352 +465;736;304 +465;736;384 +465;784;352 +427;704;960 +427;704;992 +427;752;960 +427;752;992 +428;412;848;;False; +428;416;388;2;; +428;560;972;3;False; +428;744;172;2;False; +428;832;460;1;False; +428;896;988;3;False; +428;928;500;3;False; +428;1008;348;2;False; +437;192;112; +437;224;48; +437;544;80;True +437;576;80;True +437;704;880; +437;752;736; +425;528;720 +425;544;608 +425;560;576 +425;560;720 +425;896;1008 +425;1040;384 +422;400;688;;;;2 +422;400;768;;;2; +422;432;688;;;;2 +422;432;768;;;2; +422;512;816;;3;;2 +422;512;896;;3;2; +422;624;816;3;;;2 +422;624;896;3;;2; +422;672;432;;3;;2 +422;672;512;;3;2; +422;784;432;3;;;2 +422;784;512;3;;2; +424;368;704;; +424;368;752;; +424;688;224;; +424;736;192;; +424;768;208;; +424;848;592;; +424;880;576;; +424;880;608;; +252;88;344;d5_et_6 +252;232;728;d5_et_4 +252;248;352;d5_et_7 +252;408;824;d5_et_3 +252;544;696;d5_et_8 +252;560;824;d5_et_2 +252;568;936;d5_et_d2 +252;616;72;d5_et_12 +252;680;952;d5_et_1 +252;720;696;d5_et_5 +252;728;176;d5_et_9 +22;168;376;;;; +22;328;376;;;; +22;488;856;;;; +22;496;384;;;; +22;648;984;;;; +22;688;288;;;; +22;728;144;;;; +22;800;464;;;; +22;800;480;;;; +22;808;992;;;; +22;816;208;;;; +22;864;536;;;; +22;880;408;;;; +22;880;536;;;; +22;896;408;;;; +22;968;1024;;;; +22;976;488;;;; +342;256;688;;;;;; +342;256;704;;;;;; +342;256;720;;;;;; +342;256;736;;;;;; +342;272;688;;;;;; +342;272;704;;;;;; +342;272;720;;;;;; +342;272;736;;;;;; +342;288;688;;;;;; +342;288;704;;;;;; +342;288;720;;;;;; +342;288;736;;;;;; +342;304;688;;;;;; +342;304;704;;;;;; +342;304;720;;;;;; +342;304;736;;;;;; +342;352;720;;;;;; +342;384;720;;;;;; +342;384;736;;;;;; +342;416;720;;;;;; +342;416;736;;;;;; +342;448;720;;;;;; +342;448;736;;;;;; +342;512;224;;;;;; +342;512;240;;;;;; +342;512;256;;;;;; +342;528;304;;;;;; +342;528;320;;;;;; +342;528;336;;;;;; +342;528;352;;;;;; +342;528;368;;;;;; +342;544;224;;;;;; +342;544;240;;;;;; +342;544;304;;;;;; +342;544;320;;;;;; +342;544;336;;;;;; +342;544;352;;;;;; +342;544;368;;;;;; +342;560;224;;;;;; +342;560;240;;;;;; +342;560;304;;;;;; +342;560;320;;;;;; +342;560;336;;;;;; +342;560;352;;;;;; +342;560;368;;;;;; +342;576;224;;;;;; +342;576;240;;;;;; +342;576;304;;;;;; +342;576;320;;;;;; +342;576;336;;;;;; +342;576;352;;;;;; +342;576;368;;;;;; +342;592;192;;;;;; +342;592;208;;;;;; +342;592;224;;;;;; +342;592;240;;;;;; +342;608;192;;;;;; +342;608;208;;;;;; +342;608;224;;;;;; +342;608;240;;;;;; +342;608;688;;;;;; +342;608;704;;;;;; +342;608;736;;;;;; +342;608;752;;;;;; +342;624;192;;;;;; +342;624;208;;;;;; +342;624;224;;;;;; +342;624;240;;;;;; +342;624;256;;;;;; +342;624;704;;;;;; +342;624;720;;;;;; +342;624;736;;;;;; +342;624;752;;;;;; +342;848;944;;;;;; +342;848;960;;;;;; +342;864;176;;;;;; +342;864;384;;;;;; +342;864;944;;;;;; +342;864;960;;;;;; +342;880;176;;;;;; +342;880;384;;;;;; +342;880;944;;;;;; +342;880;960;;;;;; +342;896;176;;;;;; +342;896;384;;;;;; +342;896;944;;;;;; +342;896;960;;;;;; +342;912;176;;;;;; +342;912;384;;;;;; +342;928;208;;;;;; +342;928;224;;;;;; +342;928;240;;;;;; +342;928;256;;;;;; +342;928;336;;;;;; +342;928;352;;;;;; +342;928;368;;;;;; +342;944;208;;;;;; +342;944;224;;;;;; +342;944;240;;;;;; +342;944;256;;;;;; +342;1008;304;;;;;; +342;1008;320;;;;;; +342;1024;304;;;;;; +342;1024;320;;;;;; +342;1040;304;;;;;; +342;1040;320;;;;;; +342;1056;304;;;;;; +342;1056;320;;;;;; +274;688;448;;;; +274;688;496;;;; +274;720;464;;;; +274;736;480;;;; +274;768;448;;;; +274;768;496;;;; +343;408;256;3 +200;224;752;w;;arrow;; +200;400;880;w;;bomb_10;; +200;408;72;;d5_instrument;instrument4;; +200;544;736;w;;arrow;; +200;560;112;w;;heart_3;; +200;944;240;w;;heart_3;; +200;1040;368;w;;bomb_10;; +162;376;64;-18;2;8;;;;;; +162;448;64;18;2;8;;;;;; +168;168;24;d5_door_16;!d5_enter_d16|d5_ms!=3; +168;168;424;d5_door_8;d5_et_7|!d5_enter_5; +168;248;8;d5_key1_spawn;d5_block_1&d5_block_2; +168;312;264;d5_door_14;d5_ndoor&(!d5_enter_ndoor|d5_nHeart); +168;328;152;d5_door_15;d5_nHeart&(!d5_enter_I|d5_instrument); +168;328;424;d5_door_9;d5_et_7|!d5_enter_5; +168;328;792;d5_door_5;d5_et_4; +168;488;528;d5_door_10;d5_gohma; +168;488;880;d5_door_4;d5_et_2|!d5_enter_2; +168;560;664;d5_door_17;!d5_enter_6; +168;592;792;d5_door_3;d5_et_2|!d5_enter_2; +168;648;96;d5_door_12;d5_et_9&(!d5_enter_d11|d5_ms!=2)&(!d5_enter_d12|d5_et_12); +168;648;1064;d5_door_2;(d5_et_1|!d5_enter_1)&(d5_et_d2|!d5_enter_d2); +168;704;664;d5_door_6;(d5_et_5|!d5_enter_3)&(!d5_enter_4|d5_ms!=0); +168;808;592;d5_door_7;!d5_enter_4|d5_ms!=0; +168;824;136;d5_door_11;d5_et_9&(!d5_enter_d11|d5_ms!=2); +168;968;464;d5_door_13;(!d5_enter_d13|d5_ms!=1)&d5_button_d13; +334;512;640;d5_barrier_2 +334;624;352;d5_barrier_1 +167;104;344;d5_et_6;0 +167;152;728;d5_et_4;0 +167;168;0;d5_enter_d16;0 +167;256;424;d5_enter_5;0 +167;264;352;d5_et_7;0 +167;312;240;d5_enter_ndoor;0 +167;456;936;d5_et_2;0 +167;472;936;d5_enter_2;0 +167;504;112;d5_enter_I;0 +167;520;696;d5_enter_6;0 +167;544;712;d5_et_8;0 +167;568;1064;d5_et_d2;0 +167;568;1088;d5_enter_d2;0 +167;616;24;d5_et_12;0 +167;648;72;d5_enter_d12;0 +167;728;192;d5_et_9;0 +167;728;1064;d5_et_1;0 +167;728;1088;d5_enter_1;0 +167;808;664;d5_enter_4;0 +167;824;112;d5_enter_d11;0 +167;824;704;d5_et_5;0 +167;824;800;d5_enter_3;0 +167;928;448;d5_button_d13;0 +167;968;440;d5_enter_d13;0 +303;32;352;;;;; +303;144;352;;;;; +308;736;288;;;;; +309;800;352;;;;; +310;736;400;;;;; +311;656;352;;;;; +170;160;88;d5_enter_d16;;;; +170;176;376;d5_enter_5;2;;; +170;320;376;d5_enter_5;;;; +170;408;144;d5_enter_I;1;;; +170;408;272;d5_enter_ndoor;1;;; +170;496;736;d5_enter_6;2;;; +170;528;960;d5_enter_d2;2;;; +170;536;672;d5_enter_6;3;32;; +170;568;784;d5_enter_6;1;;; +170;608;672;d5_enter_6;1;32;;True +170;640;120;d5_enter_d12;;;; +170;640;984;d5_enter_d2;;;; +170;656;832;d5_enter_2;;;64; +170;656;984;d5_enter_1;2;;; +170;704;800;d5_enter_3;1;64;; +170;728;144;d5_enter_d11;1;;; +170;728;160;d5_enter_d11;3;;;True +170;728;656;d5_enter_4;1;;; +170;728;672;d5_enter_3;3;64;; +170;728;928;d5_enter_1;3;;; +170;808;992;d5_enter_1;;;; +170;848;464;movestone_reset;;;32; +170;864;512;movestone_reset;3;32;; +170;880;448;movestone_reset;1;32;; +170;912;480;movestone_reset;2;;32; +170;960;488;d5_enter_d13;;;;True +170;976;488;d5_enter_d13;2;;; +25;368;64;;;; +25;368;80;;;; +25;368;96;;;; +25;384;96;;;; +25;432;96;;;; +25;448;64;;;; +25;448;80;;;; +25;448;96;;;; +504;368;560;d5_gohma;True +504;416;608;d5_gohma; +503;80;64;d5_ms;3 +503;720;64;d5_ms;2 +503;720;576;d5_ms; +503;1040;448;d5_ms;1 +223;32;48;0;;;;;;; +223;32;128;0;;;;;;; +223;144;48;0;;;;;;; +223;144;128;0;;;;;;; +223;224;80;4;d5_block_1;;;;;; +223;240;96;0;;;;;;; +223;256;96;0;;;;;;; +223;272;80;1;d5_block_2;;;;;; +223;352;736;;;;;;;; +223;368;832;0;;;;;;; +223;368;880;0;;;;;;; +223;384;688;;;;;;;; +223;384;704;;;;;;;; +223;384;752;;;;;;;; +223;384;768;;;;;;;; +223;400;848;0;;;;;;; +223;416;688;;;;;;;; +223;416;704;;;;;;;; +223;416;752;;;;;;;; +223;416;768;;;;;;;; +223;416;864;0;;;;;;; +223;448;832;0;;;;;;; +223;448;880;0;;;;;;; +223;480;320;0;;;;;;; +223;480;720;0;;;;;;; +223;496;320;0;;;;;;; +223;496;720;0;;;;;;; +223;528;592;0;;;;;;; +223;528;832;0;;;;;;; +223;544;592;0;;;;;;; +223;544;880;0;;;;;;; +223;560;608;8;;;;;;; +223;576;608;8;;;;;;; +223;576;848;0;;;;;;; +223;592;352;0;;;;;;; +223;592;368;0;;;;;;; +223;592;592;0;;;;;;; +223;592;688;0;;;;;;; +223;592;704;0;;;;;;; +223;592;720;0;;;;;;; +223;592;736;0;;;;;;; +223;592;752;0;;;;;;; +223;592;864;0;;;;;;; +223;608;320;0;;;;;;; +223;608;336;0;;;;;;; +223;608;352;0;;;;;;; +223;608;384;;;;;;;; +223;608;592;0;;;;;;; +223;624;592;0;;;;;;; +223;640;816;0;;;;;;; +223;640;896;0;;;;;;; +223;656;816;0;;;;;;; +223;656;896;0;;;;;;; +223;672;48;0;;;;;;; +223;672;176;;;;;;;; +223;672;560;0;;;;;;; +223;672;784;0;;;;;;; +223;672;800;0;;;;;;; +223;688;176;;;;;;;; +223;688;192;;;;;;;; +223;688;720;0;;;;;;; +223;688;784;0;;;;;;; +223;688;800;0;;;;;;; +223;704;192;;;;;;;; +223;704;208;;;;;;;; +223;720;224;;;;;;;; +223;736;224;;;;;;;; +223;736;240;;;;;;;; +223;752;256;;;;;;;; +223;768;256;;;;;;;; +223;768;720;0;;;;;;; +223;768;784;0;;;;;;; +223;768;800;0;;;;;;; +223;784;48;0;;;;;;; +223;784;128;0;;;;;;; +223;784;784;0;;;;;;; +223;784;800;0;;;;;;; +223;784;960;0;;;;;;; +223;800;960;0;;;;;;; +223;800;976;0;;;;;;; +223;816;960;0;;;;;;; +223;816;976;0;;;;;;; +223;832;176;0;;;;;;; +223;832;976;0;;;;;;; +223;848;368;0;;;;;;; +223;848;976;0;;;;;;; +223;864;192;0;;;;;;; +223;864;368;0;;;;;;; +223;864;464;0;;;;;;; +223;864;496;0;;;;;;; +223;864;976;0;;;;;;; +223;880;192;0;;;;;;; +223;880;480;;;;;;;;movestone_reset +223;880;976;0;;;;;;; +223;896;192;0;;;;;;; +223;896;464;0;;;;;;; +223;896;496;0;;;;;;; +223;896;976;0;;;;;;; +223;912;192;0;;;;;;; +223;912;208;0;;;;;;; +223;912;224;0;;;;;;; +223;912;240;0;;;;;;; +223;912;256;0;;;;;;; +223;912;272;0;;;;;;; +223;912;288;0;;;;;;; +223;912;304;0;;;;;;; +223;912;320;0;;;;;;; +223;912;336;0;;;;;;; +223;912;352;0;;;;;;; +223;912;976;0;;;;;;; +223;928;976;0;;;;;;; +223;944;384;0;;;;;;; +223;944;976;0;;;;;;; +223;960;320;0;;;;;;; +223;976;320;0;;;;;;; +223;992;336;0;;;;;;; +223;992;432;0;;;;;;; +223;1008;336;0;;;;;;; +223;1024;336;0;;;;;;; +223;1040;336;0;;;;;;; +223;1056;336;0;;;;;;; +223;1072;336;0;;;;;;; +223;1072;352;0;;;;;;; +223;1072;368;0;;;;;;; +223;1088;304;0;;;;;;; +223;1088;368;0;;;;;;; +223;1104;304;0;;;;;;; +223;1104;368;0;;;;;;; +223;1104;432;0;;;;;;; +287;992;1088;74 +518;408;216;d5_nightmare +164;256;336;d5_et_7;1;dialogBox;sound_secrete; +164;408;600;d5_gohma;1;dungeonTeleporter;.d5teleport; +164;504;136;d5_enter_I;1;dialogBox;d5_instrument_music; +164;568;952;d5_et_d2;1;dialogBox;sound_secrete; +164;576;824;d5_et_2;1;dialogBox;sound_secrete; +164;616;48;d5_et_12;1;dialogBox;sound_secrete; +164;680;976;d5_et_1;1;dialogBox;sound_secrete; +164;728;224;d5_et_9;1;dialogBox;sound_secrete; +164;736;696;d5_et_5;1;dialogBox;sound_secrete; +164;928;432;d5_button_d13;1;dialogBox;sound_secrete; +164;1048;984;d5_gohma;1;dungeonTeleporter;.d5teleport; +166;208;64;d5_key1_spawn;1;d5_spawn_key_1 +166;464;832;d5_et_3;1;d5_chest_0 +231;32;384;;ruby;;;; +231;48;384;;ruby;;;; +231;128;304;;;;;; +231;144;304;;heart;;;; +231;144;320;;;;;; +231;192;688;;;;;; +231;192;704;;heart;;;; +231;192;720;;;;;; +231;192;736;;;;;; +231;192;752;;;;;; +231;192;768;;;;;; +231;384;832;;;;;; +231;384;864;;;;;; +231;432;848;;;;;; +231;432;880;;;;;; +231;512;752;;;;;; +231;512;768;;;;;; +231;528;768;;;;;; +231;560;592;;heart;;;; +231;576;592;;arrow_1;;;; +231;592;112;;;;;; +231;592;128;;;;;; +231;608;720;;fairy;;;; +231;672;192;;;;;; +231;672;256;;heart;;;; +231;720;208;;;;;; +231;752;240;;;;;; +231;784;176;;heart;;;; +231;784;256;;;;;; +231;848;256;;ruby;;;; +231;864;256;;;;;; +231;864;304;;ruby;;;; +231;864;320;;;;;; +231;880;256;;ruby;;;; +231;896;576;;bomb_1;;;; +231;896;592;;;;;; +231;912;576;;bomb_1;;;; +231;912;592;;heart;;;; +239;608;256;d5_pullBridge_1; +239;624;688;d5_pullBridge_0;True +239;944;192;d5_pullBridge_2;True +414;112;320 +414;848;320 +414;896;336 +160;400;96; +160;416;96; +438;256;128 +438;304;48 +438;560;80 +438;688;688 +438;752;832 +438;768;688 +415;112;368 +415;688;480 +415;848;208 +415;1072;384 +461;32;352;d5_et_6 +461;144;352;d5_et_6 +461;576;688;d5_et_8 +246;384;64; +246;384;80; +246;400;48; +246;400;64; +246;400;80; +246;400;96; +246;416;48; +246;416;64; +246;416;80; +246;416;96; +246;432;64; +246;432;80; +157;672;304; +157;672;320; +157;672;336; +157;672;352; +157;672;368; +157;672;384; +157;688;304; +157;688;320; +157;688;336; +157;688;352; +157;688;368; +157;688;384; +157;688;400; +157;688;416; +157;688;432; +157;704;304; +157;704;320; +157;704;336; +157;704;352; +157;704;368; +157;704;384; +157;704;432; +157;704;448; +157;704;464; +157;704;480; +157;704;496; +157;704;880; +157;704;896; +157;704;944; +157;720;304; +157;720;320; +157;720;384; +157;720;880; +157;720;960; +157;720;976; +157;720;992; +157;736;304; +157;736;320; +157;736;384; +157;736;752; +157;736;768; +157;736;784; +157;736;800; +157;736;816; +157;736;832; +157;736;848; +157;736;864; +157;736;880; +157;736;992; +157;736;1008; +157;736;1024; +157;752;304; +157;752;320; +157;752;384; +157;752;720; +157;752;736; +157;752;752; +157;752;768; +157;752;784; +157;752;800; +157;768;304; +157;768;320; +157;768;336; +157;768;352; +157;768;368; +157;768;384; +157;784;304; +157;784;320; +157;784;336; +157;784;352; +157;784;368; +157;784;384; +108;672;304;;;;;; +108;672;320;;;;;; +108;672;336;;;;;; +108;672;352;;;;;; +108;672;368;;;;;; +108;672;384;;;;;; +108;688;304;;;;;; +108;688;320;;;;;; +108;688;336;;;;;; +108;688;352;;;;;; +108;688;368;;;;;; +108;688;384;;;;;; +108;688;400;;;;;; +108;688;416;;;;;; +108;688;432;;;;;; +108;704;304;;;;;; +108;704;320;;;;;; +108;704;336;;;;;; +108;704;352;;;;;; +108;704;368;;;;;; +108;704;384;;;;;; +108;704;432;;;;;; +108;704;448;;;;;; +108;704;464;;;;;; +108;704;480;;;;;; +108;704;496;;;;;; +108;704;880;;;;;; +108;704;896;;;;;; +108;704;944;;;;;; +108;720;304;;;;;; +108;720;320;;;;;; +108;720;384;;;;;; +108;720;880;;;;;; +108;720;960;;;;;; +108;720;976;;;;;; +108;720;992;;;;;; +108;736;304;;;;;; +108;736;320;;;;;; +108;736;384;;;;;; +108;736;752;;;;;; +108;736;768;;;;;; +108;736;784;;;;;; +108;736;800;;;;;; +108;736;816;;;;;; +108;736;832;;;;;; +108;736;848;;;;;; +108;736;864;;;;;; +108;736;880;;;;;; +108;736;992;;;;;; +108;736;1008;;;;;; +108;736;1024;;;;;; +108;752;304;;;;;; +108;752;320;;;;;; +108;752;384;;;;;; +108;752;720;;;;;; +108;752;736;;;;;; +108;752;752;;;;;; +108;752;768;;;;;; +108;752;784;;;;;; +108;752;800;;;;;; +108;768;304;;;;;; +108;768;320;;;;;; +108;768;336;;;;;; +108;768;352;;;;;; +108;768;368;;;;;; +108;768;384;;;;;; +108;784;304;;;;;; +108;784;320;;;;;; +108;784;336;;;;;; +108;784;352;;;;;; +108;784;368;;;;;; +108;784;384;;;;;; +109;720;336;;;;;; +109;720;352;;;;;; +109;720;368;;;;;; +109;736;336;;;;;; +109;736;352;;;;;; +109;736;368;;;;;; +109;752;336;;;;;; +109;752;352;;;;;; +109;752;368;;;;;; +158;720;336 +158;720;352 +158;720;368 +158;736;336 +158;736;352 +158;736;368 +158;752;336 +158;752;352 +158;752;368 diff --git a/bin/Data/Maps/dungeon5.map.data b/bin/Data/Maps/dungeon5.map.data new file mode 100644 index 0000000..95091d7 --- /dev/null +++ b/bin/Data/Maps/dungeon5.map.data @@ -0,0 +1,69 @@ +72 +67 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon5_2d_1.map b/bin/Data/Maps/dungeon5_2d_1.map new file mode 100644 index 0000000..235cbde --- /dev/null +++ b/bin/Data/Maps/dungeon5_2d_1.map @@ -0,0 +1,650 @@ +3 +1 +1 +tileset 2d.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,69,104,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,104,69,, +,63,104,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,104,63,, +,63,104,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,104,63,, +,69,69,113,113,113,113,113,113,113,69,69,104,69,113,113,113,113,69,104,69,, +,63,113,113,113,113,113,113,113,113,63,63,104,63,113,113,113,113,113,104,63,, +,63,113,113,113,113,113,113,113,113,69,69,104,63,113,113,113,113,113,104,63,, +,63,113,113,113,113,113,113,113,113,113,113,104,63,113,113,113,113,113,113,63,, +,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,0,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +88 +171;176;112;;;chainPlatform2reset;true;False; +171;176;112;;;chainPlatform1reset;true;False; +0;16;16;;; +0;16;32;;; +0;16;48;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;32;64;;; +0;32;128;;; +0;48;16;;; +0;48;128;;; +0;64;16;;; +0;64;128;;; +0;80;16;;; +0;80;128;;; +0;96;16;;; +0;96;128;;; +0;112;16;;; +0;112;128;;; +0;128;16;;; +0;128;128;;; +0;144;16;;; +0;144;128;;; +0;160;16;;; +0;160;64;;; +0;160;80;;; +0;160;96;;; +0;160;128;;; +0;176;16;;; +0;176;64;;; +0;176;80;;; +0;176;96;;; +0;176;128;;; +0;192;16;;; +0;192;128;;; +0;208;16;;; +0;208;64;;; +0;208;80;;; +0;208;96;;; +0;208;112;;; +0;224;16;;; +0;224;128;;; +0;240;16;;; +0;240;128;;; +0;256;16;;; +0;256;128;;; +0;272;16;;; +0;272;128;;; +0;288;16;;; +0;288;64;;; +0;288;128;;; +0;304;128;;; +0;320;16;;; +0;320;32;;; +0;320;48;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +0;320;112;;; +286;-8;40;;;; +347;48;96;chainPlatform1;16;-64 +347;80;96;chainPlatform2;16;-64 +347;112;64;chainPlatform1;48;-32 +347;144;64;chainPlatform2;48;-32 +347;240;96;chainPlatform3;16;-64 +347;272;64;chainPlatform3;48;-32 +153;32;8;;;d5_2d_1L;dungeon5.map;d5_2d_1L;3;;False +153;304;8;;;d5_2d_1R;dungeon5.map;d5_2d_1R;3;;False +300;32;16;128;;;;; +300;304;16;;;;;; +258;32;16; +258;32;32; +258;32;48; +258;192;64; +258;192;80; +258;192;96; +258;192;112; +258;304;16; +258;304;32; +258;304;48; +258;304;64; +258;304;80; +258;304;96; +259;192;64; +259;304;64; +257;-8;16 +287;-8;64;32 diff --git a/bin/Data/Maps/dungeon5_2d_1.map.data b/bin/Data/Maps/dungeon5_2d_1.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/dungeon5_2d_1.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon5_2d_2.map b/bin/Data/Maps/dungeon5_2d_2.map new file mode 100644 index 0000000..ace16e1 --- /dev/null +++ b/bin/Data/Maps/dungeon5_2d_2.map @@ -0,0 +1,692 @@ +3 +1 +1 +tileset 2d.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,61,104,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,104,61,, +,63,104,113,68,110,108,68,113,113,113,113,68,113,110,108,110,68,113,104,63,, +,63,104,113,68,108,113,68,113,113,113,113,68,113,108,113,108,68,113,104,63,, +,63,88,88,88,113,88,88,113,113,88,88,88,88,113,113,88,88,88,88,63,, +,31,113,113,113,113,113,113,113,104,113,113,113,113,113,113,113,113,113,113,32,, +,31,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,32,, +,29,24,17,17,17,17,17,17,17,17,17,17,17,25,25,17,17,17,24,29,, +,29,29,25,25,25,25,25,25,25,25,25,25,25,29,29,25,25,25,29,29,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,0,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,1,,,,,,,,,,,,,,,,,,,2,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +130 +127;32;96;;;;; +127;48;96;;;;; +127;64;96;;;;; +127;80;96;;;;; +127;96;96;;;;; +127;112;96;;;;; +127;128;96;;;;; +127;144;96;;;;; +127;160;96;;;;; +127;176;96;;;;; +127;192;96;;;;; +127;208;96;;;;; +127;224;96;;;;; +127;240;96;;;;; +127;256;96;;;;; +127;272;96;;;;; +127;288;96;;;;; +127;304;96;;;;; +0;16;16;;; +0;16;32;;; +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;32;112;;; +0;48;16;;; +0;48;128;;; +0;64;16;;; +0;64;128;;; +0;80;16;;; +0;80;128;;; +0;96;16;;; +0;96;128;;; +0;112;16;;; +0;112;128;;; +0;128;16;;; +0;128;128;;; +0;144;16;;; +0;144;128;;; +0;160;16;;; +0;160;128;;; +0;176;16;;; +0;176;128;;; +0;192;16;;; +0;192;128;;; +0;208;16;;; +0;208;128;;; +0;224;16;;; +0;224;112;;; +0;240;16;;; +0;240;112;;; +0;256;16;;; +0;256;128;;; +0;272;16;;; +0;272;128;;; +0;288;16;;; +0;288;128;;; +0;304;112;;; +0;320;16;;; +0;320;32;;; +0;320;48;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +2;32;64;;; +2;48;64;;; +2;64;64;;; +2;96;64;;; +2;112;64;;; +2;160;64;;; +2;176;64;;; +2;192;64;;; +2;208;64;;; +2;256;64;;; +2;272;64;;; +2;288;64;;; +2;304;64;;; +153;32;8;;;d5_2d_2L;dungeon5.map;d5_2d_2L;3;;False +153;304;8;;;d5_2d_2R;dungeon5.map;d5_2d_2R;3;;False +300;32;16;;;;;; +300;304;16;;;;;; +284;-8;40;;200;200;150 +258;32;16; +258;32;32; +258;32;48; +258;144;80; +258;304;16; +258;304;32; +258;304;48; +259;144;80; +485;64;96;;True +485;112;96;;True +485;208;96;;True +485;272;96;;True +303;96;48;;;;; +303;240;48;;;;; +257;-8;16 +287;-8;64;32 +158;32;96 +158;48;96 +158;48;112 +158;64;96 +158;64;112 +158;80;96 +158;80;112 +158;96;96 +158;96;112 +158;112;96 +158;112;112 +158;128;96 +158;128;112 +158;144;96 +158;144;112 +158;160;96 +158;160;112 +158;176;96 +158;176;112 +158;192;96 +158;192;112 +158;208;96 +158;208;112 +158;224;96 +158;240;96 +158;256;96 +158;256;112 +158;272;96 +158;272;112 +158;288;96 +158;288;112 +158;304;96 diff --git a/bin/Data/Maps/dungeon5_2d_2.map.data b/bin/Data/Maps/dungeon5_2d_2.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/dungeon5_2d_2.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon5_2d_3.map b/bin/Data/Maps/dungeon5_2d_3.map new file mode 100644 index 0000000..b62f347 --- /dev/null +++ b/bin/Data/Maps/dungeon5_2d_3.map @@ -0,0 +1,659 @@ +3 +1 +1 +tileset 2d.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,69,104,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,66,69,, +,63,104,113,113,113,113,57,63,113,113,113,113,110,108,110,113,57,63,66,63,, +,63,104,113,113,113,113,113,63,113,69,69,113,108,113,108,113,113,63,66,63,, +,69,69,69,69,69,104,104,63,113,63,63,69,113,113,113,69,104,69,66,69,, +,63,113,113,110,108,110,113,69,113,69,69,69,69,69,69,69,113,113,66,63,, +,63,89,113,108,113,108,113,113,113,113,113,113,113,113,113,113,113,113,66,63,, +,69,69,113,113,113,113,113,113,113,69,69,113,113,113,113,113,113,113,113,69,, +,29,29,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +97 +0;16;16;;; +0;16;32;;; +0;16;48;;; +0;16;80;;; +0;16;96;;; +0;32;64;;; +0;32;112;;; +0;48;16;;; +0;48;64;;; +0;48;128;;; +0;64;16;;; +0;64;64;;; +0;64;128;;; +0;80;16;;; +0;80;64;;; +0;80;128;;; +0;96;16;;; +0;96;128;;; +0;112;16;;; +0;112;128;;; +0;128;32;;; +0;128;48;;; +0;128;64;;; +0;128;80;;; +0;128;128;;; +0;144;16;;; +0;144;128;;; +0;160;16;;; +0;160;48;;; +0;160;64;;; +0;160;80;;; +0;160;112;;; +0;176;16;;; +0;176;48;;; +0;176;80;;; +0;176;112;;; +0;192;16;;; +0;192;64;;; +0;192;80;;; +0;192;128;;; +0;208;16;;; +0;208;80;;; +0;208;128;;; +0;224;16;;; +0;224;80;;; +0;224;128;;; +0;240;16;;; +0;240;80;;; +0;240;128;;; +0;256;16;;; +0;256;64;;; +0;256;80;;; +0;256;128;;; +0;272;16;;; +0;272;128;;; +0;288;16;;; +0;288;32;;; +0;288;48;;; +0;288;64;;; +0;288;128;;; +0;304;128;;; +0;320;16;;; +0;320;32;;; +0;320;48;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +0;320;112;;; +153;32;8;;;d5_2d_3L;dungeon5.map;d5_2d_3L;3;;False +153;304;8;;;d5_2d_3R;dungeon5.map;d5_2d_3R;3;;False +300;32;16;;;;;; +300;304;16;;;;;; +284;-8;40;;200;200;150 +258;32;16; +258;32;32; +258;32;48; +258;96;64; +258;112;64; +258;272;64; +258;304;16; +258;304;32; +258;304;48; +258;304;64; +258;304;80; +258;304;96; +259;96;64; +259;112;64; +259;272;64; +484;32;96 +484;208;64 +484;240;64 +24;112;32;;;; +24;272;32;;;; +303;80;96;;;;; +303;224;48;;;;; +257;-8;16 +287;-8;64;32 diff --git a/bin/Data/Maps/dungeon5_2d_3.map.data b/bin/Data/Maps/dungeon5_2d_3.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/dungeon5_2d_3.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon5_2d_4.map b/bin/Data/Maps/dungeon5_2d_4.map new file mode 100644 index 0000000..00d20c9 --- /dev/null +++ b/bin/Data/Maps/dungeon5_2d_4.map @@ -0,0 +1,715 @@ +3 +1 +1 +tileset 2d.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,69,104,69,69,69,69,69,69,69,69,69,69,,,,,,,69,69,, +,63,113,63,39,39,39,39,39,39,63,29,63,17,17,17,17,17,17,63,29,, +,63,113,63,113,113,113,113,113,113,63,29,63,17,17,63,17,17,17,63,29,, +,63,113,63,113,113,113,69,113,113,63,29,63,17,17,63,17,17,17,63,29,, +,69,113,69,113,113,113,69,69,69,69,69,69,17,17,69,69,17,17,63,29,, +,63,113,113,113,113,113,113,113,113,91,91,91,17,17,17,17,17,17,63,29,, +,63,52,52,94,113,113,113,113,113,91,91,91,17,17,17,17,17,17,63,29,, +,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,29,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,,0,0,0,0,0,0,0,0,0,0,,,,,,,0,0,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +153 +127;208;17;;;;; +127;224;17;;;;; +127;240;17;;;;; +127;256;17;;;;; +127;272;17;;;;; +127;288;17;;;;; +125;32;32;;;;; +125;64;64;;;;; +125;80;64;;;;; +125;96;64;;;;; +0;16;16;;; +0;16;32;;; +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;32;128;;; +0;48;16;;; +0;48;32;;; +0;48;48;;; +0;48;64;;; +0;48;80;;; +0;48;128;;; +0;64;16;;; +0;64;128;;; +0;80;16;;; +0;80;128;;; +0;96;16;;; +0;96;128;;; +0;112;16;;; +0;112;64;;; +0;112;80;;; +0;112;128;;; +0;128;16;;; +0;128;80;;; +0;128;128;;; +0;144;16;;; +0;144;80;;; +0;144;128;;; +0;160;32;;; +0;160;48;;; +0;160;64;;; +0;160;80;;; +0;160;128;;; +0;176;80;;; +0;176;128;;; +0;192;16;;; +0;192;32;;; +0;192;48;;; +0;192;64;;; +0;192;80;;; +0;192;128;;; +0;208;128;;; +0;224;128;;; +0;240;48;;; +0;240;64;;; +0;240;80;;; +0;240;128;;; +0;256;80;;; +0;256;128;;; +0;272;128;;; +0;288;128;;; +0;304;16;;; +0;304;32;;; +0;304;48;;; +0;304;64;;; +0;304;80;;; +0;304;96;;; +0;304;112;;; +153;32;8;;;d5_2d_4L;dungeon5.map;d5_2d_4L;3;;False +153;208;8;96;;d5_2d_4R;dungeon5.map;d5_2d_4R;3;3;False +300;32;16;;;;;; +300;248;16;128;;;;; +284;-8;40;;200;200;150 +258;32;16; +486;64;64 +486;80;64 +486;208;80 +486;208;96 +484;128;64 +257;-8;16 +287;-8;64;32 +158;32;32 +158;32;48 +158;32;64 +158;32;80 +158;32;96 +158;32;112 +158;48;96 +158;48;112 +158;64;64 +158;64;80 +158;64;96 +158;64;112 +158;80;64 +158;80;80 +158;80;96 +158;80;112 +158;96;64 +158;96;80 +158;96;96 +158;96;112 +158;112;96 +158;112;112 +158;128;96 +158;128;112 +158;144;96 +158;144;112 +158;160;96 +158;160;112 +158;176;96 +158;176;112 +158;192;96 +158;192;112 +158;208;16 +158;208;32 +158;208;48 +158;208;64 +158;208;80 +158;208;96 +158;208;112 +158;224;16 +158;224;32 +158;224;48 +158;224;64 +158;224;80 +158;224;96 +158;224;112 +158;240;16 +158;240;32 +158;240;96 +158;240;112 +158;256;16 +158;256;32 +158;256;48 +158;256;64 +158;256;96 +158;256;112 +158;272;16 +158;272;32 +158;272;48 +158;272;64 +158;272;80 +158;272;96 +158;272;112 +158;288;16 +158;288;32 +158;288;48 +158;288;64 +158;288;80 +158;288;96 +158;288;112 diff --git a/bin/Data/Maps/dungeon5_2d_4.map.data b/bin/Data/Maps/dungeon5_2d_4.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/dungeon5_2d_4.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon5_entry.map b/bin/Data/Maps/dungeon5_entry.map new file mode 100644 index 0000000..4aa5bce --- /dev/null +++ b/bin/Data/Maps/dungeon5_entry.map @@ -0,0 +1,706 @@ +3 +1 +1 +tileset 2d.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,0,0,0,0,0,0,9,7,7,7,7,7,13,0,0,0,0,0,0,9,, +,0,0,0,0,0,0,9,7,7,7,7,7,13,0,0,0,0,0,0,9,, +,0,0,0,0,0,4,9,7,7,7,7,7,13,4,0,0,0,0,0,9,, +,0,0,0,0,0,14,7,7,7,7,7,7,7,12,0,0,0,0,4,9,, +,0,0,0,0,0,8,20,20,20,20,20,20,20,11,0,0,0,0,14,7,, +,4,0,0,0,0,0,50,87,87,87,87,87,51,0,4,0,0,4,9,7,, +,10,12,0,4,14,10,16,16,16,16,16,16,16,10,12,0,4,14,7,7,, +,7,7,10,10,7,7,7,7,7,7,7,7,7,7,7,10,10,7,7,7,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,0,0,0,0,0,0,0,,,,,,,0,0, +,,,,,,,,,,,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,0, +,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +144 +126;16;16;;;;; +126;32;16;;;;; +126;48;16;;;;; +126;64;16;;;;; +126;80;16;;;;; +126;96;16;;;;; +126;224;16;;;;; +126;240;16;;;;; +126;256;16;;;;; +126;272;16;;;;; +126;288;16;;;;; +126;304;16;;;;; +0;0;0;;; +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;0;64;;; +0;0;80;;; +0;0;96;;; +0;16;112;;; +0;32;112;;; +0;48;128;;; +0;64;128;;; +0;80;112;;; +0;96;64;;; +0;96;80;;; +0;96;112;;; +0;112;0;;; +0;112;16;;; +0;112;32;;; +0;112;48;;; +0;112;80;;; +0;112;112;;; +0;128;80;;; +0;128;112;;; +0;144;80;;; +0;144;112;;; +0;160;80;;; +0;160;112;;; +0;176;80;;; +0;176;112;;; +0;192;80;;; +0;192;112;;; +0;208;0;;; +0;208;16;;; +0;208;32;;; +0;208;48;;; +0;208;80;;; +0;208;112;;; +0;224;64;;; +0;224;80;;; +0;224;112;;; +0;240;112;;; +0;256;128;;; +0;272;128;;; +0;288;112;;; +0;304;80;;; +0;304;96;;; +0;320;0;;; +0;320;16;;; +0;320;32;;; +0;320;48;;; +0;320;64;;; +153;16;8;96;;left;overworld.map;d5_entry_left;3;3;False +153;224;8;96;;right;overworld.map;d5_entry_right;3;3;False +257;-24;16 +287;-24;40;37 +158;16;16 +158;16;32 +158;16;48 +158;16;64 +158;16;80 +158;16;96 +158;32;16 +158;32;32 +158;32;48 +158;32;64 +158;32;80 +158;32;96 +158;48;16 +158;48;32 +158;48;48 +158;48;64 +158;48;80 +158;48;96 +158;48;112 +158;64;16 +158;64;32 +158;64;48 +158;64;64 +158;64;80 +158;64;96 +158;64;112 +158;80;16 +158;80;32 +158;80;48 +158;80;64 +158;80;80 +158;80;96 +158;96;16 +158;96;32 +158;96;48 +158;96;96 +158;112;96 +158;128;96 +158;144;96 +158;160;96 +158;176;96 +158;192;96 +158;208;96 +158;224;16 +158;224;32 +158;224;48 +158;224;96 +158;240;16 +158;240;32 +158;240;48 +158;240;64 +158;240;80 +158;240;96 +158;256;16 +158;256;32 +158;256;48 +158;256;64 +158;256;80 +158;256;96 +158;256;112 +158;272;16 +158;272;32 +158;272;48 +158;272;64 +158;272;80 +158;272;96 +158;272;112 +158;288;16 +158;288;32 +158;288;48 +158;288;64 +158;288;80 +158;288;96 +158;304;16 +158;304;32 +158;304;48 +158;304;64 diff --git a/bin/Data/Maps/dungeon5_entry.map.data b/bin/Data/Maps/dungeon5_entry.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/dungeon5_entry.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon6.map b/bin/Data/Maps/dungeon6.map new file mode 100644 index 0000000..9d7c875 --- /dev/null +++ b/bin/Data/Maps/dungeon6.map @@ -0,0 +1,3247 @@ +3 +1 +2 +dungeon 6.png +83 +59 +3 +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,15,,,,,,,,, +,9,14,14,14,14,10,22,12,14,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,14,14,23,9,14,14,14,14,10,,, +,15,11,11,11,52,17,11,11,11,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,15,11,11,11,15,52,11,11,11,17,,, +,15,11,11,11,52,17,11,11,11,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,15,11,11,11,15,52,11,11,11,17,,, +,15,11,11,11,52,17,11,52,11,22,14,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,14,23,11,52,11,15,52,11,11,11,17,,, +,15,52,52,52,52,22,14,43,14,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,14,43,14,23,52,52,52,52,17,,, +,15,36,36,36,36,36,36,36,36,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,15,36,36,36,36,36,36,36,36,17,,, +,15,36,36,36,36,36,36,36,36,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,15,36,36,36,36,36,36,36,36,17,,, +,8,16,16,29,28,16,16,16,16,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,2,2,15,,,,,,,,,,,,,,,,,,,,,,,,8,16,16,16,16,29,28,16,16,7,,, +,9,14,14,27,26,14,14,14,14,10,36,44,44,44,44,44,44,44,44,48,,,,,,,,,,,19,19,19,19,19,19,19,19,19,19,9,14,10,22,14,14,23,9,14,10,9,14,14,14,14,14,14,14,14,10,9,14,14,14,14,14,14,14,14,10,,,,9,14,27,26,14,10,,,, +,15,36,36,36,36,36,52,36,36,17,51,47,47,36,47,47,47,41,36,45,,,,,,,,,,,19,52,52,52,36,36,52,52,52,19,15,36,17,11,11,11,11,15,36,17,15,36,36,36,36,36,36,36,36,17,15,36,36,36,36,36,36,36,36,17,9,14,14,23,36,36,36,36,22,10,,, +,15,36,36,52,52,52,52,52,52,17,9,14,14,43,14,14,10,46,36,45,,,,,,,,,,,19,52,52,52,52,52,52,52,52,19,15,36,17,11,11,11,11,15,36,17,15,36,36,36,36,36,36,36,36,17,15,36,11,11,11,11,11,11,36,17,15,36,36,36,36,36,36,36,36,17,,, +,15,36,36,52,36,36,52,36,36,17,15,36,11,11,11,36,17,46,36,45,,,,,,,,,,,19,52,52,36,52,52,36,52,52,19,15,36,17,11,11,11,11,15,36,17,15,36,36,36,36,36,36,36,36,17,15,36,11,11,11,11,11,11,36,17,15,36,19,19,19,19,19,19,19,17,,, +,15,36,36,52,36,36,52,36,36,22,23,36,11,11,11,36,17,46,36,45,,,,,,,,,,,19,52,52,52,52,52,52,52,52,19,15,36,22,14,43,43,14,23,36,17,15,36,36,36,36,36,36,36,36,17,15,36,36,36,36,36,36,36,36,17,15,36,36,36,36,36,36,36,36,17,,, +,8,43,16,20,36,36,52,36,36,36,36,36,11,11,11,36,17,46,36,45,,,,,,,,,,,19,52,52,52,52,52,52,52,52,19,15,36,36,36,11,11,36,36,36,17,15,36,36,36,36,36,36,36,36,17,15,36,42,47,47,47,47,47,47,17,15,19,19,19,19,19,19,19,36,17,,, +,2,2,2,15,36,36,21,16,16,16,20,36,36,36,36,36,17,46,36,45,,,,,,,,,,,19,52,52,52,52,52,52,52,52,19,15,36,36,36,11,11,36,36,36,17,15,36,36,36,36,36,36,36,36,17,15,36,45,9,14,14,14,14,10,17,15,36,36,36,36,36,36,36,36,17,,, +,2,2,2,8,29,28,7,,,,15,36,36,36,36,36,17,46,36,45,,,,,,,,,,,46,36,45,19,19,19,19,19,19,19,8,16,16,16,29,28,16,16,16,7,8,16,16,16,29,28,16,16,16,7,15,36,45,15,,,,,17,17,8,16,29,28,16,16,16,16,16,7,,, +,9,14,14,14,27,26,10,,,,15,36,11,11,11,36,17,46,36,39,44,44,44,44,44,44,44,44,44,44,40,36,45,9,14,14,14,14,14,10,9,14,14,14,27,26,14,14,14,10,9,14,14,14,27,26,14,14,14,10,15,36,45,15,,,,,17,17,9,14,27,26,14,10,22,14,14,10,,, +,15,36,36,52,36,36,22,14,14,14,23,36,11,11,11,36,17,36,47,47,47,47,47,47,47,47,47,47,47,47,47,47,50,15,36,36,36,36,36,17,15,36,36,36,36,36,36,36,36,17,15,36,36,36,36,36,36,36,36,17,15,36,45,15,,,,,17,17,15,36,36,36,36,17,46,36,13,17,,, +,15,36,36,52,36,36,36,36,36,36,36,36,11,11,11,36,22,14,14,10,9,14,14,14,14,14,14,14,14,10,9,14,14,23,36,36,36,36,36,17,15,36,36,36,36,36,36,36,36,17,15,11,11,11,36,36,11,11,11,17,15,36,45,15,,,,,17,17,15,36,36,36,36,17,36,36,36,17,,, +,15,36,36,52,36,36,52,52,52,21,20,36,11,11,11,36,36,36,36,25,24,36,36,36,36,36,36,36,36,25,24,36,36,36,36,36,36,36,36,17,15,36,36,36,36,36,36,36,36,17,15,11,13,11,36,36,11,11,11,17,15,36,45,15,,,,,17,17,15,36,36,36,36,17,51,36,47,22,14,, +,15,36,36,52,36,36,52,36,36,17,15,36,11,11,11,36,36,36,36,30,31,36,36,36,36,36,36,36,36,30,31,36,36,21,16,16,16,20,36,17,15,36,36,36,36,36,36,36,36,17,15,11,11,11,36,36,11,11,11,17,15,36,45,8,16,20,,21,7,17,15,36,36,36,36,22,14,43,14,10,,, +,15,36,36,36,36,36,52,36,36,17,15,36,11,13,11,36,21,16,16,7,8,16,16,16,16,16,16,16,16,7,8,16,16,7,36,36,36,15,36,17,15,36,36,36,36,36,36,36,36,17,15,36,36,36,36,36,36,36,36,17,15,36,39,44,48,15,,17,21,7,15,36,36,36,36,36,36,36,36,17,,, +,15,36,36,36,36,36,52,36,36,17,15,36,11,11,11,36,17,49,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,40,36,45,15,36,17,15,36,36,36,36,36,36,36,36,17,15,36,36,36,36,36,36,36,36,17,15,36,36,36,45,15,,17,17,,15,36,36,36,36,36,36,21,16,7,,, +,8,16,16,20,36,36,21,16,16,7,8,16,16,16,16,16,7,46,36,42,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,50,15,36,17,8,16,16,16,29,28,16,16,16,7,8,16,16,16,29,28,16,16,16,7,15,36,21,16,20,15,,17,17,,8,16,29,28,16,16,16,7,36,21,16,, +,9,14,14,23,36,36,22,14,14,10,9,14,14,14,14,14,10,46,36,45,9,14,14,14,14,14,14,14,14,10,9,14,14,14,14,14,14,23,36,17,9,14,14,14,27,26,14,14,14,10,9,14,14,14,27,26,14,14,14,10,15,36,22,14,23,15,,17,22,10,9,14,27,26,14,14,14,10,36,22,14,, +,15,36,36,36,36,36,52,36,36,17,15,36,36,36,36,36,17,36,36,50,15,56,56,56,56,56,56,56,56,17,15,13,36,53,36,36,53,36,36,17,15,36,36,36,36,36,36,36,36,17,15,36,36,11,11,11,11,36,36,17,15,36,36,45,9,23,,17,46,17,15,53,36,36,36,36,36,22,43,10,,, +,15,36,36,36,36,36,52,36,36,17,15,36,36,36,36,36,22,14,43,10,15,56,56,56,56,56,56,56,56,17,15,36,53,36,36,36,36,53,36,17,15,36,36,36,36,36,36,36,36,17,15,36,11,36,36,36,36,11,36,17,15,36,36,36,15,,,17,36,17,15,36,36,36,36,36,36,54,36,17,,, +,15,36,36,36,36,36,52,36,36,17,15,36,36,36,52,52,36,36,36,17,15,56,19,19,56,19,19,56,56,17,15,53,11,53,36,36,53,36,53,17,15,36,36,36,36,36,36,36,36,17,15,11,36,36,11,11,36,36,11,17,15,47,47,50,15,,,17,46,17,15,36,36,54,36,54,36,55,53,17,,, +,15,52,52,52,52,52,52,36,36,25,24,52,52,52,52,36,11,11,11,38,38,56,56,56,19,56,56,56,56,17,15,36,53,36,53,53,36,53,36,17,15,36,36,36,36,36,36,36,36,17,15,36,11,36,11,11,36,11,36,17,15,9,14,14,23,,,17,46,25,24,36,36,55,36,55,36,36,36,17,,, +,15,36,36,36,36,36,52,52,52,30,31,36,36,36,52,36,11,36,36,17,15,56,56,56,19,19,19,56,56,17,15,36,36,53,36,36,53,36,36,17,15,36,36,36,36,36,36,36,36,17,15,36,36,11,11,11,11,36,36,17,15,15,,,,,,17,46,30,31,36,36,36,36,36,36,36,36,17,,, +,15,36,36,36,36,36,52,36,36,17,15,36,36,36,52,36,11,36,36,17,15,56,19,19,19,56,19,56,56,17,15,36,36,36,53,53,36,36,36,17,15,36,36,36,36,36,36,36,36,17,15,36,36,36,36,36,36,36,36,17,15,15,,21,16,16,16,7,46,17,15,53,36,36,36,36,36,36,53,17,,, +,8,16,16,16,16,16,16,16,16,7,8,20,36,21,16,20,11,21,16,7,8,16,16,16,16,16,16,16,16,7,8,16,16,16,16,16,29,28,16,7,8,16,16,16,29,28,16,16,16,7,8,16,16,16,37,16,16,16,16,7,15,15,,17,21,16,16,16,16,7,8,16,16,16,16,16,16,16,16,7,,, +,,,,,,,,,,,9,23,36,17,2,15,11,22,14,10,9,14,14,14,14,14,14,14,14,10,2,2,2,2,2,9,27,26,10,2,9,14,14,14,27,26,14,14,14,10,9,14,14,14,37,14,14,14,14,10,15,15,,17,22,14,14,14,14,10,,,,,,,,,,,,, +,,,,,,,,,,,15,36,52,22,14,23,52,36,36,25,24,36,36,36,36,36,11,11,11,17,9,14,14,14,14,23,36,36,22,10,15,36,36,36,36,36,36,36,36,17,15,36,36,36,36,36,36,36,36,17,15,15,,17,46,36,36,36,36,17,,,,,,,,,,,,, +,,,,,,,,,,,15,36,36,11,11,11,11,36,36,30,31,36,36,36,36,36,11,11,11,17,15,36,36,36,36,36,36,36,36,17,15,54,36,47,47,47,47,36,54,17,15,36,36,36,36,36,36,36,36,17,15,15,,17,46,36,36,36,36,17,,,,,,,,,,,,, +,,,,,,,,,,,15,36,36,11,11,11,11,36,36,17,8,16,16,16,16,20,11,11,11,17,15,36,36,54,53,54,36,36,36,17,15,55,36,36,36,36,36,36,55,17,15,36,36,36,36,36,36,36,36,17,15,15,,17,51,36,47,41,36,17,,,,,,,,,,,,, +,,,,,,,,,,,15,36,36,11,11,11,11,36,36,17,2,2,2,2,2,8,20,36,36,17,15,36,36,57,36,57,36,36,36,17,15,36,53,53,53,53,53,53,36,17,15,36,36,36,36,36,36,36,36,17,15,15,,22,14,43,10,46,36,17,,,,,,,,,,,,, +,,,,,,,,,,,15,36,52,36,36,36,52,36,36,22,14,14,14,14,10,2,15,36,36,17,15,36,36,55,53,55,36,36,36,25,24,36,36,36,36,36,36,36,36,17,15,36,36,36,36,36,36,36,36,17,15,15,,,,,17,46,36,17,,,,,,,,,,,,, +,,,,,,,,,,,15,36,36,36,36,36,11,11,11,11,11,11,11,36,17,2,15,36,36,17,15,36,36,36,36,36,36,36,36,30,31,36,36,36,36,36,36,36,36,17,15,36,36,36,36,36,36,36,36,17,15,8,16,16,16,16,7,46,36,17,,,,,,,,,,,,, +,,,,,,,,,,,8,16,16,16,29,28,16,16,16,16,20,36,11,36,17,2,8,29,28,7,8,16,16,16,16,16,16,16,16,7,8,16,16,16,16,16,16,16,16,7,8,16,16,16,29,28,16,16,16,7,8,16,16,16,16,16,16,29,28,7,,,,,,,,,,,,, +,,,,,,,,,,,49,44,48,9,27,26,10,49,44,48,15,36,11,36,17,2,9,27,26,10,,,,,,,,,,,,,,,,,,,,,,,9,14,27,26,14,10,,,,,9,14,14,14,14,27,26,10,,,,,,,,,,,,, +,,,,,,,,,,,46,36,45,15,36,36,17,46,36,45,15,36,11,36,17,2,15,36,36,17,,,,,,,,,,,,,,,,,,,,,9,14,23,36,36,36,36,22,14,10,9,14,23,36,36,36,36,11,11,17,,,,,,,,,,,,, +,,,,,,,,,,,46,36,45,15,36,36,17,46,36,45,15,36,11,36,17,2,15,11,11,17,,,,,,,,,,,,,,,,,,,,,15,36,36,36,36,36,36,36,36,17,15,36,36,36,36,36,36,36,36,17,,,,,,,,,,,,, +,,,,,,,,,,,36,36,36,15,36,36,17,36,36,36,15,36,11,36,17,2,15,11,11,17,,,,,,,,,,,,,,,,,,,,,15,36,36,36,36,36,36,36,36,17,15,36,36,36,36,36,36,36,36,17,,,,,,,,,,,,, +,,,,,,,,,,,9,43,14,23,36,36,22,14,43,10,15,36,11,36,17,2,15,11,11,17,,,,,,,,,,,,,,,,,,,,,15,36,36,36,36,36,36,36,36,25,24,36,36,36,36,36,36,21,16,7,,,,,,,,,,,,, +,,,,,,,,,,,15,36,36,36,36,36,36,36,36,17,15,36,11,36,17,2,15,36,36,17,,,,,,,,,,,,,,,,,,,,,15,36,36,36,36,36,36,36,36,30,31,36,36,36,36,36,36,17,11,21,,,,,,,,,,,,, +,,,,,,,,,,,15,36,36,36,36,36,36,36,36,17,15,36,11,36,17,2,15,36,36,17,,,,,,,,,,,,,,,,,,,,,15,36,36,36,36,36,36,36,36,17,15,11,11,36,36,36,36,17,11,17,,,,,,,,,,,,, +,,,,,,,,,,,8,16,16,16,29,28,16,16,16,7,8,20,11,21,7,2,8,29,28,7,,,,,,,,,,,,,,,,,,,,,8,16,16,16,29,28,16,16,16,7,8,16,16,29,28,16,16,7,11,17,,,,,,,,,,,,, +,,,,,,,,,,,9,14,14,14,27,26,14,14,14,10,9,23,11,22,14,14,14,27,26,10,9,14,14,14,14,14,14,14,14,10,,,9,14,10,9,14,10,,,9,14,14,14,27,26,14,14,14,10,9,14,14,27,26,14,14,10,11,17,,,,,,,,,,,,, +,,,,,,,,,,,15,36,36,36,36,36,36,36,36,17,15,36,11,36,36,36,36,36,36,17,15,36,36,36,36,36,36,36,36,17,,,15,36,17,15,36,17,,,15,36,36,36,36,36,36,36,36,17,15,36,36,36,36,36,36,17,11,17,,,,,,,,,,,,, +,,,,,,,,,,,15,52,52,52,52,52,36,36,36,17,15,36,11,11,11,11,11,36,36,22,23,36,36,36,36,36,36,36,36,22,14,14,23,36,22,23,36,22,14,14,23,36,36,36,36,36,36,36,36,17,15,36,52,36,36,36,52,17,11,17,,,,,,,,,,,,, +,,,,,,,,,,,15,52,11,11,11,52,36,36,36,17,15,36,11,36,36,36,11,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,17,15,52,36,52,52,52,36,17,11,17,,,,,,,,,,,,, +,,,,,,,,,,,15,52,11,13,11,52,36,36,36,17,15,36,11,36,36,36,11,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,17,8,43,20,52,52,52,36,17,11,17,,,,,,,,,,,,, +,,,,,,,,,,,15,52,11,11,11,52,36,36,36,17,15,36,11,11,11,11,11,36,36,21,20,36,36,34,18,18,35,36,36,21,16,16,20,36,36,36,36,21,16,16,20,36,36,36,36,36,36,36,36,17,11,11,15,52,21,43,16,7,11,17,,,,,,,,,,,,, +,,,,,,,,,,,15,52,52,52,52,52,36,36,36,17,15,36,36,36,36,36,36,36,36,17,15,36,36,32,4,3,33,36,36,17,,,15,36,36,53,53,17,,,15,36,36,36,36,36,36,36,36,17,11,11,8,16,7,11,11,11,11,17,,,,,,,,,,,,, +,,,,,,,,,,,8,16,16,16,16,16,16,16,16,7,8,16,16,16,16,16,16,16,16,7,8,16,16,6,0,1,5,16,16,7,,,8,16,16,16,16,7,,,8,16,16,16,16,16,16,16,16,7,21,16,16,16,16,16,16,16,16,7,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,, +0,,,,,,,,,,,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,,,,,,,,,,,0,, +0,,,,,,,,,,,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,,,,,,,,,,,0,, +0,,,,,,,,,,,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,,,,,,,,,,,0,, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,,,,,,,0,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,0,0,0,0,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,,,,,,,0,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,,,,,,,0,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,,,,,,,0,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,,,,,,,0,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +2538 +169;192;432;d6_button_0 +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;16;128;;; +0;16;176;;; +0;16;192;;; +0;16;208;;; +0;16;224;;; +0;16;240;;; +0;16;304;;; +0;16;320;;; +0;16;336;;; +0;16;352;;; +0;16;368;;; +0;16;384;;; +0;16;432;;; +0;16;448;;; +0;16;464;;; +0;16;480;;; +0;16;496;;; +0;16;512;;; +0;32;32;;; +0;32;144;;; +0;32;160;;; +0;32;288;;; +0;32;400;;; +0;32;416;;; +0;32;528;;; +0;48;32;;; +0;48;144;;; +0;48;160;;; +0;48;288;;; +0;48;400;;; +0;48;416;;; +0;48;528;;; +0;64;32;;; +0;64;288;;; +0;64;400;;; +0;64;416;;; +0;64;528;;; +0;80;32;;; +0;80;528;;; +0;96;144;;; +0;96;160;;; +0;96;528;;; +0;112;32;;; +0;112;144;;; +0;112;160;;; +0;112;256;;; +0;112;304;;; +0;112;400;;; +0;112;416;;; +0;112;528;;; +0;128;16;;; +0;128;144;;; +0;128;160;;; +0;128;256;;; +0;128;304;;; +0;128;400;;; +0;128;416;;; +0;128;528;;; +0;144;32;;; +0;144;144;;; +0;144;160;;; +0;144;256;;; +0;144;304;;; +0;144;400;;; +0;144;416;;; +0;144;528;;; +0;160;48;;; +0;160;64;;; +0;160;80;;; +0;160;96;;; +0;160;112;;; +0;160;128;;; +0;160;192;;; +0;160;208;;; +0;160;224;;; +0;160;256;;; +0;160;304;;; +0;160;336;;; +0;160;352;;; +0;160;368;;; +0;160;384;;; +0;160;432;;; +0;160;448;;; +0;160;464;;; +0;160;512;;; +0;176;208;;; +0;176;224;;; +0;176;256;;; +0;176;272;;; +0;176;288;;; +0;176;304;;; +0;176;336;;; +0;176;352;;; +0;176;368;;; +0;176;384;;; +0;176;432;;; +0;176;448;;; +0;176;464;;; +0;176;512;;; +0;176;560;;; +0;176;576;;; +0;176;592;;; +0;176;608;;; +0;176;624;;; +0;176;640;;; +0;176;736;;; +0;176;752;;; +0;176;768;;; +0;176;816;;; +0;176;832;;; +0;176;848;;; +0;176;864;;; +0;176;880;;; +0;176;896;;; +0;192;400;;; +0;192;416;;; +0;192;528;;; +0;192;544;;; +0;192;784;;; +0;192;800;;; +0;192;912;;; +0;208;400;;; +0;208;416;;; +0;208;784;;; +0;208;800;;; +0;208;912;;; +0;224;400;;; +0;224;416;;; +0;224;528;;; +0;224;544;;; +0;224;560;;; +0;224;656;;; +0;224;720;;; +0;224;784;;; +0;224;800;;; +0;224;912;;; +0;240;400;;; +0;240;416;;; +0;240;528;;; +0;240;560;;; +0;240;912;;; +0;256;400;;; +0;256;416;;; +0;256;528;;; +0;256;544;;; +0;256;560;;; +0;256;912;;; +0;272;320;;; +0;272;656;;; +0;272;720;;; +0;272;784;;; +0;272;800;;; +0;272;912;;; +0;288;320;;; +0;288;528;;; +0;288;544;;; +0;288;784;;; +0;288;800;;; +0;288;912;;; +0;304;528;;; +0;304;544;;; +0;304;784;;; +0;304;800;;; +0;304;912;;; +0;320;464;;; +0;320;496;;; +0;320;512;;; +0;320;592;;; +0;320;608;;; +0;320;624;;; +0;320;736;;; +0;320;752;;; +0;320;768;;; +0;320;816;;; +0;320;832;;; +0;320;848;;; +0;320;864;;; +0;320;880;;; +0;320;896;;; +0;336;464;;; +0;336;496;;; +0;336;512;;; +0;336;624;;; +0;336;656;;; +0;336;720;;; +0;336;736;;; +0;336;752;;; +0;336;768;;; +0;336;816;;; +0;336;832;;; +0;336;848;;; +0;336;864;;; +0;336;880;;; +0;336;896;;; +0;352;528;;; +0;352;544;;; +0;352;592;;; +0;352;624;;; +0;352;784;;; +0;352;800;;; +0;352;912;;; +0;368;464;;; +0;368;512;;; +0;368;528;;; +0;368;544;;; +0;368;592;;; +0;368;624;;; +0;368;912;;; +0;384;464;;; +0;384;512;;; +0;384;528;;; +0;384;544;;; +0;384;592;;; +0;384;624;;; +0;384;784;;; +0;384;800;;; +0;384;912;;; +0;400;480;;; +0;400;496;;; +0;400;512;;; +0;400;528;;; +0;400;544;;; +0;400;592;;; +0;400;640;;; +0;400;656;;; +0;400;672;;; +0;400;688;;; +0;400;704;;; +0;400;720;;; +0;400;736;;; +0;400;752;;; +0;400;768;;; +0;400;800;;; +0;400;912;;; +0;416;464;;; +0;416;496;;; +0;416;528;;; +0;416;544;;; +0;416;592;;; +0;416;800;;; +0;416;912;;; +0;432;464;;; +0;432;496;;; +0;432;512;;; +0;432;528;;; +0;432;544;;; +0;432;608;;; +0;432;624;;; +0;432;640;;; +0;432;688;;; +0;432;704;;; +0;432;720;;; +0;432;736;;; +0;432;752;;; +0;432;768;;; +0;432;800;;; +0;432;912;;; +0;448;528;;; +0;448;544;;; +0;448;912;;; +0;464;528;;; +0;464;544;;; +0;464;912;;; +0;480;432;;; +0;480;448;;; +0;480;464;;; +0;480;480;;; +0;480;496;;; +0;480;512;;; +0;480;560;;; +0;480;576;;; +0;480;592;;; +0;480;608;;; +0;480;624;;; +0;480;640;;; +0;480;688;;; +0;480;704;;; +0;480;720;;; +0;480;736;;; +0;480;752;;; +0;480;768;;; +0;480;816;;; +0;480;832;;; +0;480;880;;; +0;480;896;;; +0;496;160;;; +0;496;176;;; +0;496;192;;; +0;496;208;;; +0;496;224;;; +0;496;240;;; +0;496;256;;; +0;496;432;;; +0;496;448;;; +0;496;464;;; +0;496;480;;; +0;496;496;;; +0;496;512;;; +0;496;576;;; +0;496;592;;; +0;496;608;;; +0;496;624;;; +0;496;640;;; +0;496;816;;; +0;496;832;;; +0;496;880;;; +0;496;896;;; +0;512;160;;; +0;512;528;;; +0;512;560;;; +0;512;656;;; +0;512;800;;; +0;512;912;;; +0;528;160;;; +0;528;528;;; +0;528;560;;; +0;528;656;;; +0;528;800;;; +0;528;912;;; +0;544;160;;; +0;544;272;;; +0;544;528;;; +0;544;560;;; +0;544;656;;; +0;544;800;;; +0;544;912;;; +0;560;160;;; +0;560;272;;; +0;560;288;;; +0;560;352;;; +0;560;528;;; +0;560;560;;; +0;560;656;;; +0;560;800;;; +0;576;160;;; +0;576;272;;; +0;576;288;;; +0;576;352;;; +0;576;528;;; +0;576;544;;; +0;576;560;;; +0;576;656;;; +0;576;800;;; +0;592;160;;; +0;592;272;;; +0;592;288;;; +0;592;352;;; +0;592;656;;; +0;592;800;;; +0;592;912;;; +0;608;160;;; +0;608;272;;; +0;608;288;;; +0;608;352;;; +0;608;368;;; +0;608;656;;; +0;608;800;;; +0;608;912;;; +0;624;160;;; +0;624;272;;; +0;624;288;;; +0;624;528;;; +0;624;544;;; +0;624;560;;; +0;624;656;;; +0;624;800;;; +0;624;912;;; +0;640;160;;; +0;640;176;;; +0;640;192;;; +0;640;208;;; +0;640;224;;; +0;640;240;;; +0;640;256;;; +0;640;272;;; +0;640;304;;; +0;640;320;;; +0;640;336;;; +0;640;352;;; +0;640;368;;; +0;640;384;;; +0;640;400;;; +0;640;416;;; +0;640;432;;; +0;640;448;;; +0;640;464;;; +0;640;480;;; +0;640;496;;; +0;640;512;;; +0;640;560;;; +0;640;576;;; +0;640;592;;; +0;640;608;;; +0;640;816;;; +0;640;832;;; +0;640;880;;; +0;640;896;;; +0;656;176;;; +0;656;192;;; +0;656;208;;; +0;656;224;;; +0;656;240;;; +0;656;256;;; +0;656;304;;; +0;656;320;;; +0;656;336;;; +0;656;352;;; +0;656;368;;; +0;656;384;;; +0;656;432;;; +0;656;448;;; +0;656;464;;; +0;656;480;;; +0;656;496;;; +0;656;512;;; +0;656;560;;; +0;656;576;;; +0;656;592;;; +0;656;608;;; +0;656;832;;; +0;656;880;;; +0;672;160;;; +0;672;272;;; +0;672;288;;; +0;672;400;;; +0;672;416;;; +0;672;528;;; +0;672;544;;; +0;672;656;;; +0;672;832;;; +0;672;880;;; +0;688;176;;; +0;688;272;;; +0;688;288;;; +0;688;400;;; +0;688;416;;; +0;688;528;;; +0;688;544;;; +0;688;656;;; +0;688;816;;; +0;688;832;;; +0;688;880;;; +0;688;896;;; +0;704;272;;; +0;704;288;;; +0;704;400;;; +0;704;416;;; +0;704;528;;; +0;704;544;;; +0;704;656;;; +0;704;800;;; +0;704;912;;; +0;720;160;;; +0;720;656;;; +0;720;816;;; +0;720;832;;; +0;720;912;;; +0;736;160;;; +0;736;656;;; +0;736;816;;; +0;736;832;;; +0;736;912;;; +0;752;272;;; +0;752;288;;; +0;752;400;;; +0;752;416;;; +0;752;528;;; +0;752;544;;; +0;752;656;;; +0;752;800;;; +0;752;912;;; +0;768;176;;; +0;768;272;;; +0;768;288;;; +0;768;400;;; +0;768;416;;; +0;768;528;;; +0;768;544;;; +0;768;656;;; +0;768;816;;; +0;768;832;;; +0;768;880;;; +0;768;896;;; +0;784;160;;; +0;784;272;;; +0;784;288;;; +0;784;400;;; +0;784;416;;; +0;784;528;;; +0;784;544;;; +0;784;656;;; +0;784;832;;; +0;784;880;;; +0;800;176;;; +0;800;192;;; +0;800;208;;; +0;800;224;;; +0;800;240;;; +0;800;256;;; +0;800;304;;; +0;800;320;;; +0;800;336;;; +0;800;352;;; +0;800;368;;; +0;800;384;;; +0;800;432;;; +0;800;448;;; +0;800;464;;; +0;800;480;;; +0;800;496;;; +0;800;512;;; +0;800;560;;; +0;800;576;;; +0;800;592;;; +0;800;608;;; +0;800;624;;; +0;800;640;;; +0;800;832;;; +0;800;880;;; +0;816;304;;; +0;816;320;;; +0;816;336;;; +0;816;352;;; +0;816;368;;; +0;816;384;;; +0;816;432;;; +0;816;448;;; +0;816;464;;; +0;816;480;;; +0;816;496;;; +0;816;512;;; +0;816;560;;; +0;816;576;;; +0;816;592;;; +0;816;608;;; +0;816;624;;; +0;816;640;;; +0;816;704;;; +0;816;720;;; +0;816;736;;; +0;816;752;;; +0;816;768;;; +0;816;816;;; +0;816;832;;; +0;816;880;;; +0;816;896;;; +0;832;288;;; +0;832;400;;; +0;832;416;;; +0;832;528;;; +0;832;544;;; +0;832;656;;; +0;832;688;;; +0;832;784;;; +0;832;800;;; +0;832;912;;; +0;848;288;;; +0;848;400;;; +0;848;416;;; +0;848;528;;; +0;848;544;;; +0;848;656;;; +0;848;672;;; +0;848;688;;; +0;848;784;;; +0;848;800;;; +0;848;912;;; +0;864;288;;; +0;864;400;;; +0;864;416;;; +0;864;528;;; +0;864;544;;; +0;864;656;;; +0;864;672;;; +0;864;784;;; +0;864;800;;; +0;864;912;;; +0;880;912;;; +0;896;528;;; +0;896;544;;; +0;896;912;;; +0;912;288;;; +0;912;400;;; +0;912;416;;; +0;912;528;;; +0;912;544;;; +0;912;656;;; +0;912;672;;; +0;912;784;;; +0;912;800;;; +0;912;912;;; +0;928;288;;; +0;928;400;;; +0;928;416;;; +0;928;528;;; +0;928;544;;; +0;928;656;;; +0;928;688;;; +0;928;784;;; +0;928;800;;; +0;928;912;;; +0;944;288;;; +0;944;400;;; +0;944;416;;; +0;944;528;;; +0;944;544;;; +0;944;656;;; +0;944;688;;; +0;944;784;;; +0;944;800;;; +0;944;912;;; +0;960;304;;; +0;960;320;;; +0;960;336;;; +0;960;352;;; +0;960;368;;; +0;960;384;;; +0;960;432;;; +0;960;448;;; +0;960;464;;; +0;960;480;;; +0;960;496;;; +0;960;512;;; +0;960;560;;; +0;960;576;;; +0;960;592;;; +0;960;608;;; +0;960;624;;; +0;960;640;;; +0;960;704;;; +0;960;720;;; +0;960;768;;; +0;960;816;;; +0;960;832;;; +0;960;848;;; +0;960;864;;; +0;960;880;;; +0;960;896;;; +0;976;176;;; +0;976;192;;; +0;976;208;;; +0;976;224;;; +0;976;240;;; +0;976;256;;; +0;976;272;;; +0;976;288;;; +0;976;304;;; +0;976;320;;; +0;976;336;;; +0;976;352;;; +0;976;368;;; +0;976;384;;; +0;976;400;;; +0;976;416;;; +0;976;432;;; +0;976;448;;; +0;976;464;;; +0;976;704;;; +0;976;720;;; +0;976;768;;; +0;976;816;;; +0;976;832;;; +0;976;848;;; +0;976;864;;; +0;976;912;;; +0;992;160;;; +0;992;496;;; +0;992;512;;; +0;992;528;;; +0;992;544;;; +0;992;560;;; +0;992;576;;; +0;992;592;;; +0;992;608;;; +0;992;624;;; +0;992;688;;; +0;992;784;;; +0;992;800;;; +0;992;912;;; +0;1008;160;;; +0;1008;400;;; +0;1008;416;;; +0;1008;640;;; +0;1008;672;;; +0;1008;688;;; +0;1008;784;;; +0;1008;800;;; +0;1008;912;;; +0;1024;160;;; +0;1024;400;;; +0;1024;416;;; +0;1024;512;;; +0;1024;528;;; +0;1024;544;;; +0;1024;640;;; +0;1024;672;;; +0;1024;912;;; +0;1040;160;;; +0;1040;400;;; +0;1040;416;;; +0;1040;512;;; +0;1040;544;;; +0;1040;640;;; +0;1040;672;;; +0;1040;912;;; +0;1056;160;;; +0;1056;400;;; +0;1056;416;;; +0;1056;432;;; +0;1056;512;;; +0;1056;544;;; +0;1056;640;;; +0;1056;672;;; +0;1056;784;;; +0;1056;800;;; +0;1056;912;;; +0;1072;160;;; +0;1072;512;;; +0;1072;544;;; +0;1072;672;;; +0;1072;784;;; +0;1072;800;;; +0;1072;912;;; +0;1088;160;;; +0;1088;352;;; +0;1088;368;;; +0;1088;384;;; +0;1088;400;;; +0;1088;416;;; +0;1088;544;;; +0;1088;736;;; +0;1088;752;;; +0;1088;912;;; +0;1104;160;;; +0;1104;272;;; +0;1104;288;;; +0;1104;304;;; +0;1104;320;;; +0;1104;336;;; +0;1104;352;;; +0;1104;416;;; +0;1104;528;;; +0;1104;544;;; +0;1104;736;;; +0;1104;912;;; +0;1120;176;;; +0;1120;192;;; +0;1120;208;;; +0;1120;224;;; +0;1120;240;;; +0;1120;432;;; +0;1120;448;;; +0;1120;464;;; +0;1120;512;;; +0;1120;560;;; +0;1120;576;;; +0;1120;592;;; +0;1120;608;;; +0;1120;624;;; +0;1120;640;;; +0;1120;656;;; +0;1120;672;;; +0;1120;688;;; +0;1120;704;;; +0;1120;720;;; +0;1120;736;;; +0;1120;752;;; +0;1120;768;;; +0;1120;784;;; +0;1120;800;;; +0;1120;816;;; +0;1120;832;;; +0;1120;848;;; +0;1120;864;;; +0;1120;880;;; +0;1120;896;;; +0;1120;912;;; +0;1136;48;;; +0;1136;64;;; +0;1136;80;;; +0;1136;96;;; +0;1136;112;;; +0;1136;128;;; +0;1136;192;;; +0;1136;208;;; +0;1136;224;;; +0;1136;240;;; +0;1136;256;;; +0;1136;304;;; +0;1136;320;;; +0;1136;336;;; +0;1136;352;;; +0;1136;368;;; +0;1136;384;;; +0;1136;432;;; +0;1136;448;;; +0;1136;464;;; +0;1136;512;;; +0;1152;32;;; +0;1152;144;;; +0;1152;176;;; +0;1152;240;;; +0;1152;272;;; +0;1152;288;;; +0;1152;400;;; +0;1152;416;;; +0;1152;528;;; +0;1168;32;;; +0;1168;144;;; +0;1168;176;;; +0;1168;208;;; +0;1168;240;;; +0;1168;528;;; +0;1184;32;;; +0;1184;144;;; +0;1184;176;;; +0;1184;208;;; +0;1184;240;;; +0;1184;528;;; +0;1200;144;;; +0;1200;160;;; +0;1200;208;;; +0;1200;240;;; +0;1200;272;;; +0;1200;288;;; +0;1200;400;;; +0;1200;416;;; +0;1200;528;;; +0;1216;32;;; +0;1216;208;;; +0;1216;240;;; +0;1216;272;;; +0;1216;400;;; +0;1216;416;;; +0;1216;528;;; +0;1232;32;;; +0;1232;208;;; +0;1232;240;;; +0;1232;272;;; +0;1232;288;;; +0;1232;400;;; +0;1232;416;;; +0;1232;528;;; +0;1248;32;;; +0;1248;144;;; +0;1248;160;;; +0;1248;208;;; +0;1248;240;;; +0;1248;272;;; +0;1248;288;;; +0;1248;384;;; +0;1248;528;;; +0;1264;32;;; +0;1264;144;;; +0;1264;176;;; +0;1264;208;;; +0;1264;272;;; +0;1264;288;;; +0;1264;528;;; +0;1280;48;;; +0;1280;64;;; +0;1280;80;;; +0;1280;96;;; +0;1280;112;;; +0;1280;128;;; +0;1280;192;;; +0;1280;208;;; +0;1280;224;;; +0;1280;240;;; +0;1280;256;;; +0;1280;304;;; +0;1280;320;;; +0;1280;336;;; +0;1280;368;;; +0;1280;400;;; +0;1280;416;;; +0;1280;432;;; +0;1280;448;;; +0;1280;464;;; +0;1280;480;;; +0;1280;496;;; +0;1280;512;;; +19;208;672;;; +19;320;160;;; +19;320;672;;; +19;1040;368;;; +20;176;176;;; +20;1040;592;;; +20;1232;336;;; +21;320;432;;; +21;528;304;;; +21;592;400;;; +21;1024;464;;; +14;496;288;;; +14;560;384;;; +1;160;496;;; +1;176;496;;; +1;320;352;;; +1;320;576;;; +1;336;352;;; +1;336;576;;; +1;480;352;;; +1;496;352;;; +1;552;896;;; +1;584;896;;; +1;640;640;;; +1;656;640;;; +1;960;752;;; +1;976;752;;; +1;1120;496;;; +1;1136;496;;; +3;64;144;;; +3;64;160;;; +3;80;272;;; +3;80;288;;; +3;240;656;;; +3;240;672;;; +3;240;784;;; +3;240;800;;; +3;448;656;;; +3;448;672;;; +3;448;784;;; +3;448;800;;; +3;560;912;;; +3;592;528;;; +3;592;544;;; +3;720;272;;; +3;720;288;;; +3;720;400;;; +3;720;416;;; +3;720;528;;; +3;720;544;;; +3;880;288;;; +3;880;400;;; +3;880;416;;; +3;880;656;;; +3;880;672;;; +3;880;784;;; +3;880;800;;; +3;1024;784;;; +3;1024;800;;; +3;1088;656;;; +3;1088;672;;; +3;1168;272;;; +3;1168;288;;; +3;1168;400;;; +3;1168;416;;; +3;1216;144;;; +3;1216;160;;; +4;80;144;;; +4;80;160;;; +4;96;272;;; +4;96;288;;; +4;256;656;;; +4;256;672;;; +4;256;784;;; +4;256;800;;; +4;464;656;;; +4;464;672;;; +4;464;784;;; +4;464;800;;; +4;576;912;;; +4;608;528;;; +4;608;544;;; +4;736;272;;; +4;736;288;;; +4;736;400;;; +4;736;416;;; +4;736;528;;; +4;736;544;;; +4;896;288;;; +4;896;400;;; +4;896;416;;; +4;896;656;;; +4;896;672;;; +4;896;784;;; +4;896;800;;; +4;1040;784;;; +4;1040;800;;; +4;1104;656;;; +4;1104;672;;; +4;1184;272;;; +4;1184;288;;; +4;1184;400;;; +4;1184;416;;; +4;1232;144;;; +4;1232;160;;; +2;160;480;;; +2;176;480;;; +2;320;336;;; +2;320;560;;; +2;336;336;;; +2;336;560;;; +2;480;336;;; +2;496;336;;; +2;640;624;;; +2;656;624;;; +2;960;736;;; +2;976;736;;; +2;1120;480;;; +2;1136;480;;; +15;320;288;;; +15;1008;368;;; +16;288;176;;; +16;1088;592;;; +17;320;400;;; +17;1008;240;;; +18;176;672;;; +18;288;384;;; +18;288;672;;; +199;128;64;ruby100;;d6_ruby100_1;; +199;192;688;stonelifter2;;d6_stonelifter_2;; +199;224;224;compass;six;d6_compass;; +199;224;304;stonebeak;six;d6_stoneBeak;; +199;448;576;ruby100;;d6_ruby100_0;; +199;448;720;ruby50;;d6_ruby50;; +199;1024;192;nightmarekey;six;d6_nightmarekey;;True +199;1072;304;smallkeyChest;six;d6_smallkey_0;; +199;1104;752;potion;;d6_potion;; +199;1168;64;ruby200;;d6_ruby200;; +289;568;216;d6_et_1 +289;568;496;d6_smallkey_2 +289;1024;304;d6_smallkey_0 +289;1040;192;d6_nightmarekey +234;80;208;;;;;; +234;240;720;;;;;; +234;256;720;;;;;; +234;400;464;;;;;; +234;400;560;;;;;; +234;464;720;;;;;; +234;704;864;;;;;; +234;752;864;;;;;; +234;848;336;;;;;; +234;864;736;;;;;; +234;928;336;;;;;; +261;72;144;;d6_door_7;1; +261;72;160;;d6_door_7;3; +261;88;272;;d6_door_6;1; +261;88;288;;d6_door_6;3; +261;160;488;;d6_door_5;; +261;176;488;;d6_door_5;2; +261;248;784;;d6_door_10;1; +261;248;800;;d6_door_10;3; +261;320;344;;d6_door_8;; +261;320;568;;d6_door_4;; +261;336;344;;d6_door_8;2; +261;336;568;;d6_door_4;2; +261;456;656;;d6_door_23;1; +261;456;672;;d6_door_23;3; +261;456;784;;d6_door_3;1; +261;456;800;;d6_door_3;3; +261;480;344;;d6_door_9;; +261;496;344;;d6_door_9;2; +261;600;528;;d6_door_14;1; +261;600;544;;d6_door_14;3; +261;640;632;;d6_door_15;; +261;656;632;;d6_door_15;2; +261;728;272;2;d6_door_22;1; +261;728;288;2;d6_door_22;3; +261;728;400;2;d6_door_21;1; +261;728;416;3;d6_door_21;3;d6_nightmareKeyhole +261;728;528;;d6_door_16;1; +261;728;544;;d6_door_16;3; +261;888;400;;d6_door_11;1; +261;888;416;;d6_door_11;3; +261;888;656;;d6_door_2;1; +261;888;672;1;d6_door_2;3;d6_door_2 +261;888;784;;d6_door_0;1; +261;888;800;;d6_door_0;3; +261;960;744;;d6_door_1;; +261;976;744;;d6_door_1;2; +261;1032;784;;d6_door_13;1; +261;1032;800;;d6_door_13;3; +261;1096;656;;d6_door_12;1; +261;1096;672;;d6_door_12;3; +261;1120;488;;d6_door_19;; +261;1136;488;;d6_door_19;2; +261;1176;272;;d6_door_17;1; +261;1176;288;;d6_door_17;3; +261;1176;400;;d6_door_18;1; +261;1176;416;;d6_door_18;3; +261;1224;144;;d6_door_20;1; +261;1224;160;;d6_door_20;3; +174;544;944;dungeon_6 +153;128;32;;;d6_top;overworld.map;d6_top;3;;False +153;224;368;;;d6_2d_2L;dungeon6_2d_2.map;d6_2d_2L;2;1;False +153;224;864;;;d6_2d_3L;dungeon6_2d_3.map;d6_2d_3L;2;1;False +153;512;432;;;d6_2d_1L;dungeon6_2d_1.map;d6_2d_1L;2;1;False +153;568;904;;;d6_vacuum_entry;;;3;6;False +153;568;920;;;d6;overworld.map;d6;1;; +153;848;336;;;;dungeon6_2d_1.map;d6_2d_1R;2;1;False +153;864;336;;;d6_2d_1R;;;-1;1;False +153;1264;304;;;d6_2d_2R;dungeon6_2d_2.map;d6_2d_2R;;1;False +245;544;976;six;; +62;16;256;;;;;; +62;16;272;;;;;; +62;32;272;;;;;; +62;48;272;;;;;; +62;192;256;;;;;; +62;192;336;;;;;; +62;208;256;;;;;; +62;208;336;;;;;; +62;224;256;;;;;; +62;240;256;;;;;; +62;240;336;;;;;; +62;256;256;;;;;; +62;256;336;;;;;; +62;272;336;;;;;; +62;528;848;;;;;; +62;528;864;;;;;; +62;528;880;;;;;; +62;608;848;;;;;; +62;608;864;;;;;; +62;608;880;;;;;; +62;704;176;;;;;; +62;704;208;;;;;; +62;752;176;;;;;; +62;752;208;;;;;; +62;864;688;;;;;; +62;912;688;;;;;; +62;976;880;;;;;; +62;976;896;;;;;; +62;992;896;;;;;; +325;320;480;;d6_wall_1;;; +325;336;480;;d6_wall_1;2;; +325;880;528;;d6_wall_0;1;; +325;880;544;;d6_wall_0;3;; +335;32;96;d6_switch;True; +335;32;480;d6_switch;; +335;48;96;d6_switch;True; +335;48;480;d6_switch;; +335;64;96;d6_switch;True; +335;64;192;d6_switch;; +335;64;208;d6_switch;; +335;64;224;d6_switch;; +335;64;304;d6_switch;; +335;64;320;d6_switch;; +335;64;336;d6_switch;; +335;64;352;d6_switch;; +335;64;480;d6_switch;; +335;80;48;d6_switch;True; +335;80;64;d6_switch;True; +335;80;80;d6_switch;True; +335;80;96;d6_switch;True; +335;80;192;d6_switch;; +335;80;480;d6_switch;; +335;96;192;d6_switch;; +335;96;480;d6_switch;; +335;112;176;d6_switch;True; +335;112;192;d6_switch;; +335;112;208;d6_switch;True; +335;112;224;d6_switch;True; +335;112;240;d6_switch;True; +335;112;336;d6_switch;True; +335;112;352;d6_switch;True; +335;112;368;d6_switch;True; +335;112;384;d6_switch;True; +335;112;432;d6_switch;True; +335;112;448;d6_switch;True; +335;112;464;d6_switch;True; +335;112;480;d6_switch;True; +335;112;496;d6_switch;; +335;112;512;d6_switch;; +335;128;80;d6_switch;; +335;128;192;d6_switch;; +335;128;336;d6_switch;True; +335;128;496;d6_switch;True; +335;144;192;d6_switch;; +335;144;336;d6_switch;True; +335;144;496;d6_switch;True; +335;192;480;d6_switch;True; +335;192;832;d6_switch;True; +335;192;848;d6_switch;True; +335;192;864;d6_switch;True; +335;192;880;d6_switch;True; +335;192;896;d6_switch;True; +335;208;480;d6_switch;True; +335;208;560;d6_switch;; +335;208;624;d6_switch;; +335;208;832;d6_switch;True; +335;208;896;d6_switch;True; +335;224;480;d6_switch;True; +335;224;832;d6_switch;True; +335;224;896;d6_switch;True; +335;240;464;d6_switch;; +335;240;480;d6_switch;; +335;240;496;d6_switch;; +335;240;512;d6_switch;; +335;240;832;d6_switch;True; +335;240;896;d6_switch;True; +335;256;464;d6_switch;; +335;256;832;d6_switch;True; +335;256;848;d6_switch;True; +335;256;864;d6_switch;True; +335;256;880;d6_switch;True; +335;256;896;d6_switch;True; +335;272;560;d6_switch;; +335;272;624;d6_switch;; +335;512;176;d6_switch;; +335;512;192;d6_switch;; +335;512;208;d6_switch;; +335;512;224;d6_switch;; +335;512;240;d6_switch;; +335;512;256;d6_switch;; +335;528;176;d6_switch;; +335;528;192;d6_switch;; +335;528;208;d6_switch;; +335;528;224;d6_switch;; +335;528;240;d6_switch;; +335;528;256;d6_switch;; +335;544;176;d6_switch;; +335;544;192;d6_switch;; +335;544;224;d6_switch;; +335;544;240;d6_switch;; +335;544;256;d6_switch;; +335;560;192;d6_switch;; +335;560;208;d6_switch;; +335;560;224;d6_switch;; +335;560;240;d6_switch;; +335;560;256;d6_switch;; +335;576;192;d6_switch;; +335;576;208;d6_switch;; +335;576;224;d6_switch;; +335;576;240;d6_switch;; +335;576;256;d6_switch;; +335;592;176;d6_switch;; +335;592;192;d6_switch;; +335;592;224;d6_switch;; +335;592;240;d6_switch;; +335;592;256;d6_switch;; +335;608;176;d6_switch;; +335;608;192;d6_switch;; +335;608;208;d6_switch;; +335;608;224;d6_switch;; +335;608;240;d6_switch;; +335;608;256;d6_switch;; +335;624;176;d6_switch;; +335;624;192;d6_switch;; +335;624;208;d6_switch;; +335;624;224;d6_switch;; +335;624;240;d6_switch;; +335;624;256;d6_switch;; +335;992;848;d6_switch;True; +335;1008;832;d6_switch;True; +335;1024;848;d6_switch;True; +335;1024;864;d6_switch;; +335;1024;880;d6_switch;; +335;1040;848;d6_switch;True; +335;1040;864;d6_switch;True; +335;1056;848;d6_switch;True; +335;1056;864;d6_switch;; +335;1072;832;d6_switch;True; +335;1168;80;d6_switch;; +335;1216;48;d6_switch;True; +335;1216;64;d6_switch;True; +335;1216;80;d6_switch;True; +335;1216;96;d6_switch;True; +335;1232;96;d6_switch;True; +335;1248;96;d6_switch;True; +335;1264;96;d6_switch;True; +284;576;944;;;;150 +248;816;288;d6_wall_0;; +248;816;416;d6_wall_0;; +351;64;112;d6_horse_head_0; +351;112;112;d6_horse_head_0;3 +351;400;336;d6_horse_head_1; +351;416;352;d6_horse_head_1;3 +351;1184;112;d6_horse_head_2; +351;1232;112;d6_horse_head_2;3 +331;248;656 +350;576;369;d6_beak_1 +350;992;801;d6_beak_2 +350;1040;161;beak_d6_3 +349;704;848;2 +349;704;864;1 +349;704;880;1 +349;704;896;1 +349;720;848;3 +349;720;864;3 +349;720;880;3 +349;720;896; +349;736;848;2 +349;736;864;1 +349;736;880;1 +349;752;848;3 +349;752;864;3 +349;752;880; +330;32;512;d6_switch +330;48;64;d6_switch +330;176;160;d6_switch +330;240;592;d6_switch +330;1072;192;d6_switch +330;1248;64;d6_switch +428;560;176 +470;784;640 +468;512;464;d6_tiles_1;; +468;528;448;d6_tiles_1;11; +468;528;480;d6_tiles_1;9; +468;544;432;d6_tiles_1;4; +468;544;464;d6_tiles_1;13; +468;544;496;d6_tiles_1;7; +468;560;480;d6_tiles_1;3; +468;560;512;d6_tiles_1;14; +468;576;480;d6_tiles_1;1; +468;576;512;d6_tiles_1;12; +468;592;432;d6_tiles_1;6; +468;592;464;d6_tiles_1;15; +468;592;496;d6_tiles_1;5; +468;608;448;d6_tiles_1;8; +468;608;480;d6_tiles_1;10; +468;624;464;d6_tiles_1;2; +468;848;848;d6_tiles_0;4; +468;848;864;d6_tiles_0;6; +468;864;832;d6_tiles_0;; +468;864;848;d6_tiles_0;8; +468;864;864;d6_tiles_0;10; +468;864;880;d6_tiles_0;3; +468;880;832;d6_tiles_0;12; +468;880;880;d6_tiles_0;15; +468;896;832;d6_tiles_0;14; +468;896;880;d6_tiles_0;13; +468;912;832;d6_tiles_0;2; +468;912;848;d6_tiles_0;11; +468;912;864;d6_tiles_0;9; +468;912;880;d6_tiles_0;1; +468;928;848;d6_tiles_0;7; +468;928;864;d6_tiles_0;5; +467;32;64 +467;256;208 +467;992;336 +467;1008;848 +467;1072;848 +467;1104;592 +467;1264;64 +439;560;608;dungeon6.map;d6_vacuum_entry; +464;1008;576 +464;1024;624 +464;1056;320 +464;1072;352 +464;1088;320 +469;48;496 +469;80;464 +469;128;448 +469;304;848 +469;304;880 +469;384;864 +469;400;832 +469;416;864 +469;544;208 +469;592;208 +469;736;592 +469;1024;704 +469;1040;720 +469;1056;736 +469;1072;752 +427;48;228;3;; +427;96;172;1;False; +427;384;772;3;False; +427;528;332;1;False; +427;528;356;1;; +427;688;452;2;;d6_lamps_on +427;752;452;2;;d6_lamps_on +427;1088;572;1;False; +427;1156;208;2;; +427;1268;224;2;False; +429;304;864 +429;384;704 +424;880;592 +424;896;592 +421;704;816;;;;2 +421;752;816;;;;2 +421;1104;896;3;;2; +423;48;336;; +423;80;336;; +423;96;320;; +423;224;496;; +423;272;480;; +423;384;448;; +423;384;496;; +423;416;448;; +423;416;480;; +423;528;608;; +423;560;576;; +423;560;640;; +423;592;608;; +252;136;472;d6_et_5 +252;296;824;d6_et_3 +252;400;432;d6_et_7 +252;400;848;d6_et_0 +252;568;448;d6_et_10 +252;576;176;d6_et_1 +252;616;600;d6_et_8 +252;720;568;d6_et_9 +252;888;616;d6_et_2 +252;888;856;d6_tiles_0_et +252;1000;736;d6_et_4 +252;1056;820;d6_et_6 +252;1176;344;d6_et_11 +252;1200;440;d6_et_12 +22;72;144;;;; +22;88;288;;;; +22;176;240;;;; +22;336;640;;;; +22;368;800;;;; +22;488;344;;;; +22;624;416;;;; +22;880;532;;;; +22;1008;528;;;; +22;1096;656;;;; +22;1176;280;;;; +22;1224;152;;;; +518;720;336;d6_facade;d6_facade_heart +341;544;592;;;;;; +341;544;608;;;;;; +341;544;624;;;;;; +341;560;480;;;;;; +341;560;512;;;;;; +341;560;592;;;;;; +341;560;624;;;;;; +341;576;480;;;;;; +341;576;512;;;;;; +341;576;592;;;;;; +341;576;608;;;;;; +341;576;624;;;;;; +341;672;576;;;;;; +341;672;592;;;;;; +341;688;608;;;;;; +341;704;608;;;;;; +341;720;608;;;;;; +341;736;608;;;;;; +341;736;896;;;;;; +341;752;608;;;;;; +341;752;896;;;;;; +341;768;608;;;;;; +341;784;576;;;;;; +341;784;592;;;;;; +341;1152;432;;;;;; +341;1152;512;;;;;; +341;1184;464;;;;;; +341;1184;480;;;;;; +341;1216;464;;;;;; +341;1216;480;;;;;; +341;1248;448;;;;;; +341;1248;464;;;;;; +341;1264;464;;;;;; +341;1264;512;;;;;; +253;72;160;1024;d6_door_7_hit;;;0;; +253;88;288;1024;d6_door_6_hit;;;0;; +253;320;568;1024;d6_door_4_hit;;;0;; +253;336;568;1024;d6_door_4_hit;;;0;; +253;456;656;1024;d6_door_23_hit;;32;0;; +253;496;344;1024;d6_door_9_hit;;;0;; +253;960;744;1024;d6_door_1_hit;;;0;; +339;512;464;;;;;; +339;528;448;;;;;; +339;528;480;;;;;; +339;544;432;;;;;; +339;544;464;;;;;; +339;544;496;;;;;; +339;592;432;;;;;; +339;592;464;;;;;; +339;592;496;;;;;; +339;608;448;;;;;; +339;608;480;;;;;; +339;624;464;;;;;; +342;600;560; +342;672;632; +342;728;384;3 +342;1176;432;1 +200;48;336;w;;heart_3;; +200;64;464;w;;arrow;; +200;304;208;w;;bomb_10;; +200;368;576;w;;heart_3;; +200;624;336;w;;bomb_10;; +200;728;200;;d6_instrument;instrument5;; +200;880;336;w;;bomb_10;; +200;1056;704;w;;arrow;; +200;1200;128;w;;heart_3;; +200;1200;192;w;;bomb_10;; +162;48;248;;-18;;8;;;;; +162;64;256;18;2;8;;;;;; +162;104;48;-18;2;8;48;;;;True;True +162;112;96;;18;;8;;;;; +162;144;96;;18;;8;;;;; +162;280;432;-18;2;8;;;;;; +162;288;448;;18;;8;;;;; +162;696;192;-18;2;8;;;;;; +162;768;192;18;2;8;;;;;; +162;1008;880;18;2;8;;;;;True;True +162;1040;448;18;2;8;;;;;; +162;1072;888;;-18;;8;;;;; +162;1096;448;-18;2;8;;;;;; +162;1096;768;-18;2;8;;;;;; +162;1096;816;-18;2;8;64;;;;True;True +162;1152;96;;18;;8;;;;; +162;1184;96;;18;;8;;;;; +162;1200;48;18;2;8;48;;;;True;True +162;1224;320;-18;2;8;8;;;;; +162;1264;392;;-18;;8;;;;; +168;-8;152;d6_door_7;(d6_door_7_hit&!d6_room_3_enter)|d6_horse_head_0; +168;136;280;d6_door_6;d6_door_6_hit; +168;152;552;d6_door_5;d6_button_0; +168;152;792;d6_door_10;d6_et_3; +168;320;544;d6_door_4;d6_door_4_hit; +168;328;320;d6_door_8;!d6_room_7_enter|d6_horse_head_1; +168;416;656;d6_door_23;d6_door_23_hit; +168;488;320;d6_door_9;(d6_door_9_hit&!d6_room_7_enter)|d6_horse_head_1; +168;504;776;d6_door_3;d6_et_0; +168;648;536;d6_door_14;d6_et_8|!d6_room_4_enter; +168;648;680;d6_door_15;(d6_et_8|!d6_room_4_enter)&(d6_et_9|!d6_room_5_enter); +168;728;472;d6_lamps_on;d6_lamp_0&d6_lamp_1; +168;808;280;d6_door_22;(!d6_enter_I|s6_instrument)&d6_facade_heart; +168;808;408;d6_door_21;d6_nightmareKeyhole&(!d6_room_10_enter|d6_facade_heart); +168;808;536;d6_door_16;d6_et_9|!d6_room_5_enter; +168;808;792;d6_door_0;d6_tiles_0_et|!d6_room_0_enter; +168;936;408;d6_door_11;d6_smasher; +168;936;736;d6_door_1;(d6_door_1_hit&!d6_room_1_enter)|d6_et_4; +168;1048;664;d6_door_12;d6_et_4|!d6_room_1_enter; +168;1056;792;d6_door_13;(d6_et_4|!d6_room_1_enter)&(d6_et_6|!d6_room_2_enter); +168;1128;280;d6_door_17;d6_et_11; +168;1128;408;d6_door_18;d6_et_11&(d6_et_12|!d6_room_9_enter); +168;1128;536;d6_door_19;d6_et_12|!d6_room_9_enter; +168;1304;152;d6_door_20;!d6_room_8_enter|d6_horse_head_2; +333;624;432;d6_keyhole_1 +333;992;432;d6_keyhole_2 +167;-56;120;d6_horse_head_0;0 +167;-32;120;d6_room_3_enter;0 +167;-8;120;d6_door_7_hit;0 +167;272;824;d6_et_3;0 +167;320;528;d6_door_4_hit; +167;360;344;d6_horse_head_1;0 +167;408;304;d6_room_7_enter;0 +167;488;664;d6_door_23_hit; +167;504;752;d6_et_0;0 +167;512;344;d6_door_9_hit;0 +167;560;680;d6_et_8;0 +167;584;680;d6_room_4_enter;0 +167;672;680;d6_room_5_enter;0 +167;696;680;d6_et_9;0 +167;720;440;d6_lamp_0;0 +167;736;440;d6_lamp_1;0 +167;776;408;d6_room_10_enter;0 +167;800;136;d6_enter_I; +167;816;936;d6_tiles_0_et;0 +167;840;936;d6_room_0_enter;0 +167;888;632;d6_et_2;0 +167;936;712;d6_door_1_hit;0 +167;1000;712;d6_et_4;0 +167;1024;820;d6_et_6;0 +167;1144;712;d6_room_1_enter;0 +167;1144;792;d6_room_2_enter;0 +167;1304;344;d6_et_11;0 +167;1304;440;d6_et_12;0 +167;1328;152;d6_room_8_enter;0 +167;1328;440;d6_room_9_enter;0 +167;1352;152;d6_horse_head_2;0 +302;176;720;;;;; +302;208;720;;;;; +302;224;336;;;;; +302;288;304;;;;; +302;288;720;;;;; +302;320;720;;;;; +302;368;448;;;;True; +302;368;832;;;;; +302;368;880;;;;; +302;432;448;;;;True; +302;432;832;;;;; +302;432;880;;;;; +302;512;576;;;;; +302;512;640;;;;; +302;512;816;;;;; +302;512;896;;;;; +302;560;368;;;;; +302;592;368;;;;; +302;608;576;;;;; +302;608;640;;;;; +302;624;816;;;;; +302;624;896;;;;; +302;672;176;;;;; +302;672;256;;;;; +302;672;560;;;;; +302;688;464;;;;; +302;688;480;;;;True;d6_lamp_0 +302;704;464;;;;; +302;704;480;;;;; +302;752;464;;;;; +302;752;480;;;;; +302;768;464;;;;; +302;768;480;;;;True;d6_lamp_1 +302;784;176;;;;; +302;784;256;;;;; +302;784;560;;;;; +302;832;384;;;;; +302;832;560;;;;; +302;832;640;;;;; +302;944;384;;;;; +302;944;560;;;;; +302;944;640;;;;; +315;48;32;;;;; +315;48;160;;;;; +315;48;416;;;;; +315;96;160;;;;; +315;128;416;;;;; +315;208;192;;;;; +315;208;416;;;;; +315;224;800;;;;; +315;240;192;;;;; +315;240;560;;;;; +315;256;416;;;;; +315;272;800;;;;; +315;368;544;;;;; +315;368;624;;;;; +315;384;320;;;;; +315;432;320;;;;; +315;448;544;;;;; +315;544;416;;;;; +315;592;416;;;;; +315;704;288;;;;; +315;704;416;;;;; +315;752;288;;;;; +315;752;416;;;;; +315;864;416;;;;; +315;864;800;;;;; +315;912;416;;;;; +315;912;800;;;;; +315;1008;160;;;;; +315;1008;800;;;;; +315;1056;800;;;;; +315;1088;160;;;;; +315;1088;544;;;;; +315;1168;32;;;;; +315;1200;160;;;;; +315;1248;32;;;;; +315;1248;160;;;;; +316;320;464;;;;; +316;320;496;;;;; +316;320;592;;;;; +316;400;704;;;;; +316;400;752;;;;; +316;1120;304;;;;; +316;1120;352;;;;; +317;384;368;;;;; +317;432;368;;;;; +317;656;192;;3;;; +317;656;240;;3;;; +317;704;272;;;;; +317;752;272;;;;; +317;800;192;;1;;; +317;800;240;;1;;; +317;1024;656;;;;; +317;1072;656;;;;; +318;16;320;;;;; +318;16;368;;;;; +318;176;592;;;;; +318;336;704;;;;; +318;336;752;;;;; +318;976;304;;;;; +318;976;352;;;;; +318;976;480;;;;; +170;72;144;d6_room_3_enter;1;;; +170;336;344;d6_room_7_enter;2;;; +170;480;344;d6_room_7_enter;;;; +170;600;544;d6_room_4_enter;3;;; +170;656;632;d6_room_5_enter;2;;; +170;728;272;d6_enter_I;1;;; +170;728;400;d6_room_10_enter;1;;; +170;816;848;d6_room_0_enter;2;;32; +170;888;800;d6_room_0_enter;3;;; +170;976;744;d6_room_1_enter;2;;; +170;1032;784;d6_room_1_enter;1;;; +170;1032;800;d6_room_2_enter;3;;; +170;1096;672;d6_room_1_enter;3;;; +170;1176;416;d6_room_9_enter;3;;; +170;1224;144;d6_room_8_enter;1;;; +170;1264;384;d6_room_9_enter;1;;;True +10;192;176;;; +10;208;176;;; +10;240;176;;; +10;256;176;;; +10;272;176;;; +10;304;304;;; +10;320;304;;; +10;336;304;;; +10;336;400;;; +10;352;304;;; +10;352;400;;; +10;368;304;;; +10;368;400;;; +10;384;304;;; +10;384;400;;; +10;400;304;;; +10;400;400;;; +10;416;304;;; +10;416;400;;; +10;432;304;;; +10;432;400;;; +10;448;304;;; +10;448;400;;; +10;464;304;;; +10;464;400;;; +10;480;304;;; +10;480;400;;; +10;496;304;;; +10;496;400;;; +10;512;304;;; +10;512;400;;; +10;528;400;;; +10;544;400;;; +10;560;400;;; +10;576;400;;; +10;704;576;;; +10;720;576;;; +10;736;576;;; +10;752;576;;; +10;992;464;;; +10;1008;464;;; +10;1024;240;;; +10;1040;240;;; +10;1056;240;;; +10;1072;240;;; +10;1072;592;;; +10;1088;240;;; +10;1104;240;;; +10;1264;336;;; +11;192;160;;; +11;192;672;;; +11;208;160;;; +11;224;160;;; +11;240;160;;; +11;256;160;;; +11;272;160;;; +11;288;160;;; +11;304;160;;; +11;304;384;;; +11;304;672;;; +11;320;384;;; +11;336;288;;; +11;336;384;;; +11;352;288;;; +11;352;384;;; +11;368;288;;; +11;368;384;;; +11;384;288;;; +11;384;384;;; +11;400;288;;; +11;400;384;;; +11;416;288;;; +11;416;384;;; +11;432;288;;; +11;432;384;;; +11;448;288;;; +11;448;384;;; +11;464;288;;; +11;464;384;;; +11;480;288;;; +11;480;384;;; +11;496;384;;; +11;512;384;;; +11;528;384;;; +11;544;384;;; +11;1024;368;;; +12;176;688;;; +12;176;704;;; +12;288;192;;; +12;288;208;;; +12;288;224;;; +12;288;240;;; +12;288;256;;; +12;288;272;;; +12;288;288;;; +12;288;400;;; +12;288;416;;; +12;288;688;;; +12;288;704;;; +12;496;272;;; +12;1040;560;;; +12;1040;576;;; +12;1088;608;;; +12;1088;624;;; +12;1088;640;;; +12;1104;432;;; +12;1104;464;;; +12;1104;480;;; +12;1104;496;;; +12;1104;512;;; +12;1232;304;;; +13;208;688;;; +13;208;704;;; +13;320;176;;; +13;320;192;;; +13;320;208;;; +13;320;224;;; +13;320;240;;; +13;320;256;;; +13;320;272;;; +13;320;416;;; +13;320;688;;; +13;320;704;;; +13;528;272;;; +13;528;288;;; +13;592;384;;; +13;1008;256;;; +13;1008;272;;; +13;1008;288;;; +13;1008;304;;; +13;1008;320;;; +13;1008;336;;; +13;1008;352;;; +13;1024;432;;; +13;1040;384;;; +25;48;240;;;; +25;64;240;;;; +25;64;256;;;; +25;64;272;;;; +25;96;48;;;; +25;96;64;;;; +25;96;80;;;; +25;96;96;;;; +25;112;96;;;; +25;144;96;;;; +25;160;160;;;; +25;160;176;;;; +25;176;192;;;; +25;176;656;;;; +25;192;192;;;; +25;192;656;;;; +25;208;192;;;; +25;208;656;;;; +25;208;736;;;; +25;224;672;;;; +25;224;688;;;; +25;224;704;;;; +25;224;736;;;; +25;240;192;;;; +25;256;192;;;; +25;272;192;;;; +25;272;208;;;; +25;272;224;;;; +25;272;240;;;; +25;272;256;;;; +25;272;272;;;; +25;272;288;;;; +25;272;304;;;; +25;272;368;;;; +25;272;384;;;; +25;272;400;;;; +25;272;416;;;; +25;272;432;;;; +25;272;448;;;; +25;272;672;;;; +25;272;688;;;; +25;272;704;;;; +25;272;736;;;; +25;288;368;;;; +25;288;448;;;; +25;288;656;;;; +25;288;736;;;; +25;304;320;;;; +25;304;368;;;; +25;304;656;;;; +25;320;320;;;; +25;320;368;;;; +25;320;448;;;; +25;320;656;;;; +25;336;320;;;; +25;336;368;;;; +25;336;416;;;; +25;336;432;;;; +25;336;448;;;; +25;336;672;;;; +25;336;688;;;; +25;336;704;;;; +25;352;320;;;; +25;352;368;;;; +25;352;416;;;; +25;368;320;;;; +25;368;368;;;; +25;368;416;;;; +25;384;320;;;; +25;384;368;;;; +25;384;416;;;; +25;400;320;;;; +25;400;368;;;; +25;400;416;;;; +25;416;320;;;; +25;416;368;;;; +25;416;416;;;; +25;432;320;;;; +25;432;368;;;; +25;432;416;;;; +25;448;320;;;; +25;448;368;;;; +25;448;416;;;; +25;464;320;;;; +25;464;368;;;; +25;464;416;;;; +25;480;320;;;; +25;480;368;;;; +25;480;416;;;; +25;496;320;;;; +25;496;368;;;; +25;496;416;;;; +25;512;320;;;; +25;512;368;;;; +25;512;416;;;; +25;528;320;;;; +25;528;368;;;; +25;528;416;;;; +25;544;288;;;; +25;544;304;;;; +25;544;320;;;; +25;544;352;;;; +25;544;368;;;; +25;544;416;;;; +25;560;416;;;; +25;576;416;;;; +25;592;416;;;; +25;608;384;;;; +25;608;400;;;; +25;608;416;;;; +25;688;192;;;; +25;688;208;;;; +25;688;224;;;; +25;704;224;;;; +25;752;224;;;; +25;768;192;;;; +25;768;208;;;; +25;768;224;;;; +25;992;480;;;; +25;1008;480;;;; +25;1008;864;;;; +25;1008;880;;;; +25;1008;896;;;; +25;1024;256;;;; +25;1024;272;;;; +25;1024;288;;;; +25;1024;304;;;; +25;1024;320;;;; +25;1024;336;;;; +25;1024;352;;;; +25;1024;480;;;; +25;1024;560;;;; +25;1024;576;;;; +25;1024;592;;;; +25;1024;608;;;; +25;1024;896;;;; +25;1040;256;;;; +25;1040;352;;;; +25;1040;432;;;; +25;1040;448;;;; +25;1040;464;;;; +25;1040;480;;;; +25;1040;608;;;; +25;1040;880;;;; +25;1040;896;;;; +25;1056;256;;;; +25;1056;352;;;; +25;1056;368;;;; +25;1056;384;;;; +25;1072;256;;;; +25;1072;608;;;; +25;1072;624;;;; +25;1072;640;;;; +25;1072;880;;;; +25;1088;256;;;; +25;1088;432;;;; +25;1088;448;;;; +25;1088;464;;;; +25;1088;480;;;; +25;1088;496;;;; +25;1088;512;;;; +25;1088;768;;;; +25;1088;784;;;; +25;1088;800;;;; +25;1088;816;;;; +25;1088;832;;;; +25;1088;848;;;; +25;1088;864;;;; +25;1088;880;;;; +25;1104;256;;;; +25;1152;96;;;; +25;1184;96;;;; +25;1200;48;;;; +25;1200;64;;;; +25;1200;80;;;; +25;1200;96;;;; +25;1216;304;;;; +25;1216;320;;;; +25;1216;336;;;; +25;1216;352;;;; +25;1232;352;;;; +25;1248;400;;;; +25;1248;416;;;; +25;1248;432;;;; +25;1264;352;;;; +25;1264;384;;;; +462;256;576 +499;1200;496;;; +499;1216;448;;; +505;888;464;d6_smasher +226;688;576;;;;;;;; +226;720;624;;;;;;;; +226;736;640;;;;;;;; +226;768;592;;;;;;;; +226;1008;448;0;;;;;;; +287;576;976;87 +165;48;208;d6_door_7_hit;d6Statue; +165;128;352;d6_door_6_hit;pot; +165;240;624;d6_door_4;d6Statue; +165;560;304;d6_door_9_hit;d6Statue; +165;912;736;d6_door_1_hit;d6Statue; +165;992;176;d6_nightmarekey;pot; +164;-32;152;d6_door_7;1;dialogBox;sound_secrete; +164;152;280;d6_door_6;1;dialogBox;d6_door_sound_0; +164;200;456;d6_button_0;1;dialogBox;d6_button_sound_0; +164;272;848;d6_et_3;1;dialogBox;sound_secrete; +164;330;464;d6_wall_1;1;spriteLight;doorLight.255.200.200.255.3; +164;336;536;d6_door_4_hit;1;dialogBox;sound_secrete; +164;400;880;d6_et_0;1;dialogBox;sound_secrete; +164;408;344;d6_door_9;1;dialogBox;sound_secrete; +164;416;672;d6_door_23_hit;1;dialogBox;sound_secrete; +164;456;344;d6_horse_head_1;1;dialogBox;sound_secrete; +164;568;856;d6_smasher;1;dungeonTeleporter;.d6teleport; +164;616;616;d6_et_8;1;dialogBox;sound_secrete; +164;728;496;d6_lamps_on;1;dialogBox;sound_secrete; +164;736;568;d6_et_9;1;dialogBox;sound_secrete; +164;776;136;d6_enter_I;1;dialogBox;d6_instrument_music; +164;864;936;d6_tiles_0_et;1;dialogBox;sound_secrete; +164;888;472;d6_smasher;1;dungeonTeleporter;.d6teleport; +164;936;760;d6_door_1;1;dialogBox;sound_secrete; +164;1024;744;d6_et_4;1;dialogBox;sound_secrete; +164;1040;820;d6_et_6;1;dialogBox;sound_secrete; +164;1200;368;d6_et_11;1;dialogBox;sound_secrete; +164;1208;112;d6_horse_head_2;1;dialogBox;sound_secrete; +164;1240;488;d6_door_19;0;dialogBox;d6_mboss_enter; +164;1240;508;d6_et_12;1;dialogBox;d6_mboss_killed; +430;1152;336 +430;1168;368 +430;1200;336 +166;144;448;d6_et_5;1;d6_etChest_0 +166;464;432;d6_et_7;1;d6_ladder_spawn +166;528;208;d6_et_1;1;d6_smallkey_0_spawn +166;528;464;d6_et_10;1;d6_smallkey_1_spawn +231;128;368;;bomb_1;;;; +231;128;384;;;;;; +231;144;352;;;;;; +231;144;368;;bomb_1;;;; +231;144;384;;;;;; +231;192;432;;heart;;;; +231;192;512;;arrow_1;;;; +231;208;432;;;;;; +231;224;432;;;;;; +231;224;448;;;;;; +231;256;448;;bomb_1;;;; +231;304;688;;fairy;;;; +231;384;336;;;;;; +231;384;352;;heart;;;; +231;432;336;;heart;;;; +231;432;352;;;;;; +231;832;896;;;;;; +231;848;592;;;;;; +231;848;608;;bomb_1;;;; +231;928;592;;heart;;;; +231;928;608;;;;;; +231;944;896;;;;;; +231;992;192;;;;;; +231;992;208;;;;;; +231;992;224;;;;;; +231;992;816;;heart;;;; +231;1008;176;;;;;; +231;1008;224;;;;;; +231;1008;384;;;;;; +231;1024;176;;;;;; +231;1024;224;;;;;; +231;1024;384;;heart;;;; +231;1040;176;;;;;; +231;1040;224;;;;;; +231;1056;176;;;;;; +231;1056;224;;;;;; +231;1072;176;;;;;; +231;1072;224;;;;;; +231;1072;560;;;;;; +231;1088;176;;;;;; +231;1088;224;;;;;; +231;1088;560;;bomb_1;;;; +231;1104;176;;;;;; +231;1104;192;;;;;; +231;1104;208;;;;;; +231;1104;224;;;;;; +231;1104;560;;arrow_1;;;; +231;1152;224;;;;;; +231;1152;304;;bomb_1;;;; +231;1184;192;;arrow_1;;;; +231;1200;224;;;;;; +231;1200;304;;;;;; +231;1216;256;;;;;; +231;1248;224;;;;;; +231;1264;192;;heart;;;; +249;336;416;0.6;0.1 +249;816;160;0.9;0.1 +175;1264;384;;;d6_mboss_leave +160;32;240; +160;128;96; +160;192;736; +160;224;192; +160;304;448; +160;304;736; +160;720;224; +160;736;224; +160;992;864; +160;1056;608; +160;1056;880; +160;1168;96; +160;1248;352; +160;1264;432; +161;888;272;;24;;;1 +460;832;560;d6_et_2 +460;832;640;d6_et_2 +460;944;560;d6_et_2 +460;944;640;d6_et_2 +246;32;240; +246;32;256; +246;32;272; +246;48;256; +246;48;272; +246;112;48; +246;112;64; +246;112;80; +246;128;48; +246;128;64; +246;128;80; +246;128;96; +246;144;48; +246;144;64; +246;144;80; +246;176;176; +246;176;672; +246;176;688; +246;176;704; +246;192;160; +246;192;176; +246;192;672; +246;192;688; +246;192;704; +246;192;720; +246;192;736; +246;208;160; +246;208;176; +246;208;672; +246;208;688; +246;208;704; +246;224;160; +246;224;176; +246;224;192; +246;240;160; +246;240;176; +246;256;160; +246;256;176; +246;272;160; +246;272;176; +246;288;160; +246;288;176; +246;288;192; +246;288;208; +246;288;224; +246;288;240; +246;288;256; +246;288;272; +246;288;288; +246;288;384; +246;288;400; +246;288;416; +246;288;432; +246;288;672; +246;288;688; +246;288;704; +246;304;160; +246;304;176; +246;304;192; +246;304;208; +246;304;224; +246;304;240; +246;304;256; +246;304;272; +246;304;288; +246;304;304; +246;304;384; +246;304;400; +246;304;416; +246;304;432; +246;304;448; +246;304;672; +246;304;688; +246;304;704; +246;304;720; +246;304;736; +246;320;160; +246;320;176; +246;320;192; +246;320;208; +246;320;224; +246;320;240; +246;320;256; +246;320;272; +246;320;288; +246;320;304; +246;320;384; +246;320;400; +246;320;416; +246;320;432; +246;320;672; +246;320;688; +246;320;704; +246;336;288; +246;336;304; +246;336;384; +246;336;400; +246;352;288; +246;352;304; +246;352;384; +246;352;400; +246;368;288; +246;368;304; +246;368;384; +246;368;400; +246;384;288; +246;384;304; +246;384;384; +246;384;400; +246;400;288; +246;400;304; +246;400;384; +246;400;400; +246;416;288; +246;416;304; +246;416;384; +246;416;400; +246;432;288; +246;432;304; +246;432;384; +246;432;400; +246;448;288; +246;448;304; +246;448;384; +246;448;400; +246;464;288; +246;464;304; +246;464;384; +246;464;400; +246;480;288; +246;480;304; +246;480;384; +246;480;400; +246;496;272; +246;496;288; +246;496;304; +246;496;384; +246;496;400; +246;512;176; +246;512;192; +246;512;208; +246;512;224; +246;512;240; +246;512;256; +246;512;272; +246;512;288; +246;512;304; +246;512;384; +246;512;400; +246;528;176; +246;528;192; +246;528;208; +246;528;224; +246;528;240; +246;528;256; +246;528;272; +246;528;288; +246;528;304; +246;528;384; +246;528;400; +246;544;384; +246;544;400; +246;560;384; +246;560;400; +246;576;384; +246;576;400; +246;592;384; +246;592;400; +246;704;192; +246;704;208; +246;720;176; +246;720;192; +246;720;208; +246;720;224; +246;736;176; +246;736;192; +246;736;208; +246;736;224; +246;752;192; +246;752;208; +246;992;176; +246;992;192; +246;992;208; +246;992;224; +246;992;240; +246;992;256; +246;992;272; +246;992;288; +246;992;304; +246;992;320; +246;992;336; +246;992;352; +246;992;368; +246;992;384; +246;992;400; +246;992;416; +246;992;432; +246;992;448; +246;992;464; +246;992;864; +246;992;880; +246;1008;176; +246;1008;192; +246;1008;208; +246;1008;224; +246;1008;240; +246;1008;256; +246;1008;272; +246;1008;288; +246;1008;304; +246;1008;320; +246;1008;336; +246;1008;352; +246;1008;368; +246;1008;384; +246;1008;432; +246;1008;448; +246;1008;464; +246;1024;176; +246;1024;192; +246;1024;208; +246;1024;224; +246;1024;240; +246;1024;368; +246;1024;384; +246;1024;432; +246;1024;448; +246;1024;464; +246;1040;176; +246;1040;192; +246;1040;208; +246;1040;224; +246;1040;240; +246;1040;368; +246;1040;384; +246;1040;560; +246;1040;576; +246;1040;592; +246;1056;176; +246;1056;192; +246;1056;208; +246;1056;224; +246;1056;240; +246;1056;560; +246;1056;576; +246;1056;592; +246;1056;880; +246;1056;896; +246;1072;176; +246;1072;192; +246;1072;208; +246;1072;224; +246;1072;240; +246;1072;560; +246;1072;576; +246;1072;592; +246;1072;896; +246;1088;176; +246;1088;192; +246;1088;208; +246;1088;224; +246;1088;240; +246;1088;560; +246;1088;576; +246;1088;592; +246;1088;608; +246;1088;624; +246;1088;640; +246;1088;896; +246;1104;176; +246;1104;192; +246;1104;208; +246;1104;224; +246;1104;240; +246;1104;432; +246;1104;448; +246;1104;464; +246;1104;480; +246;1104;496; +246;1104;512; +246;1104;560; +246;1104;576; +246;1104;592; +246;1104;608; +246;1104;624; +246;1104;640; +246;1104;768; +246;1104;784; +246;1104;800; +246;1104;816; +246;1104;832; +246;1104;848; +246;1104;864; +246;1104;880; +246;1152;48; +246;1152;64; +246;1152;80; +246;1168;48; +246;1168;64; +246;1168;80; +246;1168;96; +246;1184;48; +246;1184;64; +246;1184;80; +246;1232;304; +246;1232;320; +246;1232;336; +246;1248;304; +246;1248;320; +246;1248;336; +246;1248;352; +246;1264;304; +246;1264;320; +246;1264;336; +246;1264;400; +246;1264;416; +246;1264;432; +157;1008;496; +157;1008;512; +157;1008;528; +157;1008;544; +157;1008;560; +157;1008;576; +157;1008;592; +157;1008;608; +157;1008;624; +157;1024;496; +157;1024;624; +157;1040;272; +157;1040;288; +157;1040;304; +157;1040;320; +157;1040;336; +157;1040;496; +157;1040;624; +157;1056;272; +157;1056;288; +157;1056;304; +157;1056;320; +157;1056;336; +157;1056;448; +157;1056;464; +157;1056;480; +157;1056;496; +157;1056;624; +157;1072;272; +157;1072;288; +157;1072;320; +157;1072;336; +157;1072;352; +157;1072;368; +157;1072;384; +157;1072;400; +157;1072;416; +157;1072;432; +157;1072;448; +157;1072;464; +157;1072;480; +157;1072;496; +157;1088;272; +157;1088;288; +157;1088;304; +157;1088;320; +157;1088;336; +108;1008;496;;;;;; +108;1008;512;;;;;; +108;1008;528;;;;;; +108;1008;544;;;;;; +108;1008;560;;;;;; +108;1008;576;;;;;; +108;1008;592;;;;;; +108;1008;608;;;;;; +108;1008;624;;;;;; +108;1024;496;;;;;; +108;1024;624;;;;;; +108;1040;272;;;;;; +108;1040;288;;;;;; +108;1040;304;;;;;; +108;1040;320;;;;;; +108;1040;336;;;;;; +108;1040;496;;;;;; +108;1040;624;;;;;; +108;1056;272;;;;;; +108;1056;288;;;;;; +108;1056;304;;;;;; +108;1056;320;;;;;; +108;1056;336;;;;;; +108;1056;448;;;;;; +108;1056;464;;;;;; +108;1056;480;;;;;; +108;1056;496;;;;;; +108;1056;624;;;;;; +108;1072;272;;;;;; +108;1072;288;;;;;; +108;1072;304;;;;;; +108;1072;320;;;;;; +108;1072;336;;;;;; +108;1072;352;;;;;; +108;1072;368;;;;;; +108;1072;384;;;;;; +108;1072;400;;;;;; +108;1072;416;;;;;; +108;1072;432;;;;;; +108;1072;448;;;;;; +108;1072;464;;;;;; +108;1072;480;;;;;; +108;1072;496;;;;;; +108;1088;272;;;;;; +108;1088;288;;;;;; +108;1088;304;;;;;; +108;1088;320;;;;;; +108;1088;336;;;;;; diff --git a/bin/Data/Maps/dungeon6.map.data b/bin/Data/Maps/dungeon6.map.data new file mode 100644 index 0000000..304cf4c --- /dev/null +++ b/bin/Data/Maps/dungeon6.map.data @@ -0,0 +1,61 @@ +83 +59 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon6_2d_1.map b/bin/Data/Maps/dungeon6_2d_1.map new file mode 100644 index 0000000..333f525 --- /dev/null +++ b/bin/Data/Maps/dungeon6_2d_1.map @@ -0,0 +1,667 @@ +3 +0 +0 +tileset 2d.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,27,66,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,66,27,, +,27,66,107,76,107,76,107,76,113,113,113,113,113,76,113,113,113,113,66,27,, +,27,66,113,76,113,76,113,76,113,113,113,113,113,113,113,113,113,113,113,27,, +,27,66,113,76,113,76,113,76,27,27,27,27,113,27,113,27,27,113,76,27,, +,27,66,113,76,113,76,113,76,27,82,82,27,113,27,113,27,27,113,76,27,, +,27,113,113,113,113,113,113,76,27,82,82,27,113,113,113,113,113,113,76,27,, +,27,83,83,83,83,27,83,83,27,82,82,27,83,83,27,113,113,113,83,27,, +,27,27,27,27,27,27,27,27,27,82,82,27,27,27,27,27,27,27,27,27,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,0,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +105 +0;16;16;;; +0;16;32;;; +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;32;128;;; +0;48;16;;; +0;48;128;;; +0;64;16;;; +0;64;128;;; +0;80;16;;; +0;80;128;;; +0;96;16;;; +0;96;112;;; +0;112;16;;; +0;112;128;;; +0;128;16;;; +0;128;128;;; +0;144;16;;; +0;144;64;;; +0;144;80;;; +0;144;96;;; +0;144;112;;; +0;160;16;;; +0;160;64;;; +0;176;16;;; +0;176;64;;; +0;192;16;;; +0;192;64;;; +0;192;80;;; +0;192;96;;; +0;192;112;;; +0;208;16;;; +0;208;128;;; +0;224;16;;; +0;224;64;;; +0;224;80;;; +0;224;128;;; +0;240;16;;; +0;240;112;;; +0;256;16;;; +0;256;64;;; +0;256;80;;; +0;256;128;;; +0;272;16;;; +0;272;64;;; +0;272;80;;; +0;272;128;;; +0;288;16;;; +0;288;128;;; +0;304;128;;; +0;320;16;;; +0;320;32;;; +0;320;48;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +0;320;112;;; +286;40;152;;;; +153;32;8;;;d6_2d_1L;dungeon6.map;d6_2d_1L;3;;False +153;304;8;;;d6_2d_1R;dungeon6.map;d6_2d_1R;3;;False +258;32;16; +258;32;32; +258;32;48; +258;32;64; +258;32;80; +258;64;32; +258;64;48; +258;64;64; +258;64;80; +258;96;32; +258;96;48; +258;96;64; +258;96;80; +258;128;32; +258;128;48; +258;128;64; +258;128;80; +258;128;96; +258;224;32; +258;304;16; +258;304;32; +258;304;64; +258;304;80; +258;304;96; +259;304;64; +427;224;92;1;False; +427;256;52;3;; +484;272;112 +257;16;152 +287;64;152;32 +348;32;112 +348;48;112 +348;64;112 +348;80;112 +348;112;112 +348;128;112 +348;208;112 +348;224;112 +348;304;112 +306;48;48;;;;; +306;80;48;;;;; +306;112;48;;;;; diff --git a/bin/Data/Maps/dungeon6_2d_1.map.data b/bin/Data/Maps/dungeon6_2d_1.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/dungeon6_2d_1.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon6_2d_2.map b/bin/Data/Maps/dungeon6_2d_2.map new file mode 100644 index 0000000..ed05a29 --- /dev/null +++ b/bin/Data/Maps/dungeon6_2d_2.map @@ -0,0 +1,642 @@ +3 +1 +1 +tileset 2d.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,27,76,27,82,82,82,82,82,82,82,82,82,82,82,82,82,82,27,76,27,, +,27,76,27,27,27,27,27,27,27,82,82,27,27,27,27,27,82,27,76,27,, +,27,76,27,27,113,113,113,113,27,27,27,27,113,27,113,27,27,27,76,27,, +,27,76,109,107,109,113,113,109,107,109,109,107,109,113,113,109,107,109,76,27,, +,27,76,107,113,107,113,113,107,113,107,107,113,107,113,113,107,113,107,76,27,, +,27,76,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,76,27,, +,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,, +,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,0,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +80 +0;16;16;;; +0;16;32;;; +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;32;112;;; +0;48;16;;; +0;48;32;;; +0;48;48;;; +0;48;112;;; +0;64;48;;; +0;64;112;;; +0;80;32;;; +0;80;112;;; +0;96;32;;; +0;96;112;;; +0;112;32;;; +0;112;112;;; +0;128;32;;; +0;128;112;;; +0;144;48;;; +0;144;112;;; +0;160;48;;; +0;160;112;;; +0;176;48;;; +0;176;112;;; +0;192;48;;; +0;192;112;;; +0;208;32;;; +0;208;112;;; +0;224;48;;; +0;224;112;;; +0;240;32;;; +0;240;112;;; +0;256;48;;; +0;256;112;;; +0;272;48;;; +0;272;112;;; +0;288;16;;; +0;288;32;;; +0;288;48;;; +0;288;112;;; +0;304;112;;; +0;320;16;;; +0;320;32;;; +0;320;48;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +286;40;152;;;; +298;32;0;;;;;; +298;304;0;;;;;; +153;32;8;;;d6_2d_2L;dungeon6.map;d6_2d_2L;3;;False +153;304;8;;;d6_2d_2R;dungeon6.map;d6_2d_2R;3;;False +258;32;16; +258;32;32; +258;32;48; +258;32;64; +258;32;80; +258;32;96; +258;304;16; +258;304;32; +258;304;48; +258;304;64; +258;304;80; +258;304;96; +488;80;48 +488;96;48 +488;112;48 +488;128;48 +488;208;48 +488;224;64 +488;240;48 +257;16;152 +287;64;152;32 +306;64;80;;;;; +306;144;80;;;;; +306;192;80;;;;; +306;272;80;;;;; diff --git a/bin/Data/Maps/dungeon6_2d_2.map.data b/bin/Data/Maps/dungeon6_2d_2.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/dungeon6_2d_2.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon6_2d_3.map b/bin/Data/Maps/dungeon6_2d_3.map new file mode 100644 index 0000000..66c4599 --- /dev/null +++ b/bin/Data/Maps/dungeon6_2d_3.map @@ -0,0 +1,663 @@ +3 +1 +1 +tileset 2d.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,27,76,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,76,27,, +,27,76,113,113,109,107,109,113,113,113,113,109,107,109,27,27,113,113,76,27,, +,27,76,113,113,107,113,107,113,113,113,113,107,113,107,27,27,113,113,76,27,, +,27,27,27,76,113,113,113,113,76,27,27,76,113,113,113,113,113,113,76,27,, +,27,76,76,76,113,76,76,113,76,27,27,76,113,113,76,76,113,113,76,27,, +,27,76,113,113,113,113,113,113,76,27,27,76,113,113,113,113,113,113,76,27,, +,27,76,113,113,113,113,113,113,76,27,27,27,27,89,113,113,113,27,27,27,, +,27,27,27,27,27,27,27,27,27,27,82,82,27,27,27,27,27,27,82,82,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,0,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +101 +0;16;16;;; +0;16;32;;; +0;16;48;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;32;64;;; +0;32;128;;; +0;48;16;;; +0;48;64;;; +0;48;128;;; +0;64;16;;; +0;64;128;;; +0;80;16;;; +0;80;128;;; +0;96;16;;; +0;96;128;;; +0;112;16;;; +0;112;128;;; +0;128;16;;; +0;128;128;;; +0;144;16;;; +0;144;128;;; +0;160;16;;; +0;160;64;;; +0;160;80;;; +0;160;96;;; +0;160;112;;; +0;176;16;;; +0;176;64;;; +0;176;80;;; +0;176;96;;; +0;192;16;;; +0;192;112;;; +0;208;16;;; +0;208;112;;; +0;224;16;;; +0;224;128;;; +0;240;32;;; +0;240;48;;; +0;240;128;;; +0;256;32;;; +0;256;48;;; +0;256;128;;; +0;272;16;;; +0;272;128;;; +0;288;16;;; +0;288;112;;; +0;304;112;;; +0;320;16;;; +0;320;32;;; +0;320;48;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +286;40;152;;;; +153;32;8;;;d6_2d_3L;dungeon6.map;d6_2d_3L;3;;False +153;304;8;;;d6_2d_3R;dungeon6.map;d6_2d_3R;3;;False +245;88;152;six;False; +258;32;16; +258;32;32; +258;32;48; +258;32;80; +258;32;96; +258;32;112; +258;48;80; +258;64;64; +258;64;80; +258;96;80; +258;112;80; +258;144;64; +258;144;80; +258;144;96; +258;144;112; +258;192;64; +258;192;80; +258;192;96; +258;240;80; +258;256;80; +258;304;16; +258;304;32; +258;304;48; +258;304;64; +258;304;80; +258;304;96; +259;64;64; +259;96;80; +259;112;80; +259;144;64; +259;192;64; +259;240;80; +259;256;80; +487;88;40 +487;208;32 +484;80;112 +484;112;112 +484;240;112 +257;16;152 +287;64;152;32 +306;96;48;;;;; +306;208;48;;;;; diff --git a/bin/Data/Maps/dungeon6_2d_3.map.data b/bin/Data/Maps/dungeon6_2d_3.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/dungeon6_2d_3.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon7_1.map b/bin/Data/Maps/dungeon7_1.map new file mode 100644 index 0000000..0054e0a --- /dev/null +++ b/bin/Data/Maps/dungeon7_1.map @@ -0,0 +1,1666 @@ +3 +1 +1 +dungeon 7.png +42 +35 +3 +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,13,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,14,, +,16,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,17,, +,16,3,13,19,19,19,19,19,19,19,19,19,19,19,19,10,19,19,19,14,13,19,19,19,10,19,19,19,19,19,19,19,19,19,19,19,19,14,3,17,, +,16,3,16,56,56,56,56,56,56,56,56,56,40,56,56,56,56,56,56,17,16,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,17,3,17,, +,16,3,16,56,40,40,40,40,40,40,40,40,40,56,56,56,56,56,56,17,16,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,17,3,17,, +,16,3,16,56,40,56,56,56,56,56,56,56,40,56,56,56,56,56,56,17,16,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,17,3,17,, +,16,3,16,56,40,56,56,56,56,56,56,56,40,56,56,56,56,56,56,17,16,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,17,3,17,, +,16,3,16,56,40,56,24,18,18,18,18,23,40,24,18,18,23,40,24,12,15,18,18,18,18,18,18,18,18,18,23,56,56,24,18,23,56,17,3,17,, +,16,3,16,56,40,56,26,19,19,14,13,25,40,26,19,19,25,40,26,14,13,19,19,19,19,19,19,19,19,14,16,56,56,17,2,16,56,17,3,17,, +,16,3,16,56,40,56,40,56,56,26,25,52,40,52,52,52,52,40,52,26,25,56,56,56,56,56,56,56,56,26,25,56,56,26,19,25,56,17,3,17,, +,16,3,16,56,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,56,56,56,56,56,56,56,56,56,56,56,56,17,3,17,, +,16,3,16,56,40,56,40,56,56,24,23,46,40,46,46,46,46,40,46,24,23,56,56,56,40,56,56,56,56,24,23,56,56,56,56,56,56,17,3,17,, +,16,3,16,56,40,56,40,56,56,26,25,52,40,52,52,52,52,40,52,26,25,56,56,56,40,56,56,56,56,26,25,56,56,56,56,56,56,17,3,17,, +,16,3,16,56,40,56,40,56,56,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,56,56,56,1,56,56,17,3,17,, +,16,3,16,56,40,56,40,56,56,24,23,46,40,46,46,46,46,40,24,18,18,18,18,23,40,40,40,40,56,24,23,56,56,56,56,56,56,17,3,17,, +,16,3,16,56,40,56,24,18,18,12,15,23,40,24,18,18,23,40,17,3,3,3,3,16,40,40,24,18,18,12,15,18,18,18,18,18,18,12,3,17,, +,16,3,16,56,40,56,26,10,19,14,13,25,40,26,19,19,25,40,17,3,3,3,3,16,40,40,26,19,14,2,13,19,19,19,19,10,19,14,3,17,, +,16,3,16,56,40,56,40,40,40,17,16,13,19,14,56,56,56,40,17,3,3,13,6,25,40,40,40,40,17,2,16,56,56,56,56,56,56,17,3,17,, +,16,3,16,56,40,56,40,56,56,26,25,16,58,17,56,56,56,40,26,19,19,25,40,56,56,56,56,40,26,19,25,56,56,56,56,56,56,17,3,17,, +,16,3,16,56,40,40,40,56,56,56,56,16,58,17,56,56,56,40,40,40,40,40,40,56,3,3,56,40,40,40,40,3,3,56,56,56,56,17,3,17,, +,16,3,16,56,56,56,56,56,56,24,23,15,18,12,56,56,56,56,56,40,40,40,40,56,3,3,56,40,40,40,40,3,3,56,56,56,56,17,3,17,, +,16,3,16,40,40,40,40,40,40,17,16,56,56,56,56,56,56,56,56,24,18,23,40,56,56,56,56,40,24,18,23,56,3,56,56,56,56,17,3,17,, +,16,3,16,56,56,56,56,56,56,17,16,56,56,56,56,56,56,56,56,17,2,16,40,40,40,40,40,40,17,2,16,56,3,56,56,56,56,17,3,17,, +,16,3,16,56,56,56,56,56,56,17,15,18,18,18,18,18,18,18,18,12,2,15,18,23,56,56,24,18,12,2,15,23,3,56,24,39,34,12,3,17,, +,16,3,16,56,56,56,56,56,56,17,13,19,19,19,19,19,19,19,19,14,13,19,19,25,56,56,26,19,19,14,2,16,3,56,26,35,37,14,3,17,, +,16,3,16,3,3,3,3,3,3,26,25,56,56,56,56,56,56,56,56,26,25,56,56,56,56,56,56,56,56,26,19,25,3,56,56,56,56,17,3,17,, +,16,3,16,3,3,56,56,3,3,56,56,56,56,3,3,3,3,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,3,56,56,56,56,17,3,17,, +,16,3,16,3,3,56,56,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,56,3,3,56,3,3,3,3,3,3,56,56,56,56,17,3,17,, +,16,3,16,3,3,3,3,3,3,56,56,56,56,3,3,3,3,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,17,3,17,, +,16,3,15,18,18,18,18,18,18,18,23,56,56,28,11,11,27,56,56,24,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,12,3,17,, +,16,3,3,3,3,3,3,3,3,3,16,56,56,29,22,21,30,56,56,17,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,17,, +,15,18,18,18,18,18,18,18,18,23,15,18,18,8,4,5,9,18,18,12,24,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,12,, +,,,,,,,,,,16,,,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +,,,,,,,,,0,0,0,,,,,,,,,0,0,0,,,,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +1029 +0;16;32;;; +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;16;128;;; +0;16;144;;; +0;16;160;;; +0;16;176;;; +0;16;192;;; +0;16;208;;; +0;16;224;;; +0;16;240;;; +0;16;256;;; +0;16;272;;; +0;16;288;;; +0;16;304;;; +0;16;320;;; +0;16;336;;; +0;16;352;;; +0;16;368;;; +0;16;384;;; +0;16;400;;; +0;16;416;;; +0;16;432;;; +0;16;448;;; +0;16;464;;; +0;16;480;;; +0;16;496;;; +0;32;16;;; +0;32;512;;; +0;48;16;;; +0;48;512;;; +0;64;16;;; +0;64;512;;; +0;80;16;;; +0;80;512;;; +0;96;16;;; +0;96;512;;; +0;112;16;;; +0;112;128;;; +0;112;144;;; +0;112;256;;; +0;112;272;;; +0;112;512;;; +0;128;16;;; +0;128;128;;; +0;128;144;;; +0;128;256;;; +0;128;512;;; +0;144;16;;; +0;144;128;;; +0;144;144;;; +0;144;256;;; +0;144;272;;; +0;144;512;;; +0;160;16;;; +0;160;128;;; +0;160;160;;; +0;160;192;;; +0;160;208;;; +0;160;240;;; +0;160;288;;; +0;160;304;;; +0;160;336;;; +0;160;352;;; +0;160;368;;; +0;160;384;;; +0;160;400;;; +0;160;416;;; +0;160;512;;; +0;176;16;;; +0;176;128;;; +0;176;160;;; +0;176;192;;; +0;176;208;;; +0;176;240;;; +0;176;288;;; +0;176;304;;; +0;176;336;;; +0;176;352;;; +0;176;368;;; +0;176;416;;; +0;176;480;;; +0;176;496;;; +0;192;16;;; +0;192;128;;; +0;192;144;;; +0;192;256;;; +0;192;272;;; +0;192;384;;; +0;192;400;;; +0;192;512;;; +0;208;16;;; +0;208;384;;; +0;208;400;;; +0;208;512;;; +0;224;16;;; +0;224;128;;; +0;224;144;;; +0;224;256;;; +0;224;272;;; +0;224;384;;; +0;224;400;;; +0;224;512;;; +0;240;16;;; +0;240;128;;; +0;240;144;;; +0;240;256;;; +0;240;272;;; +0;240;384;;; +0;240;400;;; +0;248;528;;; +0;256;16;;; +0;256;128;;; +0;256;144;;; +0;256;256;;; +0;256;272;;; +0;256;384;;; +0;256;400;;; +0;272;16;;; +0;272;128;;; +0;272;144;;; +0;272;256;;; +0;272;272;;; +0;272;384;;; +0;272;400;;; +0;272;512;;; +0;288;16;;; +0;288;384;;; +0;288;400;;; +0;288;512;;; +0;304;16;;; +0;304;128;;; +0;304;144;;; +0;304;384;;; +0;304;400;;; +0;304;512;;; +0;320;16;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +0;320;112;;; +0;320;160;;; +0;320;192;;; +0;320;208;;; +0;320;352;;; +0;320;368;;; +0;320;416;;; +0;320;480;;; +0;320;496;;; +0;336;16;;; +0;336;64;;; +0;336;80;;; +0;336;96;;; +0;336;112;;; +0;336;160;;; +0;336;192;;; +0;336;208;;; +0;336;352;;; +0;336;416;;; +0;336;480;;; +0;352;16;;; +0;352;128;;; +0;352;144;;; +0;352;352;;; +0;352;368;;; +0;352;400;;; +0;352;512;;; +0;368;16;;; +0;368;128;;; +0;368;144;;; +0;368;384;;; +0;368;400;;; +0;368;512;;; +0;384;16;;; +0;384;128;;; +0;384;144;;; +0;384;384;;; +0;384;400;;; +0;384;512;;; +0;400;16;;; +0;400;128;;; +0;400;144;;; +0;400;512;;; +0;416;16;;; +0;416;128;;; +0;416;144;;; +0;416;512;;; +0;432;16;;; +0;432;128;;; +0;432;144;;; +0;432;256;;; +0;432;272;;; +0;432;384;;; +0;432;400;;; +0;432;512;;; +0;448;16;;; +0;448;128;;; +0;448;144;;; +0;448;256;;; +0;448;272;;; +0;448;384;;; +0;448;400;;; +0;448;512;;; +0;464;16;;; +0;464;128;;; +0;464;144;;; +0;464;256;;; +0;464;288;;; +0;464;304;;; +0;464;352;;; +0;464;368;;; +0;464;400;;; +0;464;512;;; +0;480;16;;; +0;480;128;;; +0;480;160;;; +0;480;192;;; +0;480;208;;; +0;480;240;;; +0;480;304;;; +0;480;352;;; +0;480;416;;; +0;480;512;;; +0;496;16;;; +0;496;128;;; +0;496;144;;; +0;496;160;;; +0;496;192;;; +0;496;208;;; +0;496;240;;; +0;496;288;;; +0;496;304;;; +0;496;352;;; +0;496;368;;; +0;496;416;;; +0;496;512;;; +0;512;16;;; +0;512;256;;; +0;512;272;;; +0;512;384;;; +0;512;400;;; +0;512;416;;; +0;512;512;;; +0;528;16;;; +0;528;256;;; +0;528;272;;; +0;528;512;;; +0;544;16;;; +0;544;128;;; +0;544;144;;; +0;544;160;;; +0;544;256;;; +0;544;272;;; +0;544;512;;; +0;560;16;;; +0;560;128;;; +0;560;160;;; +0;560;256;;; +0;560;272;;; +0;560;384;;; +0;560;400;;; +0;560;512;;; +0;576;16;;; +0;576;128;;; +0;576;144;;; +0;576;160;;; +0;576;256;;; +0;576;512;;; +0;592;16;;; +0;592;256;;; +0;592;272;;; +0;592;512;;; +0;608;16;;; +0;608;512;;; +0;624;16;;; +0;624;512;;; +0;640;32;;; +0;640;48;;; +0;640;64;;; +0;640;80;;; +0;640;96;;; +0;640;112;;; +0;640;128;;; +0;640;144;;; +0;640;160;;; +0;640;176;;; +0;640;192;;; +0;640;208;;; +0;640;224;;; +0;640;240;;; +0;640;256;;; +0;640;272;;; +0;640;288;;; +0;640;304;;; +0;640;320;;; +0;640;336;;; +0;640;352;;; +0;640;368;;; +0;640;384;;; +0;640;400;;; +0;640;416;;; +0;640;432;;; +0;640;448;;; +0;640;464;;; +0;640;480;;; +0;640;496;;; +1;232;496;;; +1;264;496;;; +3;240;512;;; +3;576;384;;; +3;576;400;;; +4;256;512;;; +4;592;384;;; +4;592;400;;; +2;256;48;;; +2;400;48;;; +199;96;304;stonebeak;seven;d7_beak;; +199;624;32;smallkeyChest;seven;d7_smallkey_2;; +28;304;240;;;; +28;304;256;;;; +28;304;272;;;; +28;304;288;;;; +28;304;304;;;; +28;320;240;;;; +28;320;304;;;; +28;336;240;;;; +28;336;304;;;; +28;352;240;;;; +28;352;288;;;; +28;352;304;;;; +28;368;240;;;; +28;384;240;;;; +28;384;256;;;; +28;384;272;;;; +28;384;288;;;; +289;608;32;d7_smallkey_2 +261;584;384;;d7_door_0;1; +261;584;400;1;d7_door_0;3;d7_door_0_keyhole +174;16;576;dungeon_7 +153;32;176;;;d7_hole_26;;;3;6;False +153;32;192;;;d7_hole_27;;;3;6;False +153;32;208;;;d7_hole_28;;;3;6;False +153;32;432;;;d7_hole_20;;;3;6;False +153;32;464;;;d7_hole_23;;;3;6;False +153;64;224;;;d7_hole_35;;;3;6;False +153;64;240;;;d7_hole_36;;;3;6;False +153;80;160;;;d7_hole_30;;;3;6;False +153;80;192;;;d7_hole_31;;;3;6;False +153;80;208;;;d7_hole_33;;;3;6;False +153;80;416;;;d7_hole_21;;;3;6;False +153;80;496;;;d7_hole_24;;;3;6;False +153;96;160;;;d7_hole_29;;;3;6;False +153;96;192;;;d7_hole_32;;;3;6;False +153;96;208;;;d7_hole_34;;;3;6;False +153;112;224;;;d7_hole_37;;;3;6;False +153;112;240;;;d7_hole_38;;;3;6;False +153;128;272;;;d7_0;dungeon7_2.map;d7_0;3;;False +153;128;432;;;d7_hole_22;;;3;6;False +153;128;464;;;d7_hole_25;;;3;6;False +153;144;176;;;d7_hole_39;;;3;6;False +153;144;192;;;d7_hole_40;;;3;6;False +153;144;208;;;d7_hole_41;;;3;6;False +153;208;192;;;d7_hole_14;;;3;6;False +153;208;208;;;d7_hole_15;;;3;6;False +153;224;432;;;d7_hole_16;;;3;6;False +153;240;432;;;d7_hole_17;;;3;6;False +153;248;520;;;d7;overworld.map;d7;1;; +153;256;48;;;d7_3;dungeon7_2.map;d7_3;3;;False +153;256;432;;;d7_hole_18;;;3;6;False +153;272;432;;;d7_hole_19;;;3;6;False +153;288;240;;;d7_hole_13;;;3;6;False +153;352;320;;;d7_hole_11;;;3;6;False +153;368;320;;;d7_hole_10;;;3;6;False +153;400;48;;;d7_2;dungeon7_2.map;d7_2;3;;False +153;400;240;;;d7_hole_5;;;3;6;False +153;400;288;;;d7_hole_9;;;3;6;False +153;416;240;;;d7_hole_4;;;3;6;False +153;416;288;;;d7_hole_8;;;3;6;False +153;432;240;;;d7_hole_3;;;3;6;False +153;432;288;;;d7_hole_7;;;3;6;False +153;448;208;;;d7_hole_0;;;3;6;False +153;448;224;;;d7_hole_1;;;3;6;False +153;448;240;;;d7_hole_2;;;3;6;False +153;448;304;;;d7_hole_6;;;3;6;False +153;576;272;;;d7_1;dungeon7_2.map;d7_1;3;;False +153;624;352;;;d7_hole_12;;;3;6;False +245;16;544;seven;; +335;64;352;d7_barrier;True; +335;80;80;d7_barrier;; +335;80;96;d7_barrier;; +335;80;112;d7_barrier;; +335;80;128;d7_barrier;; +335;80;144;d7_barrier;; +335;80;160;d7_barrier;; +335;80;176;d7_barrier;; +335;80;192;d7_barrier;; +335;80;208;d7_barrier;; +335;80;224;d7_barrier;; +335;80;240;d7_barrier;; +335;80;256;d7_barrier;; +335;80;272;d7_barrier;; +335;80;288;d7_barrier;; +335;80;304;d7_barrier;; +335;80;320;d7_barrier;; +335;80;352;d7_barrier;True; +335;96;80;d7_barrier;; +335;96;176;d7_barrier;; +335;96;320;d7_barrier;; +335;96;352;d7_barrier;True; +335;112;80;d7_barrier;; +335;112;160;d7_barrier;True; +335;112;176;d7_barrier;; +335;112;192;d7_barrier;True; +335;112;208;d7_barrier;True; +335;112;224;d7_barrier;True; +335;112;240;d7_barrier;True; +335;112;288;d7_barrier;True; +335;112;304;d7_barrier;; +335;112;320;d7_barrier;; +335;112;352;d7_barrier;True; +335;128;80;d7_barrier;; +335;128;176;d7_barrier;; +335;128;288;d7_barrier;True; +335;128;352;d7_barrier;True; +335;144;80;d7_barrier;; +335;144;176;d7_barrier;; +335;144;288;d7_barrier;True; +335;144;352;d7_barrier;True; +335;160;80;d7_barrier;; +335;160;176;d7_barrier;; +335;160;224;d7_barrier;True; +335;176;80;d7_barrier;; +335;176;176;d7_barrier;; +335;176;224;d7_barrier;True; +335;192;80;d7_barrier;; +335;192;176;d7_barrier;; +335;192;224;d7_barrier;True; +335;208;64;d7_barrier;True; +335;208;80;d7_barrier;True; +335;208;96;d7_barrier;True; +335;208;112;d7_barrier;True; +335;208;128;d7_barrier;True; +335;208;144;d7_barrier;True; +335;208;160;d7_barrier;True; +335;208;176;d7_barrier;; +335;208;192;d7_barrier;; +335;208;208;d7_barrier;; +335;208;224;d7_barrier;True; +335;208;240;d7_barrier;; +335;208;256;d7_barrier;; +335;208;272;d7_barrier;; +335;224;176;d7_barrier;; +335;224;224;d7_barrier;True; +335;240;176;d7_barrier;; +335;240;224;d7_barrier;True; +335;256;176;d7_barrier;; +335;256;224;d7_barrier;True; +335;272;176;d7_barrier;; +335;272;224;d7_barrier;True; +335;288;128;d7_barrier;True; +335;288;144;d7_barrier;True; +335;288;160;d7_barrier;True; +335;288;176;d7_barrier;; +335;288;192;d7_barrier;True; +335;288;208;d7_barrier;True; +335;288;224;d7_barrier;True; +335;288;240;d7_barrier;; +335;288;256;d7_barrier;; +335;288;272;d7_barrier;; +335;288;288;d7_barrier;; +335;288;304;d7_barrier;; +335;288;320;d7_barrier;; +335;304;176;d7_barrier;; +335;304;224;d7_barrier;True; +335;304;320;d7_barrier;; +335;320;176;d7_barrier;; +335;320;224;d7_barrier;True; +335;320;320;d7_barrier;; +335;320;336;d7_barrier;True; +335;336;176;d7_barrier;; +335;336;224;d7_barrier;True; +335;336;320;d7_barrier;; +335;336;336;d7_barrier;True; +335;352;176;d7_barrier;; +335;352;224;d7_barrier;True; +335;352;320;d7_barrier;; +335;352;336;d7_barrier;True; +335;368;176;d7_barrier;; +335;368;224;d7_barrier;True; +335;368;304;d7_barrier;; +335;368;320;d7_barrier;; +335;368;336;d7_barrier;True; +335;368;352;d7_barrier;True; +335;368;368;d7_barrier;True; +335;384;176;d7_barrier;; +335;384;224;d7_barrier;True; +335;384;368;d7_barrier;True; +335;400;176;d7_barrier;; +335;400;192;d7_barrier;; +335;400;208;d7_barrier;; +335;400;224;d7_barrier;; +335;400;240;d7_barrier;; +335;400;256;d7_barrier;; +335;400;272;d7_barrier;; +335;400;288;d7_barrier;True; +335;400;368;d7_barrier;True; +335;416;224;d7_barrier;True; +335;416;240;d7_barrier;True; +335;416;256;d7_barrier;True; +335;416;272;d7_barrier;True; +335;416;288;d7_barrier;True; +335;416;368;d7_barrier;; +335;432;224;d7_barrier;True; +335;432;240;d7_barrier;True; +335;432;288;d7_barrier;True; +335;432;368;d7_barrier;; +335;448;224;d7_barrier;True; +335;448;240;d7_barrier;True; +335;448;288;d7_barrier;True; +335;448;304;d7_barrier;True; +335;448;320;d7_barrier;True; +335;448;336;d7_barrier;; +335;448;352;d7_barrier;; +335;448;368;d7_barrier;; +335;464;224;d7_barrier;True; +335;464;320;d7_barrier;True; +335;464;336;d7_barrier;; +335;480;224;d7_barrier;True; +335;480;320;d7_barrier;True; +335;480;336;d7_barrier;; +335;496;224;d7_barrier;True; +335;496;320;d7_barrier;True; +335;496;336;d7_barrier;; +284;48;544;;;;150 +350;560;49;beak_d7_1 +53;208;464;;;;;; +53;208;480;;;;;; +53;288;464;;;;;; +53;288;480;;;;;; +330;560;224;d7_barrier +428;576;448 +475;64;64 +475;512;96 +470;400;96 +470;560;80 +474;256;304 +474;288;336 +474;544;320 +465;224;80 +465;304;96 +465;352;80 +465;448;80 +469;96;464 +427;256;370;2;; +427;592;60;1;False; +429;256;96 +436;416;208; +484;128;96 +442;368;208 +442;432;176 +442;544;432 +442;592;464 +421;352;416;;3;;2 +421;464;416;3;;;2 +421;512;288;;2;;2 +421;512;368;;2;2; +252;496;448;d7_et_0 +22;64;144;;;; +22;80;144;;;; +22;96;144;;;; +22;160;320;;;; +22;176;64;;;; +22;176;80;;;; +22;176;96;;;; +22;176;112;;;; +22;208;256;;;; +22;256;48;;;; +22;288;256;;;; +22;336;320;;;; +22;336;336;;;; +22;400;48;;;; +22;480;64;;;; +22;480;80;;;; +22;480;96;;;; +22;480;112;;;; +22;512;144;;;; +22;528;144;;;; +22;576;272;;;; +22;592;144;;;; +341;192;160;;;;;; +341;192;192;;;;;; +341;192;208;;;;;; +341;192;240;;;;;; +341;208;304;;;;;; +341;208;320;;;;;; +341;224;160;;;;;; +341;224;192;;;;;; +341;224;208;;;;;; +341;224;240;;;;;; +341;240;160;;;;;; +341;240;192;;;;;; +341;240;208;;;;;; +341;240;240;;;;;; +341;256;160;;;;;; +341;256;192;;;;;; +341;256;208;;;;;; +341;256;240;;;;;; +341;272;160;;;;;; +341;272;192;;;;;; +341;272;208;;;;;; +341;272;240;;;;;; +341;304;160;;;;;; +341;304;192;;;;;; +341;304;208;;;;;; +200;208;176;w;;heart_3;; +162;48;64;18;2;8;416;;;;;True +162;64;48;;18;544;8;;;;;True +162;64;488;;-18;96;8;;;;; +162;192;320;18;;;;;;;; +162;208;336;;-18;;;;;;; +162;224;304;-18;;;32;;;;;True +162;312;256;-18;2;8;48;;;;True;True +162;320;248;;-18;64;8;;;;True;True +162;320;304;;18;32;8;;;;True;True +162;384;256;18;2;8;32;;;;True;True +162;480;488;;-18;144;8;;;;; +162;616;64;-18;2;8;416;;;;; +168;232;552;d7_teleporter_0;d7_grim_creeper&!d7_collapsed; +168;264;552;d7_teleporter_1;d7_grim_creeper&d7_collapsed; +168;672;384;d7_door_0;d7_door_0_keyhole; +167;672;416;d7_et_0;0 +302;144;160;;;;; +302;144;240;;;;; +302;160;496;;;;; +302;192;368;;;;; +302;192;416;;;;; +302;192;496;;;;; +302;304;368;;;;; +302;304;416;;;;; +302;304;496;;;;; +302;336;496;;;;; +302;352;160;;;;; +302;384;304;;;;; +302;384;320;;;;; +302;384;336;;;;; +302;384;352;;;;; +302;400;304;;;;; +302;400;352;;;;; +302;416;304;;;;; +302;416;352;;;;; +302;432;304;;;;; +302;432;320;;;;; +302;432;336;;;;; +302;432;352;;;;; +302;464;160;;;;; +302;464;240;;;;; +302;496;400;;;;; +302;560;144;;;;; +307;80;48;;;;; +307;128;48;;;;; +307;224;48;;;;; +307;240;144;;;;; +307;256;144;;;;; +307;288;48;;;;; +307;368;48;;;;; +307;432;48;;;;; +307;448;272;;;;; +307;528;48;;;;; +307;576;48;;;;; +308;608;176;;;;; +308;608;224;;;;; +309;240;256;;;;; +309;256;256;;;;; +309;368;384;;;;; +309;448;384;;;;; +310;48;80;;;;; +310;48;176;;;;; +310;48;224;;;;; +310;48;304;;;;; +310;48;352;;;;; +25;48;48;;;; +25;48;64;;;; +25;48;80;;;; +25;48;96;;;; +25;48;112;;;; +25;48;128;;;; +25;48;144;;;; +25;48;160;;;; +25;48;176;;;; +25;48;192;;;; +25;48;208;;;; +25;48;224;;;; +25;48;240;;;; +25;48;256;;;; +25;48;272;;;; +25;48;288;;;; +25;48;304;;;; +25;48;320;;;; +25;48;336;;;; +25;48;352;;;; +25;48;368;;;; +25;48;384;;;; +25;48;400;;;; +25;48;416;;;; +25;48;432;;;; +25;48;448;;;; +25;48;464;;;; +25;48;480;;;; +25;64;48;;;; +25;64;480;;;; +25;80;48;;;; +25;80;480;;;; +25;96;48;;;; +25;96;480;;;; +25;112;48;;;; +25;112;480;;;; +25;128;48;;;; +25;128;480;;;; +25;144;48;;;; +25;144;480;;;; +25;160;48;;;; +25;160;480;;;; +25;176;48;;;; +25;192;48;;;; +25;192;288;;;; +25;192;304;;;; +25;192;320;;;; +25;192;336;;;; +25;208;48;;;; +25;208;288;;;; +25;208;336;;;; +25;224;48;;;; +25;224;288;;;; +25;224;304;;;; +25;224;320;;;; +25;224;336;;;; +25;240;48;;;; +25;272;48;;;; +25;288;48;;;; +25;304;48;;;; +25;320;48;;;; +25;336;48;;;; +25;352;48;;;; +25;352;480;;;; +25;368;48;;;; +25;368;480;;;; +25;384;48;;;; +25;384;480;;;; +25;400;480;;;; +25;416;48;;;; +25;416;480;;;; +25;432;48;;;; +25;432;480;;;; +25;448;48;;;; +25;448;480;;;; +25;464;48;;;; +25;464;480;;;; +25;480;48;;;; +25;480;480;;;; +25;496;48;;;; +25;496;480;;;; +25;512;48;;;; +25;512;480;;;; +25;528;48;;;; +25;528;480;;;; +25;544;48;;;; +25;544;480;;;; +25;560;48;;;; +25;560;480;;;; +25;576;48;;;; +25;576;480;;;; +25;592;48;;;; +25;592;480;;;; +25;608;48;;;; +25;608;64;;;; +25;608;80;;;; +25;608;96;;;; +25;608;112;;;; +25;608;128;;;; +25;608;144;;;; +25;608;160;;;; +25;608;176;;;; +25;608;192;;;; +25;608;208;;;; +25;608;224;;;; +25;608;240;;;; +25;608;256;;;; +25;608;272;;;; +25;608;288;;;; +25;608;304;;;; +25;608;320;;;; +25;608;336;;;; +25;608;352;;;; +25;608;368;;;; +25;608;384;;;; +25;608;400;;;; +25;608;416;;;; +25;608;432;;;; +25;608;448;;;; +25;608;464;;;; +25;608;480;;;; +223;352;464;0;;;;;;; +223;464;464;0;;;;;;; +223;464;496;0;;;;;;; +223;560;288;0;;;;;;; +223;560;304;0;;;;;;; +223;560;320;0;;;;;;; +223;560;336;0;;;;;;; +223;560;352;0;;;;;;; +223;560;368;0;;;;;;; +287;48;576;90 +165;272;320;;pot; +164;32;32;shellsFound;1;chest;ruby20..shell_26.;False +164;32;32;shellsFound;;chest;shellChest..shell_26.;False +164;248;456;d7_teleporter_1;1;dungeonTeleporter;dungeon7_4$map.d7_teleport; +164;248;456;d7_teleporter_0;1;dungeonTeleporter;dungeon7_3$map.d7_teleport; +166;528;432;d7_et_0;1;d7_et_0_init +166;528;448;d7_et_0_init;1;d7_spawn_key_0 +231;96;432;;bomb_1;;;; +231;96;448;;;;;; +231;112;432;;;;;; +231;112;448;;bomb_1;;;; +231;208;368;;;;;; +231;288;368;;;;;; +353;384;432 +353;384;448 +353;384;464 +353;400;432 +353;400;464 +353;416;432 +353;416;464 +353;432;432 +353;432;448 +353;432;464 +353;544;208 +353;544;224 +353;544;240 +353;560;208 +353;560;240 +353;576;208 +353;576;224 +353;576;240 +460;496;400;d7_et_0 +246;32;48; +246;32;64; +246;32;80; +246;32;96; +246;32;112; +246;32;128; +246;32;144; +246;32;160; +246;32;176; +246;32;192; +246;32;208; +246;32;224; +246;32;240; +246;32;256; +246;32;272; +246;32;288; +246;32;304; +246;32;320; +246;32;336; +246;32;352; +246;32;368; +246;32;384; +246;32;400; +246;32;416; +246;32;432; +246;32;448; +246;32;464; +246;32;480; +246;32;496; +246;48;32; +246;48;496; +246;64;32; +246;64;304; +246;64;320; +246;64;336; +246;64;496; +246;80;32; +246;80;304; +246;80;320; +246;80;336; +246;80;496; +246;96;32; +246;96;304; +246;96;320; +246;96;336; +246;96;496; +246;112;32; +246;112;304; +246;112;320; +246;112;336; +246;112;496; +246;128;32; +246;128;304; +246;128;320; +246;128;336; +246;128;496; +246;144;32; +246;144;304; +246;144;320; +246;144;336; +246;144;496; +246;160;32; +246;160;320; +246;176;32; +246;176;320; +246;192;32; +246;192;352; +246;208;32; +246;208;176; +246;208;192; +246;208;208; +246;208;224; +246;208;240; +246;208;256; +246;208;272; +246;208;352; +246;208;368; +246;224;32; +246;224;352; +246;224;368; +246;240;32; +246;240;288; +246;240;304; +246;240;320; +246;240;336; +246;240;352; +246;240;368; +246;256;32; +246;256;288; +246;256;304; +246;256;320; +246;256;336; +246;256;352; +246;256;368; +246;272;32; +246;272;288; +246;272;304; +246;272;320; +246;272;336; +246;272;352; +246;272;368; +246;288;32; +246;288;288; +246;288;304; +246;288;320; +246;288;336; +246;288;352; +246;288;368; +246;304;32; +246;304;320; +246;304;336; +246;304;352; +246;320;32; +246;320;320; +246;320;336; +246;336;32; +246;336;320; +246;336;336; +246;352;32; +246;352;320; +246;352;336; +246;368;32; +246;368;320; +246;368;336; +246;384;32; +246;400;32; +246;416;32; +246;432;32; +246;448;32; +246;464;32; +246;480;32; +246;480;496; +246;496;32; +246;496;496; +246;512;32; +246;512;496; +246;528;32; +246;528;496; +246;544;32; +246;544;496; +246;560;32; +246;560;496; +246;576;32; +246;576;496; +246;592;32; +246;592;496; +246;608;32; +246;608;496; +246;624;48; +246;624;64; +246;624;80; +246;624;96; +246;624;112; +246;624;128; +246;624;144; +246;624;160; +246;624;176; +246;624;192; +246;624;208; +246;624;224; +246;624;240; +246;624;288; +246;624;304; +246;624;320; +246;624;336; +246;624;368; +246;624;416; +246;624;432; +246;624;448; +246;624;464; +246;624;480; +246;624;496; +247;320;256; +247;320;272; +247;320;288; +247;336;256; +247;336;272; +247;336;288; +247;352;256; +247;352;272; +247;368;256; +247;368;272; +247;368;288; diff --git a/bin/Data/Maps/dungeon7_1.map.data b/bin/Data/Maps/dungeon7_1.map.data new file mode 100644 index 0000000..3c430f9 --- /dev/null +++ b/bin/Data/Maps/dungeon7_1.map.data @@ -0,0 +1,37 @@ +42 +35 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon7_2.map b/bin/Data/Maps/dungeon7_2.map new file mode 100644 index 0000000..a37e7a9 --- /dev/null +++ b/bin/Data/Maps/dungeon7_2.map @@ -0,0 +1,1385 @@ +3 +1 +1 +dungeon 7.png +42 +34 +3 +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,13,19,19,14,3,3,13,19,19,14,13,19,19,14,3,3,13,19,19,14,,,,,,,,,,,, +,,,,,,,,,,,16,0,0,17,3,3,16,0,0,17,16,56,56,17,3,3,16,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,16,0,0,26,19,20,25,0,0,17,16,56,56,26,20,19,25,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,16,0,0,0,0,0,0,0,0,17,16,56,56,56,40,56,56,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,16,0,0,0,0,0,0,0,0,17,16,56,56,56,56,56,56,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,16,0,0,0,0,0,0,0,0,17,16,56,56,56,56,56,56,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,16,0,0,0,0,0,0,0,0,17,16,56,56,56,56,56,56,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,15,18,23,0,24,18,18,23,0,17,16,56,56,24,18,18,18,18,18,12,,,,,,,,,,,, +,13,19,19,19,19,19,19,19,19,14,13,19,25,56,26,19,19,25,56,17,16,56,56,26,19,19,19,19,19,14,13,19,14,2,19,19,2,13,19,14,, +,16,56,56,56,31,31,56,56,56,17,16,56,56,56,50,56,56,56,56,17,16,56,56,56,56,56,56,56,56,17,16,56,26,14,3,3,13,25,56,17,, +,16,31,56,56,56,56,56,56,31,17,16,51,51,51,50,56,56,56,56,17,16,56,56,56,56,56,56,56,56,17,16,56,56,17,3,3,16,56,56,17,, +,16,31,56,56,31,31,56,56,31,17,16,56,41,56,56,56,56,56,56,17,16,56,56,56,56,56,56,56,50,33,32,3,56,26,6,6,25,56,56,17,, +,16,31,56,56,31,31,56,56,31,33,32,56,42,56,56,56,56,56,56,17,16,56,56,56,56,56,56,41,50,38,36,3,56,56,56,56,56,56,56,17,, +,16,56,56,31,56,56,31,56,56,38,36,56,56,56,56,56,56,56,56,26,25,40,40,40,40,40,56,47,50,17,16,56,56,56,56,56,56,56,56,17,, +,16,56,56,31,56,56,31,56,56,17,16,56,56,56,56,56,56,31,56,56,56,56,56,56,31,31,31,42,44,17,16,56,56,56,56,56,56,56,56,17,, +,15,18,18,18,39,34,18,18,18,12,15,18,59,18,18,18,18,18,18,18,23,56,56,24,18,18,23,56,56,17,15,18,18,18,18,18,18,23,40,17,, +,13,19,19,19,35,37,19,20,19,19,19,19,59,19,19,19,19,19,19,14,16,56,56,26,19,19,25,56,56,17,24,23,13,19,19,19,19,25,40,17,, +,16,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,17,16,56,56,40,31,31,31,56,56,17,17,16,16,40,40,3,3,3,56,17,, +,16,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,17,16,56,56,40,56,56,40,31,24,12,26,25,16,56,40,3,7,3,56,17,, +,16,56,56,56,24,23,56,56,56,56,56,56,56,56,56,56,56,56,56,17,16,31,31,40,56,56,56,56,17,3,3,3,16,40,40,3,3,3,56,17,, +,16,56,56,56,26,25,56,56,56,56,56,56,56,56,56,56,56,56,56,17,16,56,56,56,56,56,56,56,17,3,3,3,16,40,40,40,40,56,56,17,, +,16,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,17,16,56,56,56,56,56,56,56,17,3,3,3,16,40,40,40,40,40,31,17,, +,16,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,17,16,56,56,56,56,56,56,56,17,3,3,3,16,40,40,40,40,56,56,17,, +,15,18,18,18,18,23,56,24,18,18,18,18,59,18,23,56,56,24,18,12,15,18,18,23,56,24,18,18,12,3,3,3,15,18,18,23,40,24,18,12,, +,13,19,19,19,19,25,56,26,19,14,13,19,59,19,25,56,56,26,19,14,13,19,19,25,56,26,19,10,14,3,3,3,13,19,19,25,40,26,19,14,, +,16,56,56,56,31,56,56,56,56,17,16,56,56,56,56,51,51,3,3,17,16,56,49,3,3,3,50,56,17,3,3,3,16,56,56,56,56,56,56,17,, +,16,31,56,56,56,56,56,31,56,17,16,56,56,31,31,31,31,3,56,17,16,56,49,3,3,3,50,56,26,19,19,6,25,56,56,56,56,56,56,17,, +,16,56,3,56,56,56,56,56,56,26,25,56,56,56,56,48,56,3,3,17,16,56,49,3,3,3,50,56,56,40,40,56,56,56,56,56,56,56,56,17,, +,16,31,56,56,56,56,56,31,56,56,56,56,56,56,56,56,56,56,56,26,25,56,54,48,48,48,53,56,56,40,40,56,56,56,56,56,56,56,56,17,, +,16,56,56,56,56,56,56,56,56,24,23,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,24,23,56,56,56,56,56,56,56,56,17,, +,16,56,56,56,31,56,56,56,56,17,16,56,56,56,56,56,56,56,56,24,23,56,56,56,56,56,56,56,56,17,16,56,56,56,56,56,56,56,56,17,, +,15,18,18,18,18,18,18,18,18,12,15,18,18,18,18,18,18,18,18,12,15,18,18,18,18,18,18,18,18,12,15,18,18,18,18,18,18,18,18,12,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +57,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +751 +0;16;160;;; +0;16;176;;; +0;16;192;;; +0;16;208;;; +0;16;224;;; +0;16;240;;; +0;16;288;;; +0;16;304;;; +0;16;320;;; +0;16;336;;; +0;16;352;;; +0;16;368;;; +0;16;416;;; +0;16;432;;; +0;16;448;;; +0;16;464;;; +0;16;480;;; +0;16;496;;; +0;32;144;;; +0;32;256;;; +0;32;272;;; +0;32;384;;; +0;32;400;;; +0;32;512;;; +0;48;144;;; +0;48;256;;; +0;48;272;;; +0;48;384;;; +0;48;400;;; +0;48;512;;; +0;64;144;;; +0;64;256;;; +0;64;272;;; +0;64;384;;; +0;64;400;;; +0;64;512;;; +0;80;144;;; +0;80;320;;; +0;80;336;;; +0;80;384;;; +0;80;400;;; +0;80;512;;; +0;96;144;;; +0;96;320;;; +0;96;336;;; +0;96;384;;; +0;96;400;;; +0;96;512;;; +0;112;144;;; +0;112;256;;; +0;112;272;;; +0;112;512;;; +0;128;144;;; +0;128;256;;; +0;128;384;;; +0;128;400;;; +0;128;512;;; +0;144;144;;; +0;144;256;;; +0;144;272;;; +0;144;384;;; +0;144;400;;; +0;144;512;;; +0;160;160;;; +0;160;176;;; +0;160;192;;; +0;160;240;;; +0;160;272;;; +0;160;384;;; +0;160;416;;; +0;160;432;;; +0;160;448;;; +0;160;480;;; +0;160;496;;; +0;176;32;;; +0;176;48;;; +0;176;64;;; +0;176;80;;; +0;176;96;;; +0;176;112;;; +0;176;160;;; +0;176;176;;; +0;176;192;;; +0;176;240;;; +0;176;272;;; +0;176;384;;; +0;176;416;;; +0;176;432;;; +0;176;448;;; +0;176;480;;; +0;176;496;;; +0;192;16;;; +0;192;128;;; +0;192;144;;; +0;192;256;;; +0;192;272;;; +0;192;400;;; +0;192;512;;; +0;208;16;;; +0;208;128;;; +0;208;144;;; +0;208;512;;; +0;224;32;;; +0;224;48;;; +0;224;256;;; +0;224;272;;; +0;224;400;;; +0;224;512;;; +0;240;48;;; +0;240;128;;; +0;240;144;;; +0;240;256;;; +0;240;272;;; +0;240;384;;; +0;240;400;;; +0;240;512;;; +0;256;128;;; +0;256;144;;; +0;256;256;;; +0;256;272;;; +0;256;512;;; +0;272;32;;; +0;272;48;;; +0;272;128;;; +0;272;144;;; +0;272;256;;; +0;272;272;;; +0;272;512;;; +0;288;16;;; +0;288;128;;; +0;288;144;;; +0;288;256;;; +0;288;272;;; +0;288;384;;; +0;288;398;;; +0;288;512;;; +0;304;16;;; +0;304;256;;; +0;304;272;;; +0;304;384;;; +0;304;398;;; +0;304;512;;; +0;320;32;;; +0;320;48;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +0;320;112;;; +0;320;128;;; +0;320;144;;; +0;320;160;;; +0;320;176;;; +0;320;192;;; +0;320;208;;; +0;320;224;;; +0;320;256;;; +0;320;272;;; +0;320;288;;; +0;320;304;;; +0;320;320;;; +0;320;336;;; +0;320;352;;; +0;320;368;;; +0;320;416;;; +0;320;432;;; +0;320;448;;; +0;320;464;;; +0;320;496;;; +0;336;32;;; +0;336;48;;; +0;336;64;;; +0;336;80;;; +0;336;96;;; +0;336;112;;; +0;336;128;;; +0;336;144;;; +0;336;160;;; +0;336;176;;; +0;336;192;;; +0;336;208;;; +0;336;224;;; +0;336;256;;; +0;336;272;;; +0;336;288;;; +0;336;304;;; +0;336;320;;; +0;336;336;;; +0;336;352;;; +0;336;368;;; +0;336;416;;; +0;336;432;;; +0;336;448;;; +0;336;464;;; +0;336;496;;; +0;352;16;;; +0;352;384;;; +0;352;400;;; +0;352;512;;; +0;368;16;;; +0;368;384;;; +0;368;400;;; +0;368;512;;; +0;384;32;;; +0;384;48;;; +0;384;128;;; +0;384;144;;; +0;384;256;;; +0;384;272;;; +0;384;384;;; +0;384;400;;; +0;384;512;;; +0;400;128;;; +0;400;144;;; +0;400;256;;; +0;400;272;;; +0;400;512;;; +0;416;48;;; +0;416;128;;; +0;416;144;;; +0;416;256;;; +0;416;272;;; +0;416;512;;; +0;432;32;;; +0;432;48;;; +0;432;128;;; +0;432;144;;; +0;432;256;;; +0;432;272;;; +0;432;512;;; +0;448;16;;; +0;448;128;;; +0;448;144;;; +0;448;512;;; +0;464;16;;; +0;464;128;;; +0;464;144;;; +0;464;512;;; +0;480;32;;; +0;480;48;;; +0;480;64;;; +0;480;80;;; +0;480;96;;; +0;480;112;;; +0;480;160;;; +0;480;176;;; +0;480;224;;; +0;480;480;;; +0;480;496;;; +0;496;160;;; +0;496;176;;; +0;496;224;;; +0;496;240;;; +0;496;304;;; +0;496;480;;; +0;496;496;;; +0;512;144;;; +0;512;256;;; +0;512;304;;; +0;512;512;;; +0;528;152;;; +0;528;256;;; +0;528;288;;; +0;528;304;;; +0;528;512;;; +0;544;152;;; +0;544;256;;; +0;544;272;;; +0;544;512;;; +0;560;144;;; +0;560;256;;; +0;560;272;;; +0;560;512;;; +0;576;144;;; +0;576;256;;; +0;576;272;;; +0;576;512;;; +0;592;152;;; +0;592;256;;; +0;592;272;;; +0;592;512;;; +0;608;152;;; +0;608;256;;; +0;608;272;;; +0;608;384;;; +0;608;400;;; +0;608;512;;; +0;624;144;;; +0;624;384;;; +0;624;400;;; +0;624;512;;; +0;640;160;;; +0;640;176;;; +0;640;192;;; +0;640;208;;; +0;640;224;;; +0;640;240;;; +0;640;256;;; +0;640;272;;; +0;640;288;;; +0;640;304;;; +0;640;320;;; +0;640;336;;; +0;640;352;;; +0;640;368;;; +0;640;416;;; +0;640;432;;; +0;640;448;;; +0;640;464;;; +0;640;480;;; +0;640;496;;; +20;464;240;;; +14;432;464;;; +1;160;224;;; +1;176;224;;; +1;480;208;;; +1;496;208;;; +3;80;256;;; +3;80;272;;; +4;96;256;;; +4;96;272;;; +2;160;208;;; +2;176;208;;; +2;480;192;;; +2;496;192;;; +15;368;464;;; +458;192;64;;d7_2_cardboy_0 +458;208;480;;d7_2_cardboy_1 +458;240;496;1;d7_2_cardboy_1 +458;256;112;1;d7_2_cardboy_0 +458;272;480;2;d7_2_cardboy_1 +458;304;80;2;d7_2_cardboy_0 +199;544;304;mirrorShield;;d7_mirrorShield;; +289;80;472;d7_smallkey_1 +261;160;216;;d7_2_door_0;; +261;176;216;;d7_2_door_0;2; +270;208;272;;d7_2_wall_0;3;; +270;208;384;;d7_2_wall_1;1;; +153;128;272;;;d7_0;dungeon7_1.map;d7_0;3;;False +153;256;48;;;d7_3;dungeon7_1.map;d7_3;3;;False +153;400;48;;10;d7_2;dungeon7_1.map;d7_2;3;;False +153;400;352;;;d7_3_hole_0;;;3;6;False +153;400;368;;;d7_3_hole_1;;;3;6;False +153;416;336;;;d7_3_hole_2;;;3;6;False +153;416;352;;;d7_3_hole_3;;;3;6;False +153;416;368;;;d7_3_hole_4;;;3;6;False +153;432;336;;;d7_3_hole_5;;;3;6;False +153;432;352;;;d7_3_hole_6;;;3;6;False +153;432;368;;;d7_3_hole_7;;;3;6;False +153;448;336;;;d7_3_hole_8;;;3;6;False +153;448;352;;;d7_3_hole_9;;;3;6;False +153;448;368;;;d7_3_hole_10;;;3;6;False +153;480;336;;;d7_3_hole_11;;;3;6;False +153;480;352;;;d7_3_hole_12;;;3;6;False +153;480;368;;;d7_3_hole_13;;;3;6;False +153;592;304;;;d7_1;dungeon7_1.map;d7_1;2;1;False +245;16;544;seven;;1 +326;208;256;;d7_2_wall_0;1;; +326;208;400;;d7_2_wall_1;3;; +292;568;166;d7_ball +335;352;224;d7_barrier;True; +335;368;224;d7_barrier;True; +335;384;224;d7_barrier;True; +335;384;288;d7_barrier;True; +335;384;304;d7_barrier;True; +335;384;320;d7_barrier;True; +335;400;64;d7_barrier;True; +335;400;224;d7_barrier;True; +335;416;224;d7_barrier;True; +335;432;304;d7_barrier;True; +335;480;448;d7_barrier;; +335;480;464;d7_barrier;; +335;496;448;d7_barrier;; +335;496;464;d7_barrier;; +335;544;288;d7_barrier;True; +335;544;320;d7_barrier;True; +335;544;336;d7_barrier;True; +335;544;352;d7_barrier;True; +335;544;368;d7_barrier;True; +335;560;288;d7_barrier;True; +335;560;304;d7_barrier;True; +335;560;320;d7_barrier;True; +335;560;336;d7_barrier;True; +335;560;352;d7_barrier;True; +335;560;368;d7_barrier;True; +335;576;336;d7_barrier;True; +335;576;352;d7_barrier;True; +335;576;368;d7_barrier;True; +335;592;336;d7_barrier;True; +335;592;352;d7_barrier;True; +335;592;368;d7_barrier;True; +335;592;384;d7_barrier;True; +335;592;400;d7_barrier;True; +335;608;352;d7_barrier;True; +335;624;256;d7_barrier;; +335;624;272;d7_barrier;; +284;48;544;;;;150 +351;368;80;d7_horse; +351;448;80;d7_horse;3 +331;88;256 +350;192;401;beak_d7_3 +350;512;145;beak_d7_2 +293;256;192;d7_pillar_3 +293;256;336;d7_pillar_0 +293;400;192;d7_pillar_2 +293;400;336;d7_pillar_1 +260;624;150;0.13;d7_lever_open +53;512;384;;;;;; +53;512;400;;;;;; +330;400;432;d7_barrier +330;624;368;d7_barrier +428;112;160 +428;416;112 +428;592;480 +468;32;176;d7_2_tiles;;2 +468;32;192;d7_2_tiles;8;2 +468;32;208;d7_2_tiles;11;2 +468;64;224;d7_2_tiles;2;2 +468;64;240;d7_2_tiles;15;2 +468;80;160;d7_2_tiles;12;2 +468;80;192;d7_2_tiles;4;2 +468;80;208;d7_2_tiles;7;2 +468;96;160;d7_2_tiles;14;2 +468;96;192;d7_2_tiles;6;2 +468;96;208;d7_2_tiles;5;2 +468;112;224;d7_2_tiles;3;2 +468;112;240;d7_2_tiles;13;2 +468;144;176;d7_2_tiles;1;2 +468;144;192;d7_2_tiles;10;2 +468;144;208;d7_2_tiles;9;2 +427;48;284;1;False; +427;96;308;2;; +424;448;160 +423;64;320;; +423;128;352;; +423;240;352;; +423;288;320;; +423;368;176;; +423;368;352;; +423;384;496;; +423;416;208;; +423;448;448;; +252;56;168;d7_2_et_0 +22;112;392;;;; +22;128;272;;;; +22;256;48;;;; +22;400;48;;;; +22;448;400;;;; +341;32;432;;;;;; +341;32;464;;;;;; +341;80;416;;;;;; +341;80;496;;;;;; +341;128;432;;;;;; +341;128;464;;;;;; +341;208;192;;;;;; +341;208;208;;;;;; +341;224;432;;;;;; +341;240;432;;;;;; +341;256;432;;;;;; +341;272;432;;;;;; +341;288;240;;;;;; +341;352;320;;;;;; +341;368;320;;;;;; +341;400;240;;;;;; +341;400;288;;;;;; +341;416;240;;;;;; +341;416;288;;;;;; +341;432;240;;;;;; +341;432;288;;;;;; +341;448;208;;;;;; +341;448;224;;;;;; +341;448;240;;;;;; +341;448;304;;;;;; +341;624;352;;;;;; +339;32;176;;;;;; +339;32;192;;;;;; +339;32;208;;;;;; +339;64;224;;;;;; +339;64;240;;;;;; +339;80;160;;;;;; +339;80;192;;;;;; +339;80;208;;;;;; +339;96;160;;;;;; +339;96;192;;;;;; +339;96;208;;;;;; +339;112;224;;;;;; +339;112;240;;;;;; +339;144;176;;;;;; +339;144;192;;;;;; +339;144;208;;;;;; +342;88;240; +343;32;176;dungeon7_1.map;d7_hole_26 +343;32;192;dungeon7_1.map;d7_hole_27 +343;32;208;dungeon7_1.map;d7_hole_28 +343;32;432;dungeon7_1.map;d7_hole_20 +343;32;464;dungeon7_1.map;d7_hole_23 +343;64;224;dungeon7_1.map;d7_hole_35 +343;64;240;dungeon7_1.map;d7_hole_36 +343;80;160;dungeon7_1.map;d7_hole_29 +343;80;192;dungeon7_1.map;d7_hole_31 +343;80;208;dungeon7_1.map;d7_hole_33 +343;80;416;dungeon7_1.map;d7_hole_21 +343;80;496;dungeon7_1.map;d7_hole_24 +343;96;160;dungeon7_1.map;d7_hole_30 +343;96;192;dungeon7_1.map;d7_hole_32 +343;96;208;dungeon7_1.map;d7_hole_34 +343;112;224;dungeon7_1.map;d7_hole_37 +343;112;240;dungeon7_1.map;d7_hole_38 +343;128;432;dungeon7_1.map;d7_hole_22 +343;128;464;dungeon7_1.map;d7_hole_25 +343;144;176;dungeon7_1.map;d7_hole_39 +343;144;192;dungeon7_1.map;d7_hole_40 +343;144;208;dungeon7_1.map;d7_hole_41 +343;208;192;dungeon7_1.map;d7_hole_14 +343;208;208;dungeon7_1.map;d7_hole_15 +343;224;432;dungeon7_1.map;d7_hole_16 +343;240;432;dungeon7_1.map;d7_hole_17 +343;256;432;dungeon7_1.map;d7_hole_18 +343;272;432;dungeon7_1.map;d7_hole_19 +343;288;240;dungeon7_1.map;d7_hole_13 +343;352;320;dungeon7_1.map;d7_hole_11 +343;368;320;dungeon7_1.map;d7_hole_10 +343;400;240;dungeon7_1.map;d7_hole_5 +343;400;288;dungeon7_1.map;d7_hole_9 +343;416;240;dungeon7_1.map;d7_hole_4 +343;416;288;dungeon7_1.map;d7_hole_8 +343;432;240;dungeon7_1.map;d7_hole_3 +343;432;288;dungeon7_1.map;d7_hole_7 +343;448;208;dungeon7_1.map;d7_hole_0 +343;448;224;dungeon7_1.map;d7_hole_1 +343;448;240;dungeon7_1.map;d7_hole_2 +343;448;304;dungeon7_1.map;d7_hole_6 +343;624;352;dungeon7_1.map;d7_hole_12 +200;432;352;w;;heart_3;; +162;472;320;-18;2;8;64;;;;; +162;472;416;-18;2;8;;;;;; +162;480;432;;18;32;8;;;;True;True +162;528;320;18;;8;64;;;;True;True +162;528;416;18;2;8;;;;;; +162;552;176;-18;2;8;;;;;; +162;592;176;18;2;8;;;;;; +168;168;264;d7_2_door_0;d7_2_et_0; +168;256;544;d7_collapsed;d7_pillar_0&d7_pillar_1&d7_pillar_2&d7_pillar_3; +333;512;448;d7_2_keyhole +167;-8;184;d7_2_et_0; +302;32;416;;;;; +302;32;496;;;;; +302;144;416;;;;; +302;144;496;;;;; +302;192;160;;;;; +302;352;416;;;;; +302;544;144;;;;; +302;544;208;;;;; +302;592;144;;;;; +302;592;208;;;;; +307;64;144;;;;; +307;112;144;;;;; +307;192;272;;;;; +307;208;16;;;;; +307;224;272;;;;; +307;288;16;;;;; +307;368;16;;;;; +307;400;144;;;;; +307;448;16;;;;; +307;448;144;;;;; +307;544;272;;;;; +307;560;144;;;;; +307;560;400;;;;; +307;576;144;;;;; +307;592;272;;;;; +307;624;400;;;;; +308;640;176;;;;; +308;640;224;;;;; +309;192;256;;;;; +309;192;384;;;;; +309;224;256;;;;; +309;224;384;;;;; +309;368;384;;;;; +309;432;384;;;;; +310;16;304;;;;; +310;16;352;;;;; +310;496;176;;;;; +310;496;224;;;;; +170;512;200;d7_lever_open;;;; +227;512;192;1 +227;512;208;3 +10;192;176;;; +10;208;176;;; +10;224;176;;; +10;256;416;;; +10;272;416;;; +11;256;448;;; +11;384;464;;; +11;400;464;;; +11;416;464;;; +12;240;160;;; +12;240;176;;; +12;432;416;;; +12;432;432;;; +12;432;448;;; +12;464;192;;; +12;464;208;;; +12;464;224;;; +13;368;416;;; +13;368;432;;; +13;368;448;;; +25;416;384;;;; +25;416;400;;;; +25;432;384;;;; +25;432;400;;;; +25;448;384;;;; +25;464;304;;;; +25;464;320;;;; +25;464;336;;;; +25;464;352;;;; +25;464;368;;;; +25;464;384;;;; +25;464;400;;;; +25;464;416;;;; +25;464;432;;;; +25;480;240;;;; +25;480;256;;;; +25;480;272;;;; +25;480;288;;;; +25;480;304;;;; +25;480;432;;;; +25;496;432;;;; +25;528;160;;;; +25;528;320;;;; +25;528;336;;;; +25;528;352;;;; +25;528;368;;;; +25;528;384;;;; +25;528;400;;;; +25;528;416;;;; +25;528;432;;;; +25;544;160;;;; +25;544;176;;;; +25;544;192;;;; +25;544;384;;;; +25;544;400;;;; +25;560;384;;;; +25;560;400;;;; +25;576;384;;;; +25;576;400;;;; +25;592;160;;;; +25;592;176;;;; +25;592;192;;;; +25;608;160;;;; +497;72;432;d7_hinox;1 +223;192;288;;;;;;;; +223;192;304;;;;;;;; +223;192;320;;;;;;;; +223;192;336;;;;;;;; +223;192;352;;;;;;;; +223;192;368;;;;;;;; +223;192;448;0;;;;;;; +223;208;448;0;;;;;;; +223;224;288;;;;;;;; +223;224;304;;;;;;;; +223;224;320;;;;;;;; +223;224;336;;;;;;;; +223;224;352;;;;;;;; +223;224;368;;;;;;;; +223;224;416;;;;;;;; +223;224;448;0;;;;;;; +223;240;416;;;;;;;; +223;240;448;0;;;;;;; +223;272;240;;;;;;;; +223;272;448;0;;;;;;; +223;272;464;0;;;;;;; +223;288;160;;;;;;;; +223;288;176;;;;;;;; +223;288;192;;;;;;;; +223;288;208;;;;;;;; +223;288;224;;;;;;;; +223;288;464;0;;;;;;; +223;304;464;0;;;;;;; +223;352;240;14;;;;;;; +223;608;336;0;;;;;;; +223;624;336;0;;;;;;; +287;80;544;90 +164;-8;208;d7_2_et_0;1;dialogBox;sound_secrete; +164;448;400;d7_collapsed;1;door;..d7_4.dungeon7_4$map.d7_4.3.0.False; +164;448;400;d7_collapsed;0;door;..d7_4.dungeon7_3$map.d7_4.3.0.False; +166;48;448;d7_hinox;1;d7_spawn_key_1 +166;304;48;d7_2_cardboy_0;1;d7_spawn_chest_1 +166;304;432;d7_2_cardboy_1;1;d7_spawn_chest_2 +166;328;264;d7_collapsed;1;tower_collapse_sequence +166;464;48;d7_horse;1;d7_spawn_chest_0 +231;304;288;;;;;; +231;304;368;;;;;; +231;560;432;;;;;; +231;560;464;;;;;; +231;560;496;;;;;; +231;608;432;;;;;; +231;608;464;;;;;; +231;608;496;;;;;; +353;240;192 +353;240;288 +353;256;288 +353;272;160 +353;272;176 +353;272;288 +353;288;288 +353;288;304 +353;288;320 +353;304;176 +353;304;320 +353;352;304 +353;352;336 +353;352;352 +353;368;160 +353;384;160 +353;384;176 +353;416;160 +353;416;176 +353;416;368 +353;432;160 +353;432;368 +353;448;352 +353;448;368 +160;560;192; +160;576;192; +460;32;496;d7_hinox +460;144;496;d7_hinox +246;480;320; +246;480;336; +246;480;352; +246;480;368; +246;480;384; +246;480;400; +246;480;416; +246;496;320; +246;496;336; +246;496;352; +246;496;368; +246;496;384; +246;496;400; +246;496;416; +246;512;320; +246;512;336; +246;512;352; +246;512;368; +246;512;384; +246;512;416; +246;560;160; +246;560;176; +246;560;192; +246;576;160; +246;576;176; +246;576;192; diff --git a/bin/Data/Maps/dungeon7_2.map.data b/bin/Data/Maps/dungeon7_2.map.data new file mode 100644 index 0000000..69f447c --- /dev/null +++ b/bin/Data/Maps/dungeon7_2.map.data @@ -0,0 +1,36 @@ +42 +34 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon7_2d.map b/bin/Data/Maps/dungeon7_2d.map new file mode 100644 index 0000000..5ab5462 --- /dev/null +++ b/bin/Data/Maps/dungeon7_2d.map @@ -0,0 +1,653 @@ +3 +0 +0 +tileset 2d.png +10 +18 +3 +3,3,3,3,3,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3, +,,,,,,,,,, +,,,,,,,,,, +2,2,59,64,64,72,64,100,2,2, +2,2,2,67,77,111,105,2,2,2, +2,2,59,64,64,72,64,100,2,2, +2,2,59,64,64,72,64,100,2,2, +2,2,59,64,64,72,64,100,2,2, +2,2,59,64,64,72,64,100,2,2, +2,2,59,64,64,72,64,100,2,2, +2,2,2,103,113,111,102,2,2,2, +59,64,64,64,64,64,64,64,64,100, +2,67,77,77,77,77,77,77,105,2, +2,59,64,64,64,64,64,64,100,2, +,59,64,64,64,64,64,64,100,, +,59,64,64,64,64,64,64,100,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +67 +0;-16;0;;; +0;-16;16;;; +0;-16;32;;; +0;-16;48;;; +0;-16;64;;; +0;-16;80;;; +0;-16;96;;; +0;-16;112;;; +0;-16;128;;; +0;-16;144;;; +0;-16;160;;; +0;-16;176;;; +0;-16;192;;; +0;0;-16;;; +0;0;208;;; +0;16;-16;;; +0;16;208;;; +0;32;-16;;; +0;32;80;;; +0;32;208;;; +0;48;-16;;; +0;48;80;;; +0;48;208;;; +0;64;-16;;; +0;64;80;;; +0;64;208;;; +0;80;-16;;; +0;80;208;;; +0;96;-16;;; +0;96;80;;; +0;96;208;;; +0;112;-16;;; +0;112;80;;; +0;112;208;;; +0;128;-16;;; +0;128;208;;; +0;144;-16;;; +0;144;208;;; +0;160;0;;; +0;160;16;;; +0;160;32;;; +0;160;48;;; +0;160;64;;; +0;160;80;;; +0;160;96;;; +0;160;112;;; +0;160;128;;; +0;160;144;;; +0;160;160;;; +0;160;176;;; +0;160;192;;; +154;64;192;;;d7_2d;dungeon7_4.map;d7_2d +245;-32;224;seven;False;2 +258;80;80; +258;80;96; +258;80;112; +258;80;128; +258;80;144; +258;80;160; +258;80;176; +258;80;192; +259;80;80; +257;-32;256 +287;-64;256;32 +520;80;32;d7_nightmare +177;-64;224 +132;0;0 diff --git a/bin/Data/Maps/dungeon7_2d.map.data b/bin/Data/Maps/dungeon7_2d.map.data new file mode 100644 index 0000000..0a02162 --- /dev/null +++ b/bin/Data/Maps/dungeon7_2d.map.data @@ -0,0 +1,20 @@ +10 +18 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon7_3.map b/bin/Data/Maps/dungeon7_3.map new file mode 100644 index 0000000..b7f5f0d --- /dev/null +++ b/bin/Data/Maps/dungeon7_3.map @@ -0,0 +1,1197 @@ +3 +1 +1 +dungeon 7.png +42 +34 +3 +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,13,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,14,,,,,,,,,,,, +,,,,,,,,,,,16,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,16,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,16,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,16,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,16,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,16,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,15,18,18,18,18,23,40,24,18,18,18,18,18,18,18,18,18,18,18,12,,,,,,,,,,,, +,13,19,19,19,19,19,19,19,19,14,13,19,19,19,19,25,40,26,19,19,19,19,19,19,19,19,19,19,19,14,13,19,19,19,19,19,19,19,19,14,, +,16,56,56,56,56,56,56,56,56,17,16,47,47,47,47,49,40,50,47,47,47,47,47,47,47,47,47,47,47,17,16,3,3,56,56,56,56,3,3,17,, +,16,56,56,56,56,56,56,56,56,26,25,51,51,51,51,51,40,50,47,47,47,47,47,47,47,47,47,47,47,17,16,3,3,56,56,56,56,3,56,17,, +,16,56,56,56,56,40,40,40,40,40,40,40,40,40,40,40,40,50,47,47,47,47,47,47,47,47,47,47,47,17,16,3,3,56,56,56,56,3,3,17,, +,16,56,56,56,40,56,56,56,56,24,23,48,48,48,48,48,48,53,47,47,47,47,47,47,47,47,47,47,47,17,16,56,56,56,56,56,56,56,56,17,, +,16,56,56,56,40,56,56,56,56,17,16,41,41,41,41,41,41,47,47,47,47,47,47,47,47,47,47,47,47,17,16,56,56,56,56,56,56,56,56,17,, +,16,56,56,3,40,56,56,56,56,17,16,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,17,16,56,56,56,56,56,56,56,56,17,, +,15,18,23,56,24,18,39,34,18,12,16,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,17,15,18,18,18,18,18,18,39,34,12,, +,2,2,16,56,26,19,35,37,19,14,16,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,17,13,19,19,14,3,3,13,35,37,14,, +,13,19,25,56,56,56,56,56,56,17,16,42,42,42,42,42,42,42,47,47,47,47,42,42,42,42,42,42,42,17,16,56,56,17,3,3,16,56,56,17,, +,16,56,56,56,56,56,56,56,56,26,25,51,51,51,51,51,51,55,47,47,47,47,49,48,48,48,48,48,48,33,32,56,56,26,19,19,25,56,56,17,, +,16,56,56,56,56,56,56,56,56,40,40,40,40,40,40,40,40,50,47,47,47,47,49,56,51,56,56,56,51,38,36,56,56,56,56,56,56,56,56,17,, +,16,56,56,56,56,56,56,56,56,24,23,56,45,48,48,43,40,50,47,47,47,47,49,56,50,41,41,41,41,17,16,56,56,56,56,56,56,56,56,17,, +,16,56,56,56,56,56,56,56,56,17,16,56,50,41,41,49,40,50,47,47,47,47,49,56,41,47,47,47,47,17,16,56,56,56,56,56,56,56,56,17,, +,16,56,56,56,56,56,56,56,56,17,16,56,50,47,47,49,40,50,47,47,47,47,49,56,47,47,47,47,47,17,16,56,56,56,56,56,56,56,56,17,, +,15,18,18,18,18,18,18,18,18,12,16,56,24,18,18,23,40,24,18,18,18,18,23,56,24,18,18,18,18,12,15,18,18,18,18,18,18,18,18,12,, +,,,,,,,,,,,16,56,26,19,19,25,40,17,48,43,13,19,25,56,26,19,19,19,19,14,,,,,,,,,,,, +,,,,,,,,,,,16,56,56,56,56,56,40,17,56,49,16,56,56,56,56,56,40,56,7,17,,,,,,,,,,,, +,,,,,,,,,,,16,56,56,56,56,56,40,17,56,49,16,56,56,56,56,56,40,40,40,17,,,,,,,,,,,, +,,,,,,,,,,,16,56,56,56,56,56,56,26,6,14,16,56,56,56,56,56,56,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,16,56,56,56,56,56,56,56,56,33,32,56,56,56,56,56,56,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,16,56,56,56,56,56,56,56,56,38,36,56,56,56,56,56,56,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,16,56,56,56,56,56,56,56,56,17,16,56,56,56,56,56,56,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,15,18,18,18,18,18,18,18,18,12,15,18,18,18,18,18,18,18,18,12,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +563 +0;16;160;;; +0;16;176;;; +0;16;192;;; +0;16;208;;; +0;16;224;;; +0;16;240;;; +0;16;304;;; +0;16;320;;; +0;16;336;;; +0;16;352;;; +0;16;368;;; +0;32;144;;; +0;32;256;;; +0;32;288;;; +0;32;384;;; +0;48;144;;; +0;48;256;;; +0;48;272;;; +0;48;288;;; +0;48;384;;; +0;64;144;;; +0;64;384;;; +0;80;144;;; +0;80;256;;; +0;80;272;;; +0;80;384;;; +0;96;144;;; +0;96;256;;; +0;96;272;;; +0;96;384;;; +0;112;144;;; +0;112;384;;; +0;128;144;;; +0;128;384;;; +0;144;144;;; +0;144;256;;; +0;144;272;;; +0;144;384;;; +0;160;160;;; +0;160;176;;; +0;160;208;;; +0;160;224;;; +0;160;240;;; +0;160;256;;; +0;160;272;;; +0;160;288;;; +0;160;304;;; +0;160;336;;; +0;160;352;;; +0;160;368;;; +0;176;160;;; +0;176;176;;; +0;176;208;;; +0;176;224;;; +0;176;240;;; +0;176;256;;; +0;176;272;;; +0;176;288;;; +0;176;304;;; +0;176;336;;; +0;176;352;;; +0;176;368;;; +0;176;384;;; +0;176;400;;; +0;176;416;;; +0;176;432;;; +0;176;448;;; +0;176;464;;; +0;176;480;;; +0;176;496;;; +0;192;512;;; +0;208;384;;; +0;208;400;;; +0;208;512;;; +0;224;384;;; +0;224;400;;; +0;224;512;;; +0;240;384;;; +0;240;400;;; +0;240;512;;; +0;256;384;;; +0;256;400;;; +0;256;512;;; +0;272;512;;; +0;288;512;;; +0;304;512;;; +0;320;496;;; +0;336;496;;; +0;352;512;;; +0;368;512;;; +0;384;512;;; +0;400;384;;; +0;400;400;;; +0;400;512;;; +0;416;384;;; +0;416;400;;; +0;416;512;;; +0;432;384;;; +0;432;400;;; +0;432;512;;; +0;448;384;;; +0;448;400;;; +0;448;512;;; +0;464;384;;; +0;464;400;;; +0;464;512;;; +0;480;288;;; +0;480;336;;; +0;480;352;;; +0;480;368;;; +0;480;416;;; +0;480;432;;; +0;480;448;;; +0;480;464;;; +0;480;480;;; +0;480;496;;; +0;496;160;;; +0;496;176;;; +0;496;192;;; +0;496;208;;; +0;496;224;;; +0;496;240;;; +0;496;288;;; +0;496;336;;; +0;496;352;;; +0;496;368;;; +0;512;144;;; +0;512;256;;; +0;512;272;;; +0;512;384;;; +0;528;144;;; +0;528;256;;; +0;528;272;;; +0;528;384;;; +0;544;144;;; +0;544;256;;; +0;544;288;;; +0;544;304;;; +0;544;384;;; +0;560;144;;; +0;560;256;;; +0;560;304;;; +0;560;384;;; +0;576;144;;; +0;576;256;;; +0;576;304;;; +0;576;384;;; +0;592;144;;; +0;592;256;;; +0;592;288;;; +0;592;304;;; +0;592;384;;; +0;608;144;;; +0;608;384;;; +0;624;144;;; +0;624;384;;; +0;640;160;;; +0;640;176;;; +0;640;192;;; +0;640;208;;; +0;640;224;;; +0;640;240;;; +0;640;256;;; +0;640;272;;; +0;640;288;;; +0;640;304;;; +0;640;320;;; +0;640;336;;; +0;640;352;;; +0;640;368;;; +19;256;336;;; +19;320;400;;; +14;288;208;;; +1;320;480;;; +1;336;480;;; +1;480;320;;; +1;496;320;;; +3;112;256;;; +3;112;272;;; +3;608;256;;; +3;608;272;;; +4;128;256;;; +4;128;272;;; +4;624;256;;; +4;624;272;;; +2;480;304;;; +2;496;304;;; +16;288;304;;; +18;208;336;;; +289;568;208;d7_nkey +261;480;312;;d7_3_door_0;; +261;496;312;;d7_3_door_0;2; +261;616;256;;d7_3_door_1;1; +261;616;272;;d7_3_door_1;3; +153;464;416;;;d7_4;dungeon7_2.map;d7_4;;1;False +245;16;544;seven;;2 +335;80;208;d7_barrier;True; +335;80;224;d7_barrier;True; +335;80;240;d7_barrier;True; +335;96;192;d7_barrier;True; +335;112;192;d7_barrier;True; +335;128;192;d7_barrier;True; +335;144;192;d7_barrier;True; +335;160;192;d7_barrier;True; +335;160;320;d7_barrier;; +335;176;192;d7_barrier;True; +335;176;320;d7_barrier;; +335;192;192;d7_barrier;True; +335;192;320;d7_barrier;; +335;208;192;d7_barrier;True; +335;208;320;d7_barrier;; +335;224;192;d7_barrier;True; +335;224;320;d7_barrier;; +335;240;192;d7_barrier;True; +335;240;320;d7_barrier;; +335;256;192;d7_barrier;True; +335;256;320;d7_barrier;; +335;272;128;d7_barrier;True; +335;272;144;d7_barrier;True; +335;272;160;d7_barrier;True; +335;272;176;d7_barrier;True; +335;272;192;d7_barrier;True; +335;272;320;d7_barrier;; +335;272;336;d7_barrier;True; +335;272;352;d7_barrier;True; +335;272;368;d7_barrier;True; +335;272;384;d7_barrier;True; +335;272;400;d7_barrier;True; +335;272;416;d7_barrier;True; +335;272;432;d7_barrier;True; +335;432;416;d7_barrier;; +335;432;432;d7_barrier;; +335;448;432;d7_barrier;; +335;464;432;d7_barrier;; +284;48;544;;;;150 +330;512;176;d7_barrier +428;112;368 +428;224;496 +470;64;336 +470;80;192 +466;400;496 +466;448;464 +465;192;480 +465;240;448 +465;384;432 +477;272;480 +469;96;288 +469;96;320 +427;96;156;1;False; +427;508;224;;; +427;592;180;3;; +427;628;224;1;; +484;48;176 +22;64;264;;;; +22;120;264;;;; +22;168;192;;;; +22;616;264;;;; +341;192;160;;;;;; +341;192;224;;;;;; +341;192;240;;;;;; +341;192;256;;;;;; +341;192;272;;;;;; +341;192;288;;;;;; +341;208;160;;;;;; +341;208;224;;;;;; +341;208;240;;;;;; +341;208;256;;;;;; +341;208;272;;;;;; +341;208;288;;;;;; +341;224;160;;;;;; +341;224;224;;;;;; +341;224;240;;;;;; +341;224;256;;;;;; +341;224;272;;;;;; +341;224;288;;;;;; +341;224;352;;;;;; +341;224;368;;;;;; +341;240;160;;;;;; +341;240;224;;;;;; +341;240;240;;;;;; +341;240;256;;;;;; +341;240;272;;;;;; +341;240;288;;;;;; +341;240;352;;;;;; +341;240;368;;;;;; +341;256;224;;;;;; +341;256;240;;;;;; +341;256;256;;;;;; +341;256;272;;;;;; +341;256;288;;;;;; +341;272;224;;;;;; +341;272;240;;;;;; +341;272;256;;;;;; +341;272;272;;;;;; +341;272;288;;;;;; +341;288;224;;;;;; +341;288;240;;;;;; +341;288;256;;;;;; +341;288;272;;;;;; +341;288;288;;;;;; +341;304;160;;;;;; +341;304;176;;;;;; +341;304;192;;;;;; +341;304;208;;;;;; +341;304;224;;;;;; +341;304;240;;;;;; +341;304;256;;;;;; +341;304;272;;;;;; +341;304;288;;;;;; +341;304;304;;;;;; +341;304;320;;;;;; +341;304;336;;;;;; +341;304;352;;;;;; +341;304;368;;;;;; +341;320;160;;;;;; +341;320;176;;;;;; +341;320;192;;;;;; +341;320;208;;;;;; +341;320;224;;;;;; +341;320;240;;;;;; +341;320;256;;;;;; +341;320;272;;;;;; +341;320;288;;;;;; +341;320;304;;;;;; +341;320;320;;;;;; +341;320;336;;;;;; +341;320;352;;;;;; +341;320;368;;;;;; +341;336;160;;;;;; +341;336;176;;;;;; +341;336;192;;;;;; +341;336;208;;;;;; +341;336;224;;;;;; +341;336;240;;;;;; +341;336;256;;;;;; +341;336;272;;;;;; +341;336;288;;;;;; +341;336;304;;;;;; +341;336;320;;;;;; +341;336;336;;;;;; +341;336;352;;;;;; +341;336;368;;;;;; +341;352;160;;;;;; +341;352;176;;;;;; +341;352;192;;;;;; +341;352;208;;;;;; +341;352;224;;;;;; +341;352;240;;;;;; +341;352;256;;;;;; +341;352;272;;;;;; +341;352;288;;;;;; +341;352;304;;;;;; +341;352;320;;;;;; +341;352;336;;;;;; +341;352;352;;;;;; +341;352;368;;;;;; +341;368;160;;;;;; +341;368;176;;;;;; +341;368;192;;;;;; +341;368;208;;;;;; +341;368;224;;;;;; +341;368;240;;;;;; +341;368;256;;;;;; +341;368;272;;;;;; +341;368;288;;;;;; +341;384;160;;;;;; +341;384;176;;;;;; +341;384;192;;;;;; +341;384;208;;;;;; +341;384;224;;;;;; +341;384;240;;;;;; +341;384;256;;;;;; +341;384;272;;;;;; +341;384;288;;;;;; +341;400;160;;;;;; +341;400;176;;;;;; +341;400;192;;;;;; +341;400;208;;;;;; +341;400;224;;;;;; +341;400;240;;;;;; +341;400;256;;;;;; +341;400;272;;;;;; +341;400;288;;;;;; +341;400;352;;;;;; +341;400;368;;;;;; +341;416;160;;;;;; +341;416;176;;;;;; +341;416;192;;;;;; +341;416;208;;;;;; +341;416;224;;;;;; +341;416;240;;;;;; +341;416;256;;;;;; +341;416;272;;;;;; +341;416;288;;;;;; +341;416;336;;;;;; +341;416;352;;;;;; +341;416;368;;;;;; +341;432;160;;;;;; +341;432;176;;;;;; +341;432;192;;;;;; +341;432;208;;;;;; +341;432;224;;;;;; +341;432;240;;;;;; +341;432;256;;;;;; +341;432;272;;;;;; +341;432;288;;;;;; +341;432;336;;;;;; +341;432;352;;;;;; +341;432;368;;;;;; +341;448;160;;;;;; +341;448;176;;;;;; +341;448;192;;;;;; +341;448;208;;;;;; +341;448;224;;;;;; +341;448;240;;;;;; +341;448;256;;;;;; +341;448;272;;;;;; +341;448;288;;;;;; +341;448;336;;;;;; +341;448;352;;;;;; +341;448;368;;;;;; +341;464;160;;;;;; +341;464;176;;;;;; +341;464;192;;;;;; +341;464;208;;;;;; +341;464;224;;;;;; +341;464;240;;;;;; +341;464;256;;;;;; +341;464;272;;;;;; +341;464;288;;;;;; +341;464;336;;;;;; +341;464;352;;;;;; +341;464;368;;;;;; +343;400;352;dungeon7_2.map;d7_3_hole_0 +343;400;368;dungeon7_2.map;d7_3_hole_1 +343;416;336;dungeon7_2.map;d7_3_hole_2 +343;416;352;dungeon7_2.map;d7_3_hole_3 +343;416;368;dungeon7_2.map;d7_3_hole_4 +343;432;336;dungeon7_2.map;d7_3_hole_5 +343;432;352;dungeon7_2.map;d7_3_hole_6 +343;432;368;dungeon7_2.map;d7_3_hole_7 +343;448;336;dungeon7_2.map;d7_3_hole_8 +343;448;352;dungeon7_2.map;d7_3_hole_9 +343;448;368;dungeon7_2.map;d7_3_hole_10 +343;464;336;dungeon7_2.map;d7_3_hole_11 +343;464;352;dungeon7_2.map;d7_3_hole_12 +343;464;368;dungeon7_2.map;d7_3_hole_13 +200;400;448;w;;bomb_10;; +162;296;408;-18;2;8;40;;;;;True +168;488;392;d7_3_door_0;!d7_3_enter_0|d7_grim_creeper; +168;608;160;d7_spawn_chest_3_check;d7_3_stone_0_dir=2&d7_3_stone_1_dir=0; +168;664;264;d7_3_door_1;!d7_3_enter_0|d7_grim_creeper; +333;64;240;d7_3_keyhole +167;504;408;d7_3_enter_0;0 +167;664;160;d7_spawn_chest_3_check;0 +302;32;304;;;;; +302;144;288;;;;; +302;512;368;;;;; +302;544;224;;;;; +302;592;224;;;;; +302;624;368;;;;; +307;64;144;;;;; +307;112;144;;;;; +307;432;400;;;;; +307;464;400;;;;; +307;480;464;;1;;; +170;496;312;d7_3_enter_0;2;;; +170;616;256;d7_3_mstone_reset;3;;; +170;616;256;d7_3_mstone_reset;1;;;True +10;192;176;;; +10;192;304;;; +10;208;176;;; +10;208;304;;; +10;224;176;;; +10;224;304;;; +10;240;176;;; +10;240;304;;; +10;256;176;;; +10;256;304;;; +10;272;304;;; +10;400;320;;; +10;464;320;;; +11;192;208;;; +11;208;208;;; +11;224;208;;; +11;224;336;;; +11;240;208;;; +11;240;336;;; +11;256;208;;; +11;272;208;;; +11;304;400;;; +11;384;304;;; +11;400;304;;; +11;416;304;;; +11;432;304;;; +11;448;304;;; +11;464;304;;; +12;208;352;;; +12;208;368;;; +12;288;160;;; +12;288;176;;; +12;288;192;;; +12;288;320;;; +12;288;336;;; +12;288;352;;; +12;288;368;;; +12;400;336;;; +13;256;160;;; +13;256;352;;; +13;256;368;;; +13;320;416;;; +13;320;432;;; +13;368;304;;; +13;368;320;;; +13;368;336;;; +13;368;352;;; +13;368;368;;; +25;288;384;;;; +25;288;400;;;; +25;288;416;;;; +25;288;432;;;; +25;288;448;;;; +25;304;384;;;; +25;320;384;;;; +25;320;448;;;; +25;320;456;;;; +25;336;384;;;; +25;336;400;;;; +25;336;416;;;; +25;336;432;;;; +25;336;448;;;; +25;336;456;;;; +25;352;384;;;; +25;352;400;;;; +25;368;384;;;; +25;368;400;;;; +508;568;280;d7_grim_creeper +223;192;416;8;;;;;;; +223;544;192;;d7_3_stone_0;;;;;;d7_3_mstone_reset +223;592;192;;d7_3_stone_1;;;;;;d7_3_mstone_reset +287;80;544;90 +164;568;328;d7_grim_creeper;1;dungeonTeleporter;dungeon7_1$map.d7_teleport; +166;624;160;d7_spawn_chest_3_check;1;d7_spawn_chest_3_init +166;624;176;d7_spawn_chest_3_init;1;d7_spawn_chest_3 +231;32;160;;;;;; +231;32;240;;;;;; +231;144;160;;;;;; +231;144;240;;;;;; +353;32;320 +353;32;336 +353;48;304 +353;128;368 +353;144;336 +353;144;352 +353;144;368 +160;304;448; +246;304;400; +246;304;416; +246;304;432; +246;304;448; +246;320;400; +246;320;416; +246;320;432; diff --git a/bin/Data/Maps/dungeon7_3.map.data b/bin/Data/Maps/dungeon7_3.map.data new file mode 100644 index 0000000..69f447c --- /dev/null +++ b/bin/Data/Maps/dungeon7_3.map.data @@ -0,0 +1,36 @@ +42 +34 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon7_4.map b/bin/Data/Maps/dungeon7_4.map new file mode 100644 index 0000000..9dabace --- /dev/null +++ b/bin/Data/Maps/dungeon7_4.map @@ -0,0 +1,1215 @@ +3 +1 +1 +dungeon 7.png +42 +34 +3 +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,13,19,19,19,19,19,19,19,19,14,13,19,19,19,19,19,19,19,19,14,,,,,,,,,,,, +,,,,,,,,,,,16,56,56,56,56,56,56,56,56,17,16,56,56,56,56,56,56,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,16,56,56,56,56,56,56,56,56,33,32,56,56,56,56,56,56,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,16,56,56,56,56,56,56,56,56,38,36,56,56,56,56,56,56,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,16,56,56,56,56,56,56,56,56,17,16,56,56,56,56,56,56,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,16,56,56,56,56,56,56,56,56,17,16,56,56,56,56,56,56,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,15,18,18,23,56,56,24,18,18,12,16,56,24,18,18,18,18,23,56,17,,,,,,,,,,,, +,,,,,,,,,,,24,18,23,16,56,56,17,24,18,23,15,18,12,24,18,18,23,15,18,12,,,,,,,,,,,, +,13,19,19,19,19,19,19,19,19,14,26,19,25,16,56,56,17,26,19,25,13,19,14,26,19,19,25,13,19,14,13,19,19,19,19,19,19,19,19,14,, +,16,56,56,56,56,56,56,56,56,17,56,56,56,16,56,56,17,56,56,43,16,56,17,56,3,3,56,16,56,17,16,3,3,56,56,56,56,3,3,17,, +,16,56,56,56,56,56,56,56,56,26,19,6,19,25,56,56,17,56,56,49,16,56,17,3,3,3,3,16,56,17,16,3,3,56,56,56,56,3,56,17,, +,16,56,56,56,56,40,40,40,40,40,40,56,56,56,56,24,12,56,56,49,16,56,17,56,3,3,56,16,56,17,16,3,3,56,56,56,56,3,3,17,, +,16,56,56,56,40,56,56,56,56,24,18,23,31,56,56,17,56,56,56,49,16,56,26,19,6,6,19,25,56,17,16,56,56,56,56,56,56,56,56,17,, +,16,56,56,56,40,56,56,56,56,17,2,16,56,56,56,17,56,56,56,49,16,56,56,56,3,3,56,56,56,17,16,56,56,56,56,56,56,56,56,17,, +,16,56,56,56,40,56,56,56,56,17,2,16,56,56,24,12,56,56,56,49,15,18,18,23,3,3,24,18,18,12,16,56,56,56,56,56,56,56,56,17,, +,15,18,23,56,24,18,39,34,18,12,2,15,39,34,12,56,56,56,56,24,18,18,23,15,39,34,12,2,2,2,15,18,18,18,18,18,18,39,34,12,, +,2,2,16,56,26,19,35,37,19,14,2,13,35,37,14,56,56,56,56,26,19,10,25,13,35,37,19,19,19,14,13,19,19,14,3,3,13,35,37,14,, +,13,19,25,56,56,56,56,56,56,17,2,16,56,56,17,56,56,56,56,56,56,56,56,16,56,56,56,56,56,17,16,56,56,17,3,3,16,56,56,17,, +,16,56,56,56,56,56,56,56,56,26,19,25,56,56,17,56,56,56,56,56,56,56,56,16,56,56,56,56,56,33,32,56,56,26,19,19,25,56,56,17,, +,16,56,56,56,56,56,56,56,56,40,40,56,56,56,26,19,19,19,19,19,19,19,19,25,56,56,56,56,56,38,36,56,56,56,56,56,56,56,56,17,, +,16,56,56,56,56,56,56,56,56,24,23,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,17,16,56,56,56,56,56,56,56,56,17,, +,16,56,56,56,56,56,56,56,56,17,16,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,17,16,56,56,56,56,56,56,56,56,17,, +,16,56,56,56,56,56,56,56,56,17,16,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,17,16,56,56,56,56,56,56,56,56,17,, +,15,18,18,18,18,18,18,18,18,12,16,56,24,18,18,23,40,24,18,18,18,18,23,56,24,18,18,18,18,12,15,18,18,18,18,18,18,18,18,12,, +,,,,,,,,,,,16,56,26,19,19,25,40,17,48,43,13,19,25,56,26,19,19,19,19,14,,,,,,,,,,,, +,,,,,,,,,,,16,56,56,56,56,56,40,17,56,49,16,56,56,56,56,56,40,56,7,17,,,,,,,,,,,, +,,,,,,,,,,,16,56,56,56,56,56,40,17,56,49,16,56,56,56,56,56,40,40,40,17,,,,,,,,,,,, +,,,,,,,,,,,16,56,56,56,56,56,56,26,6,14,16,56,56,56,56,56,56,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,16,56,56,56,56,56,56,56,56,33,32,56,56,56,56,56,56,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,16,56,56,56,56,56,56,56,56,38,36,56,56,56,56,56,56,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,16,56,56,56,56,56,56,56,56,17,16,56,56,56,56,56,56,56,56,17,,,,,,,,,,,, +,,,,,,,,,,,15,18,18,18,18,18,18,18,18,12,15,18,18,18,18,18,18,18,18,12,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +581 +0;16;160;;; +0;16;176;;; +0;16;192;;; +0;16;208;;; +0;16;224;;; +0;16;240;;; +0;16;304;;; +0;16;320;;; +0;16;336;;; +0;16;352;;; +0;16;368;;; +0;32;144;;; +0;32;256;;; +0;32;288;;; +0;32;384;;; +0;48;144;;; +0;48;256;;; +0;48;272;;; +0;48;288;;; +0;48;384;;; +0;64;144;;; +0;64;384;;; +0;80;144;;; +0;80;256;;; +0;80;272;;; +0;80;384;;; +0;96;144;;; +0;96;256;;; +0;96;272;;; +0;96;384;;; +0;112;144;;; +0;112;384;;; +0;128;144;;; +0;128;384;;; +0;144;144;;; +0;144;256;;; +0;144;272;;; +0;144;384;;; +0;160;160;;; +0;160;208;;; +0;160;224;;; +0;160;240;;; +0;160;288;;; +0;160;304;;; +0;160;336;;; +0;160;352;;; +0;160;368;;; +0;176;32;;; +0;176;48;;; +0;176;64;;; +0;176;80;;; +0;176;96;;; +0;176;208;;; +0;176;304;;; +0;176;336;;; +0;176;352;;; +0;176;368;;; +0;176;384;;; +0;176;400;;; +0;176;416;;; +0;176;432;;; +0;176;448;;; +0;176;464;;; +0;176;480;;; +0;176;496;;; +0;192;16;;; +0;192;112;;; +0;192;144;;; +0;192;208;;; +0;192;224;;; +0;192;240;;; +0;192;288;;; +0;192;304;;; +0;192;512;;; +0;208;16;;; +0;208;112;;; +0;208;144;;; +0;208;384;;; +0;208;400;;; +0;208;512;;; +0;224;16;;; +0;224;112;;; +0;224;128;;; +0;224;144;;; +0;224;384;;; +0;224;400;;; +0;224;512;;; +0;240;16;;; +0;240;384;;; +0;240;400;;; +0;240;512;;; +0;256;16;;; +0;256;384;;; +0;256;400;;; +0;256;512;;; +0;272;16;;; +0;272;112;;; +0;272;128;;; +0;272;144;;; +0;272;512;;; +0;288;16;;; +0;288;112;;; +0;288;144;;; +0;288;512;;; +0;304;16;;; +0;304;112;;; +0;304;512;;; +0;320;32;;; +0;320;80;;; +0;320;96;;; +0;320;144;;; +0;320;256;;; +0;320;272;;; +0;320;496;;; +0;336;32;;; +0;336;80;;; +0;336;96;;; +0;336;256;;; +0;336;272;;; +0;336;496;;; +0;352;16;;; +0;352;256;;; +0;352;512;;; +0;368;16;;; +0;368;112;;; +0;368;160;;; +0;368;256;;; +0;368;272;;; +0;368;512;;; +0;384;16;;; +0;384;112;;; +0;384;144;;; +0;384;512;;; +0;400;16;;; +0;400;112;;; +0;400;144;;; +0;400;384;;; +0;400;400;;; +0;400;512;;; +0;416;16;;; +0;416;112;;; +0;416;144;;; +0;416;384;;; +0;416;400;;; +0;416;512;;; +0;432;16;;; +0;432;112;;; +0;432;144;;; +0;432;240;;; +0;432;272;;; +0;432;384;;; +0;432;400;;; +0;432;512;;; +0;448;16;;; +0;448;112;;; +0;448;160;;; +0;448;240;;; +0;448;272;;; +0;448;384;;; +0;448;400;;; +0;448;512;;; +0;464;16;;; +0;464;240;;; +0;464;272;;; +0;464;384;;; +0;464;400;;; +0;464;512;;; +0;480;32;;; +0;480;48;;; +0;480;64;;; +0;480;80;;; +0;480;96;;; +0;480;160;;; +0;480;176;;; +0;480;192;;; +0;480;208;;; +0;480;224;;; +0;480;240;;; +0;480;288;;; +0;480;336;;; +0;480;352;;; +0;480;368;;; +0;480;416;;; +0;480;432;;; +0;480;448;;; +0;480;464;;; +0;480;480;;; +0;480;496;;; +0;496;160;;; +0;496;176;;; +0;496;192;;; +0;496;208;;; +0;496;224;;; +0;496;240;;; +0;496;288;;; +0;496;336;;; +0;496;352;;; +0;496;368;;; +0;512;144;;; +0;512;256;;; +0;512;272;;; +0;512;384;;; +0;528;144;;; +0;528;256;;; +0;528;272;;; +0;528;384;;; +0;544;144;;; +0;544;256;;; +0;544;288;;; +0;544;304;;; +0;544;384;;; +0;560;144;;; +0;560;256;;; +0;560;304;;; +0;560;384;;; +0;576;144;;; +0;576;256;;; +0;576;304;;; +0;576;384;;; +0;592;144;;; +0;592;256;;; +0;592;288;;; +0;592;304;;; +0;592;384;;; +0;608;144;;; +0;608;384;;; +0;624;144;;; +0;624;384;;; +0;640;160;;; +0;640;176;;; +0;640;192;;; +0;640;208;;; +0;640;224;;; +0;640;240;;; +0;640;288;;; +0;640;304;;; +0;640;320;;; +0;640;336;;; +0;640;352;;; +0;640;368;;; +19;320;160;;; +19;320;400;;; +1;320;64;;; +1;320;480;;; +1;336;64;;; +1;336;480;;; +1;480;320;;; +1;496;320;;; +3;112;256;;; +3;112;272;;; +3;208;256;;; +3;208;272;;; +3;400;256;;; +3;400;272;;; +3;608;256;;; +3;608;272;;; +4;128;256;;; +4;128;272;;; +4;416;256;;; +4;416;272;;; +4;624;256;;; +4;624;272;;; +2;320;48;;; +2;336;48;;; +2;480;304;;; +2;496;304;;; +289;568;208;d7_nkey +261;216;256;2;d7_ndoor_key;1; +261;216;272;3;d7_ndoor_key;3;d7_ndoor_key +261;408;256;2;d7_door_1;1; +261;408;272;2;d7_door_1;3; +261;480;312;;d7_3_door_0;; +261;496;312;;d7_3_door_0;2; +261;616;256;;d7_3_door_1;1; +261;616;272;;d7_3_door_1;3; +153;352;272;;;d7_2d;dungeon7_2d.map;d7_2d;3;;False +153;464;416;;;d7_4;dungeon7_2.map;d7_4;;1;False +245;16;544;seven;;2 +335;80;208;d7_barrier;True; +335;80;224;d7_barrier;True; +335;80;240;d7_barrier;True; +335;96;192;d7_barrier;True; +335;112;192;d7_barrier;True; +335;128;192;d7_barrier;True; +335;144;192;d7_barrier;True; +335;160;192;d7_barrier;True; +335;160;320;d7_barrier;; +335;176;192;d7_barrier;True; +335;176;320;d7_barrier;; +335;272;384;d7_barrier;True; +335;272;400;d7_barrier;True; +335;272;416;d7_barrier;True; +335;272;432;d7_barrier;True; +335;432;416;d7_barrier;; +335;432;432;d7_barrier;; +335;448;432;d7_barrier;; +335;464;432;d7_barrier;; +284;48;544;;;;150 +351;384;48;d7_4_horse_head;3 +351;416;32;d7_4_horse_head; +349;368;32;2 +349;368;48;1 +349;368;64;1 +349;368;80;1 +349;368;96;1 +349;384;32;2 +349;384;96; +349;400;32;2 +349;400;96; +349;416;32;2 +349;416;96; +349;432;32;2 +349;432;96; +349;448;32;3 +349;448;48;3 +349;448;64;3 +349;448;80;3 +349;448;96; +53;384;160;;;;;; +53;384;192;;;;;; +53;432;160;;;;;; +53;432;192;;;;;; +330;512;176;d7_barrier +428;112;368 +428;224;496 +470;64;336 +470;80;192 +470;240;64 +470;448;96 +466;400;496 +466;448;464 +465;128;208 +465;192;480 +465;208;48 +465;240;448 +465;288;48 +465;384;432 +477;272;480 +427;96;156;1;False; +427;508;224;;; +427;592;180;3;; +427;628;224;2;; +484;48;176 +484;208;352 +484;240;224 +484;256;176 +484;256;304 +484;288;336 +484;288;352 +484;304;208 +424;416;80 +421;192;96;;3;2; +421;304;96;3;;2; +22;64;256;;;; +22;120;256;;;; +22;160;192;;;; +22;328;472;;;; +22;616;256;;;; +339;208;208;;;;;; +200;400;448;w;;bomb_10;; +200;408;184;;d7_instrument;instrument6;; +162;208;176;;18;;8;;;;; +162;224;160;18;2;8;;;;;; +162;248;288;-18;2;8;32;;;;; +162;256;320;;18;128;6;;;;; +162;264;208;-18;2;8;32;;;;; +162;280;160;-18;2;8;32;;;;; +162;296;408;-18;2;8;48;;;;;True +162;376;176;-18;2;8;;;;;; +162;384;288;18;2;8;32;;;;; +162;448;176;18;2;8;;;;;; +168;440;264;d7_door_1;d7_nightmare&(!d7_enter_I|d7_instrument); +168;488;392;d7_3_door_0;!d7_3_enter_0|d7_grim_creeper; +168;608;160;d7_spawn_chest_3_check;d7_3_stone_0_dir=2&d7_3_stone_1_dir=0; +168;664;264;d7_3_door_1;!d7_3_enter_0|d7_grim_creeper; +333;64;240;d7_3_keyhole +167;504;408;d7_3_enter_0; +167;672;160;d7_spawn_chest_3_check;0 +302;32;304;;;;; +302;144;288;;;;; +302;176;272;;;;; +302;352;112;;;;; +302;352;160;;;;; +302;464;112;;;;; +302;464;160;;;;; +302;512;368;;;;; +302;544;224;;;;; +302;592;224;;;;; +302;624;368;;;;; +307;64;144;;;;; +307;112;144;;;;; +307;192;144;;;;; +307;224;16;;;;; +307;272;16;;;;; +307;304;144;;;;; +307;432;400;;;;; +307;464;400;;;;; +308;480;464;;;;; +170;336;336;d7_4_mstone_reset_2;;;; +170;336;352;d7_4_mstone_reset_2;;;; +170;336;368;d7_4_mstone_reset_2;;;; +170;384;384;d7_4_mstone_reset_2;3;;; +170;408;256;d7_enter_I;1;;; +170;480;312;d7_4_mstone_reset_2;2;;; +170;496;312;d7_3_enter_0;2;;; +170;616;256;d7_4_mstone_reset;3;;; +170;616;256;d7_4_mstone_reset;1;;;True +11;304;400;;; +13;320;176;;; +13;320;192;;; +13;320;208;;; +13;320;224;;; +13;320;240;;; +13;320;416;;; +13;320;432;;; +25;160;176;;;; +25;176;176;;;; +25;208;176;;;; +25;224;160;;;; +25;224;176;;;; +25;232;256;;;; +25;232;272;;;; +25;240;240;;;; +25;240;256;;;; +25;240;272;;;; +25;240;288;;;; +25;240;304;;;; +25;240;320;;;; +25;256;192;;;; +25;256;208;;;; +25;256;224;;;; +25;256;240;;;; +25;256;320;;;; +25;272;160;;;; +25;272;176;;;; +25;272;192;;;; +25;272;320;;;; +25;288;320;;;; +25;288;384;;;; +25;288;400;;;; +25;288;416;;;; +25;288;432;;;; +25;288;448;;;; +25;304;320;;;; +25;304;384;;;; +25;320;320;;;; +25;320;384;;;; +25;320;448;;;; +25;320;456;;;; +25;336;160;;;; +25;336;176;;;; +25;336;192;;;; +25;336;208;;;; +25;336;224;;;; +25;336;240;;;; +25;336;320;;;; +25;336;384;;;; +25;336;400;;;; +25;336;416;;;; +25;336;432;;;; +25;336;448;;;; +25;336;456;;;; +25;352;240;;;; +25;352;320;;;; +25;352;384;;;; +25;352;400;;;; +25;368;176;;;; +25;368;192;;;; +25;368;208;;;; +25;368;240;;;; +25;368;320;;;; +25;368;384;;;; +25;368;400;;;; +25;384;208;;;; +25;384;240;;;; +25;384;288;;;; +25;384;304;;;; +25;384;320;;;; +25;432;208;;;; +25;448;176;;;; +25;448;192;;;; +25;448;208;;;; +508;568;280;d7_grim_creeper +223;176;160;;;;;;;; +223;192;416;;;;;;;; +223;304;160;0;;;;;;; +223;400;320;8;;;;;;;d7_4_mstone_reset_2 +223;416;320;8;;;;;;;d7_4_mstone_reset_2 +223;432;320;8;;;;;;;d7_4_mstone_reset_2 +223;448;288;4;;;;;;;d7_4_mstone_reset_2 +223;448;304;4;;;;;;;d7_4_mstone_reset_2 +223;448;320;12;;;;;;;d7_4_mstone_reset_2 +223;544;192;;d7_3_stone_0;;;;;;d7_4_mstone_reset +223;592;192;;d7_3_stone_1;;;;;;d7_4_mstone_reset +287;80;544;90 +164;408;232;d7_enter_I;1;dialogBox;d7_instrument_music; +164;568;328;d7_grim_creeper;1;dungeonTeleporter;dungeon7_1$map.d7_teleport; +166;464;48;d7_4_horse_head;1;d7_spawn_chest_4 +166;624;160;d7_spawn_chest_3_check;1;d7_spawn_chest_3_init +166;624;176;d7_spawn_chest_3_init;1;d7_spawn_chest_3 +231;32;160;;;;;; +231;32;240;;;;;; +231;144;160;;;;;; +231;144;240;;;;;; +353;32;320 +353;32;336 +353;48;304 +353;128;368 +353;144;336 +353;144;352 +353;144;368 +160;192;176; +160;304;448; +160;400;208; +160;416;208; +246;192;160; +246;192;176; +246;208;160; +246;256;256; +246;256;272; +246;256;288; +246;256;304; +246;272;208; +246;272;224; +246;272;240; +246;272;256; +246;272;272; +246;272;288; +246;272;304; +246;288;160; +246;288;176; +246;288;192; +246;288;208; +246;288;224; +246;288;240; +246;288;256; +246;288;272; +246;288;288; +246;288;304; +246;304;176; +246;304;192; +246;304;208; +246;304;224; +246;304;240; +246;304;256; +246;304;272; +246;304;288; +246;304;304; +246;304;400; +246;304;416; +246;304;432; +246;304;448; +246;320;160; +246;320;176; +246;320;192; +246;320;208; +246;320;224; +246;320;240; +246;320;288; +246;320;304; +246;320;400; +246;320;416; +246;320;432; +246;336;288; +246;336;304; +246;352;288; +246;352;304; +246;368;288; +246;368;304; +246;384;176; +246;384;192; +246;400;160; +246;400;176; +246;400;192; +246;400;208; +246;416;160; +246;416;176; +246;416;192; +246;416;208; +246;432;176; +246;432;192; diff --git a/bin/Data/Maps/dungeon7_4.map.data b/bin/Data/Maps/dungeon7_4.map.data new file mode 100644 index 0000000..69f447c --- /dev/null +++ b/bin/Data/Maps/dungeon7_4.map.data @@ -0,0 +1,36 @@ +42 +34 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon8.map b/bin/Data/Maps/dungeon8.map new file mode 100644 index 0000000..e4d228d --- /dev/null +++ b/bin/Data/Maps/dungeon8.map @@ -0,0 +1,3341 @@ +3 +1 +2 +dungeon 8.png +83 +67 +3 +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,26,58,58,25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,14,23,16,49,23,23,46,14,23,16,,,,,,14,23,23,16,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25,53,26,5,5,5,5,25,53,26,,,,,,25,53,2,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25,53,26,5,5,5,5,25,53,26,,,,,,25,53,53,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25,53,26,5,5,5,5,25,53,26,,,,,,25,53,53,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25,53,49,23,57,57,23,46,53,26,,,,,,25,53,53,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25,53,53,53,5,5,53,53,53,26,,,,,,25,53,53,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25,53,53,53,5,5,53,53,53,26,,,,,,25,53,53,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13,24,24,24,37,43,24,24,24,15,,,,,,25,53,53,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,14,23,23,23,23,23,23,23,23,16,,,,,,,,,,,,,,,,,,,,,14,23,23,23,38,44,23,23,23,16,14,23,16,17,14,46,53,53,49,16,,,,,,,,,,,,,,,,,,,,,58,14,23,23,23,23,23,23,16,58,,, +,25,53,53,53,53,53,53,53,53,26,,,,,,,,,,,,,,,,,,,,,25,,,53,53,53,53,,53,26,25,,26,53,25,53,53,53,53,26,,,,,,,,,,,,,,,,,,,,,14,46,5,5,5,5,5,5,49,23,23,, +,25,53,35,31,35,35,31,35,53,26,,,,,,,,,,,,,,,,,,,,,25,,,,,,,,53,26,25,,26,53,25,53,53,53,53,26,,,,,,,,,,,,,,,,,,,,23,46,5,5,5,5,14,23,57,23,16,,, +,25,53,59,53,59,59,53,59,53,26,,,,,,,,,,,,,,,,,,,,,25,,,,,,,,53,26,25,,49,23,46,53,53,53,53,26,,,,,,,,,,,,,,,,,,,,,14,23,23,23,23,46,53,53,53,26,,, +,25,53,52,35,59,59,35,59,53,26,,,,,,,,,,,,,,,,,,,,,25,,,,,,,,53,26,25,,,,,53,53,53,53,26,,,,,,,,,,,,,,,,,,,,,25,53,1,53,53,53,21,21,21,49,23,, +,25,53,53,59,59,59,59,59,53,26,,,,,,,,,,,,,,,,,,,,,25,,,,,,,,53,26,25,,47,24,48,53,53,53,53,26,,,,,,,,,,,,,,,,,,,,23,46,53,53,53,53,14,23,57,23,16,,, +,25,53,53,52,52,52,52,52,31,26,,,,,,,,,,,,,,,,,,,,,25,53,53,53,53,53,53,53,53,26,25,53,26,53,25,53,53,53,53,26,,,,,,,,,,,,,,,,,,,,,14,23,23,16,53,25,53,53,53,26,,, +,13,37,43,24,24,24,24,24,24,15,,,,,,,,,,,,,,,,,,,,,13,24,24,24,37,43,24,24,24,15,25,53,26,53,13,24,24,24,24,15,26,,,,,,,,,25,,,,,,,,,,,25,53,53,26,53,13,37,43,24,15,,, +,14,38,44,23,23,23,23,23,23,16,26,8,17,17,17,10,14,23,23,23,23,23,46,14,23,22,16,8,17,10,14,23,23,23,38,44,23,23,23,16,25,53,26,53,14,23,23,23,16,53,49,23,23,23,23,0,23,23,23,46,53,14,23,23,23,23,23,23,23,16,25,53,53,49,23,23,38,44,23,16,,, +,25,53,53,53,53,53,,53,53,26,26,18,53,53,2,20,25,53,53,53,53,53,53,25,53,53,26,53,53,20,25,,,,18,20,,,,26,25,53,26,53,25,53,,53,26,19,19,19,19,19,19,19,19,33,53,53,53,25,31,31,31,31,31,31,31,26,25,53,53,53,53,53,53,53,53,26,,, +,25,53,,,,,,,53,26,49,23,57,23,23,23,46,14,57,16,14,23,23,46,53,53,26,53,53,9,25,17,53,,18,20,,53,17,26,25,53,49,57,46,53,,53,49,23,23,23,23,23,23,23,16,18,53,47,48,25,31,31,31,31,31,31,31,26,25,53,53,53,53,53,53,53,53,26,,, +,25,53,,,,,,,53,26,5,5,5,5,5,5,5,25,53,26,25,53,53,53,53,53,49,23,23,23,46,53,20,,18,2,,18,53,40,39,53,,53,53,53,,53,53,53,53,53,53,53,53,53,26,18,53,26,25,25,31,31,31,31,31,31,31,26,25,53,53,53,53,53,53,53,53,26,,, +,25,53,,,,,,,53,26,14,57,23,16,47,24,48,25,53,40,39,53,53,53,53,53,53,53,53,53,53,53,20,,7,9,,18,53,42,41,53,,53,53,,,,,47,48,53,53,53,53,53,26,7,19,49,46,25,31,31,31,31,31,31,31,26,25,53,53,53,53,53,53,53,53,26,,, +,25,53,,,,,,,53,40,39,53,53,26,26,58,25,25,53,42,41,53,53,53,53,53,53,53,53,53,53,53,20,,,,,18,53,49,46,,,53,,,,,,26,25,53,53,53,53,53,49,23,23,23,23,46,53,53,53,53,53,31,31,26,25,53,53,53,53,53,53,53,53,26,,, +,25,53,53,,53,53,53,53,53,42,41,53,53,26,26,58,25,13,24,15,25,53,53,53,53,53,53,53,,,,53,34,17,17,17,17,32,53,,,,,,,,,,,26,25,53,53,53,53,53,53,53,53,53,53,31,31,31,53,53,31,31,31,26,25,53,53,53,53,53,53,53,53,26,,, +,13,24,24,24,24,24,24,24,24,15,13,24,24,15,26,58,13,24,24,48,25,53,47,48,,47,24,48,,47,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,15,13,24,24,24,24,24,24,24,24,24,24,24,24,24,37,43,24,24,24,15,13,24,24,24,24,24,24,24,24,15,,, +,,,,,,,,,,,8,17,17,17,49,23,23,23,23,46,25,53,49,46,,49,23,46,,26,14,23,23,23,23,23,16,53,53,53,53,17,17,17,53,53,17,17,17,53,14,23,23,23,23,23,23,23,23,16,14,23,23,23,38,44,23,23,23,16,,,,,,,,,,,,, +,,,,,,,,,,,18,20,14,57,23,23,23,23,23,23,46,53,20,,5,,18,53,,26,25,53,53,53,53,53,26,53,53,53,53,53,53,53,53,53,53,53,53,53,25,6,6,6,35,6,6,6,6,26,25,5,5,53,5,5,5,5,5,26,,,,,,,,,,,,, +,,,,,,,,,,,18,20,25,53,53,53,53,53,53,53,53,53,34,10,,8,32,53,,26,25,53,53,31,53,53,49,57,23,16,14,23,57,23,23,23,23,57,23,16,25,6,6,6,59,6,6,6,6,26,25,5,53,53,5,5,5,5,5,26,,,,,,,,,,,,, +,,,,,,,,,,,18,20,25,53,53,53,53,53,53,47,48,53,5,53,5,53,53,53,,54,54,53,53,53,53,53,53,53,53,40,39,6,6,6,6,6,6,6,6,26,25,6,6,6,59,31,6,6,6,26,25,53,53,53,53,53,53,53,53,26,,,,,,,,,,,,, +,,,,,,,,,,,18,20,25,35,53,53,53,53,35,26,25,53,53,53,5,53,53,53,,26,25,53,53,53,53,31,53,53,53,42,41,6,47,24,24,24,48,6,6,26,25,6,6,6,59,6,6,6,6,54,54,53,53,53,53,53,53,53,53,26,,,,,,,,,,,,, +,,,,,,,,,,,18,20,25,52,53,53,53,53,59,26,25,53,53,53,5,53,53,53,,26,25,53,31,53,53,53,53,53,31,26,25,6,26,53,53,53,25,6,6,49,46,6,6,6,59,6,6,6,6,26,25,5,53,53,5,5,5,5,5,26,,,,,,,,,,,,, +,,,,,,,,,,,18,20,25,53,53,53,53,53,52,26,25,53,53,53,5,53,53,53,,26,25,53,53,53,53,53,53,31,53,26,25,6,26,53,1,53,25,6,6,53,53,53,6,6,52,31,6,6,6,26,25,5,5,53,5,5,5,5,5,26,,,,,,,,,,,,, +,,,,,,,,,,,18,20,13,24,24,24,24,24,24,15,25,53,47,24,24,24,24,48,,26,13,24,24,24,55,24,24,24,24,15,13,30,15,53,53,53,13,24,24,24,24,24,24,24,24,24,24,24,24,15,13,24,24,24,37,43,24,24,24,15,,,,,,,,,,,,, +,,,,,,,,,,,18,34,17,17,17,10,14,23,23,16,25,53,49,23,23,23,23,46,,49,23,23,23,23,55,23,23,23,23,16,14,23,23,23,23,23,23,23,23,16,14,23,23,23,23,23,23,23,23,16,14,23,23,23,38,44,23,23,23,16,,,,,,,,,,,,, +,,,,,,,,,,,7,53,53,53,53,53,25,53,53,26,25,53,53,53,53,53,,,,,,53,53,,,,,53,53,49,46,,,,,,,,,49,46,,,,,,,,,26,25,53,53,53,53,53,53,53,53,26,,,,,,,,,,,,, +,,,,,,,,,,,14,23,23,23,23,23,46,53,53,26,25,53,53,53,53,53,,,,,,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,,53,53,26,25,53,53,53,53,53,53,53,53,26,,,,,,,,,,,,, +,,,,,,,,,,,25,53,53,53,53,53,53,53,53,26,25,53,53,53,53,53,,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,47,24,24,48,53,47,24,24,48,53,53,53,53,53,,53,53,40,39,53,53,53,53,53,53,53,53,26,,,,,,,,,,,,, +,,,,,,,,,,,25,19,19,19,53,53,19,19,19,26,25,53,53,53,53,53,,53,53,47,48,53,53,53,53,53,53,53,53,53,53,53,26,58,58,25,53,49,23,23,46,53,53,53,53,53,,53,53,42,41,53,53,53,53,2,53,53,53,26,,,,,,,,,,,,, +,,,,,,,,,,,25,53,53,20,53,53,18,53,53,26,25,53,53,53,53,53,,53,53,26,25,53,53,53,53,53,53,53,53,53,53,53,49,23,23,46,53,53,53,53,53,53,53,53,53,53,53,53,53,26,25,53,53,53,53,53,53,53,53,26,,,,,,,,,,,,, +,,,,,,,,,,,25,53,53,20,53,53,18,53,53,26,25,53,53,53,53,53,,53,53,26,25,1,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,47,24,24,57,24,48,53,53,53,53,26,25,53,53,53,53,53,53,53,53,26,,,,,,,,,,,,, +,,,,,,,,,,,13,24,24,48,53,53,47,24,24,15,13,24,24,24,24,24,24,24,24,15,13,24,24,24,24,24,24,55,24,24,48,53,53,53,53,53,53,53,53,26,53,53,53,53,13,24,24,24,24,15,13,24,24,24,24,24,24,24,24,15,,,,,,,,,,,,, +,,14,23,23,23,23,23,23,16,,14,23,23,46,53,53,49,23,23,16,14,23,23,23,23,23,23,23,23,16,14,23,23,23,23,23,23,55,23,23,46,53,53,53,53,53,53,53,53,49,16,53,53,53,14,23,23,23,23,16,14,23,23,23,23,23,23,23,16,,14,23,23,23,23,23,23,23,23,16,,, +,,25,53,53,31,31,53,53,26,,25,35,35,53,53,53,53,53,53,26,25,53,53,53,53,53,53,53,53,26,25,53,53,53,53,53,53,53,53,53,53,53,,,53,,53,,53,53,49,57,16,53,25,53,53,53,2,26,25,53,53,53,53,53,53,53,26,,25,1,53,53,35,35,35,35,53,26,,, +,14,46,53,53,53,53,53,53,49,16,25,59,59,53,53,53,53,53,53,26,25,53,5,53,5,5,53,5,53,26,25,53,53,53,53,53,53,53,53,53,53,53,,,,,,,53,53,53,53,49,23,46,53,53,53,53,26,25,53,47,24,24,24,48,53,26,,25,53,53,53,52,59,59,59,53,26,,, +,25,35,53,53,53,53,53,53,35,26,25,59,52,31,31,31,53,53,53,40,39,53,53,5,5,5,5,53,53,26,25,53,53,53,53,53,53,53,53,53,53,,,,,,,,,53,53,53,53,53,53,53,53,53,53,26,25,53,26,5,5,5,25,53,26,,25,35,53,53,53,59,59,59,53,26,,, +,25,52,53,53,53,53,53,53,52,26,25,59,53,53,53,53,53,53,53,42,41,53,53,5,5,5,5,53,53,26,25,53,53,53,53,53,53,53,53,53,53,53,,,,,,,,53,53,53,53,53,53,53,53,53,53,54,54,53,26,5,5,5,25,53,26,,25,59,35,53,53,52,52,52,53,26,,, +,25,53,53,53,35,35,53,53,53,26,25,59,53,53,53,53,53,53,53,26,25,53,5,53,5,5,53,5,53,26,25,,,,,,,,,,,53,,53,,,47,57,24,24,24,24,24,24,24,24,57,48,53,26,25,53,49,23,57,23,46,53,26,,25,52,52,31,53,53,53,53,53,26,,, +,25,53,53,53,52,52,53,53,53,26,25,52,53,47,24,24,24,24,24,15,25,53,53,53,53,53,53,53,53,26,25,,,53,53,53,53,53,53,53,53,53,53,53,53,,26,2,5,5,5,5,5,5,5,5,5,25,53,26,25,53,53,53,53,53,53,53,26,,25,53,53,53,53,31,31,53,53,26,,, +,13,37,43,24,24,24,24,24,24,15,25,53,53,26,,,,,,,13,24,24,24,37,43,24,24,24,15,25,,47,48,53,53,47,24,24,24,24,24,24,24,24,24,15,5,5,5,5,5,5,5,5,5,5,13,24,15,13,24,24,24,55,24,24,24,15,,13,24,24,24,24,24,24,37,43,15,,, +,14,38,44,23,23,23,23,23,23,16,25,53,53,49,23,23,23,23,23,16,14,23,23,23,38,44,23,23,23,23,46,,49,46,53,53,49,23,23,16,14,23,23,23,23,23,16,5,5,5,5,5,5,5,5,5,5,5,5,5,14,23,23,23,55,23,23,23,23,16,14,23,23,23,23,23,23,38,44,16,,, +,25,53,53,53,53,53,53,53,53,26,25,53,53,35,53,31,53,31,53,26,25,53,53,53,53,53,53,53,,,,,,,53,53,,,,26,25,,53,53,53,53,49,23,23,16,14,23,23,23,23,23,23,16,5,5,25,35,35,35,53,53,53,53,53,26,25,53,53,53,53,53,53,53,53,26,,, +,25,53,53,53,53,53,53,53,53,26,25,53,53,59,53,53,53,53,53,26,25,53,53,53,53,53,53,53,53,47,48,53,53,,53,53,,53,53,26,25,,,53,53,53,53,,53,26,25,53,53,53,53,53,,49,23,23,46,52,59,59,35,53,53,53,53,26,25,53,53,53,53,53,53,53,53,26,,, +,25,53,53,53,53,53,53,53,53,40,39,53,53,59,53,31,53,31,53,26,25,53,53,53,53,53,53,53,53,40,39,53,53,,,,,53,53,40,39,53,53,53,53,53,53,53,53,40,39,53,53,5,5,5,,53,53,53,53,53,52,59,59,35,53,53,53,40,39,53,53,53,53,53,53,53,53,26,,, +,25,53,53,53,53,53,53,53,53,42,41,53,53,59,53,53,53,53,53,26,25,53,53,,,53,53,53,53,42,41,53,53,53,53,53,53,53,53,42,41,53,53,53,53,53,53,53,53,42,41,53,53,5,5,5,,53,53,53,53,53,53,52,59,59,35,53,53,42,41,53,53,53,53,53,53,53,53,26,,, +,25,53,53,53,53,53,53,53,53,26,25,31,31,52,53,53,31,53,53,26,25,53,53,,53,53,53,53,53,26,25,53,53,53,53,53,53,53,53,26,25,53,53,53,53,53,53,53,53,26,25,53,53,5,5,5,,47,24,24,48,53,53,53,52,59,59,35,53,26,25,53,53,53,53,53,53,53,53,26,,, +,25,53,53,53,53,53,53,53,53,26,25,53,53,53,31,53,53,53,31,26,25,,,,,,,,,26,25,53,53,53,53,53,53,53,53,26,25,53,53,53,53,53,53,53,53,26,25,,,53,53,53,,26,5,5,25,53,53,53,53,52,52,52,31,26,25,53,53,53,53,53,53,53,53,26,,, +,13,37,43,24,24,24,24,24,24,15,13,24,24,24,24,24,24,24,24,15,13,24,24,24,24,24,24,24,24,15,13,24,24,48,53,53,47,24,24,15,13,24,24,24,37,43,24,24,24,15,13,24,24,24,24,24,24,15,5,5,13,24,24,24,24,24,24,24,24,15,13,24,24,24,24,24,24,37,43,15,,, +,14,38,44,23,23,23,23,23,16,,,,,,,,,,,,,,,,,,,,,,,,,25,53,53,26,,,,14,23,23,23,38,44,23,23,23,16,,,,,,,,,,,,,,,,,,,,,,,,14,23,23,23,38,44,16,,, +,25,53,53,53,53,53,53,53,26,,,,,,,,,,,,,,,,,,,,,,,,,25,53,53,26,,,,25,53,53,53,53,53,53,53,53,26,,,,,,,,,,,,,,,,,,,,,,,14,46,35,53,53,53,53,26,,, +,25,53,53,17,17,17,18,53,26,,,,,,,,,,,,,,,,,,,,,,,,14,46,53,53,49,16,,,25,53,53,53,53,53,53,53,53,26,,,,,,,,,,,,,,,,,,,,,,,25,53,52,53,31,31,53,26,,, +,25,53,18,5,5,5,10,53,26,,,,,,,,,,,,,,,,,,,,,,,14,46,53,53,53,53,49,16,,25,53,53,53,47,48,53,53,53,26,,,,,,,,,,,,,,,,,,,,,,,25,53,53,53,53,53,53,26,,, +,25,53,18,5,5,5,20,53,26,,,,,,,,,,,,,,,,,,,,,,,25,53,53,53,53,53,53,26,,25,53,53,53,49,46,53,53,53,26,,,,,,,,,,,,,,,,,,,,,14,23,46,53,35,53,47,24,24,15,,, +,25,53,17,7,19,19,53,53,26,,,,,,,,,,,,,,,,,,,,,,,25,53,28,29,29,27,53,26,,25,53,53,53,53,53,53,53,53,26,,,,,,,,,,,,,,,,,,,,,25,53,53,53,52,53,26,,,,,, +,25,53,53,53,53,53,53,53,26,,,,,,,,,,,,,,,,,,,,,,,25,53,51,45,36,50,53,26,,25,53,53,53,53,53,53,53,53,26,,,,,,,,,,,,,,,,,,,,,25,1,53,47,24,24,15,,,,,, +,13,24,24,24,24,24,24,24,15,,,,,,,,,,,,,,,,,,,,,,,13,24,12,4,3,11,24,15,,13,24,24,24,24,24,24,24,24,15,,,,,,,,,,,,,,,,,,,,,13,24,24,15,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,,,,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,,,,0,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,,,,0,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,,,,0,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,,,,0,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,,,,0,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,,,,0,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,,,,0,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,0,0,0,0,,,,,0,0,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,0, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,0,0,,,,,,,,,,,0,0, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,0,0,,,,,,,,,,,0,0, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,0,0,,,,,,,,,,,0,0, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,0,0,,,,,,,,,,,0,0, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,0,0,,,,,,,,,,,0,0, +0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,0,,,,,,,0,0,0,,,,,,,,0,0,,,,,,,,,,,0,, +0,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,, +,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,, +,0,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,, +0,0,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,, +0,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,0,0,0,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,0,, +0,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,0,0,,,,,0,0,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,0,, +0,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,0,,,,,,,0,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,0,, +0,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,0,0,,,,,,,,,0,, +0,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,0,, +0,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,0,0,0,0,, +0,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,0,,,,, +0,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,0,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,0,0,0,0,,,,, +0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,0,0,0,0,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,,,,,,,, +524 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +waterfallSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +2607 +169;688;816;d8_button_0 +169;1264;736;d8_button_1 +0;16;176;;; +0;16;192;;; +0;16;208;;; +0;16;224;;; +0;16;240;;; +0;16;256;;; +0;16;304;;; +0;16;320;;; +0;16;336;;; +0;16;352;;; +0;16;368;;; +0;16;384;;; +0;16;720;;; +0;16;736;;; +0;16;752;;; +0;16;768;;; +0;16;816;;; +0;16;832;;; +0;16;848;;; +0;16;864;;; +0;16;880;;; +0;16;896;;; +0;16;944;;; +0;16;960;;; +0;16;976;;; +0;16;992;;; +0;16;1008;;; +0;16;1024;;; +0;32;160;;; +0;32;400;;; +0;32;688;;; +0;32;704;;; +0;32;1040;;; +0;48;160;;; +0;48;400;;; +0;48;672;;; +0;48;1040;;; +0;64;160;;; +0;64;272;;; +0;64;288;;; +0;64;400;;; +0;64;672;;; +0;64;784;;; +0;64;800;;; +0;64;912;;; +0;64;928;;; +0;64;1040;;; +0;80;160;;; +0;80;272;;; +0;80;288;;; +0;80;400;;; +0;80;672;;; +0;80;784;;; +0;80;800;;; +0;80;912;;; +0;80;928;;; +0;80;1040;;; +0;96;160;;; +0;96;272;;; +0;96;288;;; +0;96;400;;; +0;96;672;;; +0;96;784;;; +0;96;800;;; +0;96;912;;; +0;96;928;;; +0;96;1040;;; +0;112;160;;; +0;112;272;;; +0;112;288;;; +0;112;400;;; +0;112;672;;; +0;112;784;;; +0;112;800;;; +0;112;912;;; +0;112;928;;; +0;112;1040;;; +0;128;160;;; +0;128;272;;; +0;128;288;;; +0;128;400;;; +0;128;672;;; +0;128;784;;; +0;128;800;;; +0;128;912;;; +0;128;928;;; +0;128;1040;;; +0;144;160;;; +0;144;272;;; +0;144;288;;; +0;144;400;;; +0;144;688;;; +0;144;704;;; +0;144;784;;; +0;144;800;;; +0;144;912;;; +0;144;944;;; +0;144;960;;; +0;144;976;;; +0;144;992;;; +0;144;1008;;; +0;144;1024;;; +0;160;176;;; +0;160;192;;; +0;160;208;;; +0;160;224;;; +0;160;240;;; +0;160;256;;; +0;160;304;;; +0;160;320;;; +0;160;336;;; +0;160;352;;; +0;160;720;;; +0;160;736;;; +0;160;752;;; +0;160;768;;; +0;160;816;;; +0;160;832;;; +0;160;880;;; +0;160;896;;; +0;176;272;;; +0;176;352;;; +0;176;592;;; +0;176;608;;; +0;176;624;;; +0;176;640;;; +0;176;688;;; +0;176;704;;; +0;176;720;;; +0;176;736;;; +0;176;752;;; +0;176;768;;; +0;176;784;;; +0;176;800;;; +0;176;816;;; +0;176;832;;; +0;176;880;;; +0;176;896;;; +0;192;272;;; +0;192;400;;; +0;192;656;;; +0;192;672;;; +0;192;912;;; +0;208;272;;; +0;208;400;;; +0;208;656;;; +0;208;672;;; +0;208;912;;; +0;224;272;;; +0;224;368;;; +0;224;384;;; +0;224;656;;; +0;224;672;;; +0;224;768;;; +0;224;784;;; +0;224;800;;; +0;224;912;;; +0;240;272;;; +0;240;352;;; +0;240;416;;; +0;240;768;;; +0;240;800;;; +0;240;912;;; +0;256;272;;; +0;256;352;;; +0;256;768;;; +0;256;800;;; +0;256;912;;; +0;272;272;;; +0;272;304;;; +0;272;320;;; +0;272;352;;; +0;272;528;;; +0;272;656;;; +0;272;672;;; +0;272;768;;; +0;272;800;;; +0;272;912;;; +0;288;288;;; +0;288;384;;; +0;288;528;;; +0;288;544;;; +0;288;656;;; +0;288;672;;; +0;288;768;;; +0;288;800;;; +0;288;912;;; +0;304;288;;; +0;304;384;;; +0;304;528;;; +0;304;544;;; +0;304;656;;; +0;304;672;;; +0;304;768;;; +0;304;800;;; +0;304;912;;; +0;320;288;;; +0;320;384;;; +0;320;464;;; +0;320;480;;; +0;320;496;;; +0;320;512;;; +0;320;560;;; +0;320;576;;; +0;320;592;;; +0;320;608;;; +0;320;624;;; +0;320;640;;; +0;320;688;;; +0;320;704;;; +0;320;752;;; +0;320;768;;; +0;320;816;;; +0;320;832;;; +0;320;848;;; +0;320;864;;; +0;320;880;;; +0;320;896;;; +0;336;288;;; +0;336;384;;; +0;336;400;;; +0;336;416;;; +0;336;464;;; +0;336;480;;; +0;336;496;;; +0;336;512;;; +0;336;528;;; +0;336;544;;; +0;336;560;;; +0;336;576;;; +0;336;592;;; +0;336;608;;; +0;336;624;;; +0;336;640;;; +0;336;688;;; +0;336;704;;; +0;336;752;;; +0;336;768;;; +0;336;816;;; +0;336;832;;; +0;336;848;;; +0;336;864;;; +0;336;880;;; +0;336;896;;; +0;352;288;;; +0;352;656;;; +0;352;672;;; +0;352;784;;; +0;352;800;;; +0;352;912;;; +0;368;288;;; +0;368;400;;; +0;368;416;;; +0;368;528;;; +0;368;544;;; +0;368;656;;; +0;368;672;;; +0;368;784;;; +0;368;800;;; +0;368;912;;; +0;384;400;;; +0;384;416;;; +0;384;528;;; +0;384;544;;; +0;384;656;;; +0;384;672;;; +0;384;784;;; +0;384;800;;; +0;384;912;;; +0;400;288;;; +0;400;528;;; +0;400;544;;; +0;400;656;;; +0;400;672;;; +0;400;912;;; +0;416;400;;; +0;416;416;;; +0;416;528;;; +0;416;544;;; +0;416;656;;; +0;416;672;;; +0;416;912;;; +0;432;400;;; +0;432;416;;; +0;432;528;;; +0;432;544;;; +0;432;656;;; +0;432;672;;; +0;432;784;;; +0;432;800;;; +0;432;912;;; +0;448;400;;; +0;448;416;;; +0;448;528;;; +0;448;544;;; +0;448;656;;; +0;448;672;;; +0;448;784;;; +0;448;800;;; +0;448;912;;; +0;464;656;;; +0;464;672;;; +0;464;784;;; +0;464;800;;; +0;464;912;;; +0;480;336;;; +0;480;400;;; +0;480;416;;; +0;480;432;;; +0;480;448;;; +0;480;480;;; +0;480;496;;; +0;480;512;;; +0;480;528;;; +0;480;544;;; +0;480;608;;; +0;480;624;;; +0;480;640;;; +0;480;688;;; +0;480;704;;; +0;480;720;;; +0;480;736;;; +0;480;752;;; +0;480;768;;; +0;480;784;;; +0;480;800;;; +0;480;832;;; +0;480;880;;; +0;480;896;;; +0;496;48;;; +0;496;64;;; +0;496;80;;; +0;496;96;;; +0;496;112;;; +0;496;128;;; +0;496;176;;; +0;496;192;;; +0;496;208;;; +0;496;224;;; +0;496;240;;; +0;496;256;;; +0;496;304;;; +0;496;320;;; +0;496;336;;; +0;496;400;;; +0;496;432;;; +0;496;448;;; +0;496;480;;; +0;496;496;;; +0;496;512;;; +0;496;528;;; +0;496;544;;; +0;496;608;;; +0;496;624;;; +0;496;640;;; +0;496;688;;; +0;496;704;;; +0;496;720;;; +0;496;736;;; +0;496;752;;; +0;496;768;;; +0;496;784;;; +0;496;800;;; +0;496;832;;; +0;496;880;;; +0;496;896;;; +0;512;32;;; +0;512;144;;; +0;512;160;;; +0;512;272;;; +0;512;288;;; +0;512;400;;; +0;512;416;;; +0;512;528;;; +0;512;544;;; +0;512;656;;; +0;512;672;;; +0;512;912;;; +0;512;992;;; +0;512;1008;;; +0;512;1024;;; +0;528;48;;; +0;528;144;;; +0;528;160;;; +0;528;272;;; +0;528;288;;; +0;528;400;;; +0;528;416;;; +0;528;528;;; +0;528;544;;; +0;528;656;;; +0;528;672;;; +0;528;784;;; +0;528;800;;; +0;528;912;;; +0;528;976;;; +0;528;1040;;; +0;544;32;;; +0;544;144;;; +0;544;160;;; +0;544;272;;; +0;544;288;;; +0;544;400;;; +0;544;416;;; +0;544;528;;; +0;544;544;;; +0;544;656;;; +0;544;672;;; +0;544;784;;; +0;544;800;;; +0;544;912;;; +0;544;928;;; +0;544;944;;; +0;544;960;;; +0;544;1040;;; +0;560;32;;; +0;560;400;;; +0;560;416;;; +0;560;656;;; +0;560;672;;; +0;568;1056;;; +0;576;32;;; +0;576;400;;; +0;576;416;;; +0;576;528;;; +0;576;544;;; +0;576;656;;; +0;576;672;;; +0;592;32;;; +0;592;144;;; +0;592;160;;; +0;592;272;;; +0;592;288;;; +0;592;400;;; +0;592;528;;; +0;592;544;;; +0;592;656;;; +0;592;672;;; +0;592;784;;; +0;592;800;;; +0;592;912;;; +0;592;928;;; +0;592;944;;; +0;592;960;;; +0;592;1040;;; +0;608;48;;; +0;608;144;;; +0;608;160;;; +0;608;272;;; +0;608;288;;; +0;608;400;;; +0;608;528;;; +0;608;544;;; +0;608;784;;; +0;608;800;;; +0;608;912;;; +0;608;976;;; +0;608;1040;;; +0;624;32;;; +0;624;144;;; +0;624;160;;; +0;624;272;;; +0;624;288;;; +0;624;400;;; +0;624;528;;; +0;624;544;;; +0;624;656;;; +0;624;672;;; +0;624;784;;; +0;624;800;;; +0;624;912;;; +0;624;992;;; +0;624;1008;;; +0;624;1024;;; +0;640;48;;; +0;640;64;;; +0;640;80;;; +0;640;96;;; +0;640;112;;; +0;640;128;;; +0;640;176;;; +0;640;192;;; +0;640;208;;; +0;640;224;;; +0;640;240;;; +0;640;256;;; +0;640;272;;; +0;640;304;;; +0;640;320;;; +0;640;368;;; +0;640;400;;; +0;640;496;;; +0;640;512;;; +0;640;560;;; +0;640;656;;; +0;640;672;;; +0;640;784;;; +0;640;816;;; +0;640;832;;; +0;640;880;;; +0;640;896;;; +0;656;176;;; +0;656;192;;; +0;656;208;;; +0;656;224;;; +0;656;240;;; +0;656;256;;; +0;656;272;;; +0;656;288;;; +0;656;304;;; +0;656;320;;; +0;656;368;;; +0;656;496;;; +0;656;512;;; +0;656;560;;; +0;656;656;;; +0;656;672;;; +0;656;784;;; +0;656;816;;; +0;656;832;;; +0;656;880;;; +0;656;896;;; +0;656;944;;; +0;656;960;;; +0;656;976;;; +0;656;992;;; +0;656;1008;;; +0;656;1024;;; +0;672;528;;; +0;672;544;;; +0;672;784;;; +0;672;800;;; +0;672;912;;; +0;672;928;;; +0;672;1040;;; +0;688;512;;; +0;688;528;;; +0;688;544;;; +0;688;592;;; +0;688;608;;; +0;688;624;;; +0;688;784;;; +0;688;800;;; +0;688;912;;; +0;688;928;;; +0;688;1040;;; +0;704;544;;; +0;704;592;;; +0;704;624;;; +0;704;784;;; +0;704;800;;; +0;704;912;;; +0;704;928;;; +0;704;1040;;; +0;720;544;;; +0;720;592;;; +0;720;624;;; +0;720;784;;; +0;720;800;;; +0;720;976;;; +0;720;992;;; +0;720;1040;;; +0;736;48;;; +0;736;64;;; +0;736;80;;; +0;736;96;;; +0;736;112;;; +0;736;128;;; +0;736;144;;; +0;736;160;;; +0;736;272;;; +0;736;286;;; +0;736;544;;; +0;736;592;;; +0;736;608;;; +0;736;624;;; +0;736;784;;; +0;736;800;;; +0;736;976;;; +0;736;992;;; +0;736;1040;;; +0;752;32;;; +0;752;272;;; +0;752;286;;; +0;752;512;;; +0;752;528;;; +0;752;544;;; +0;752;912;;; +0;752;928;;; +0;752;1040;;; +0;768;32;;; +0;768;272;;; +0;768;286;;; +0;768;528;;; +0;768;544;;; +0;768;592;;; +0;768;608;;; +0;768;912;;; +0;768;928;;; +0;768;1040;;; +0;784;48;;; +0;784;64;;; +0;784;80;;; +0;784;96;;; +0;784;112;;; +0;784;128;;; +0;784;144;;; +0;784;160;;; +0;784;272;;; +0;784;286;;; +0;784;528;;; +0;784;544;;; +0;784;592;;; +0;784;608;;; +0;784;912;;; +0;784;928;;; +0;784;1040;;; +0;800;176;;; +0;800;192;;; +0;800;208;;; +0;800;224;;; +0;800;240;;; +0;800;256;;; +0;800;352;;; +0;800;368;;; +0;800;384;;; +0;800;448;;; +0;800;464;;; +0;800;480;;; +0;800;496;;; +0;800;528;;; +0;800;544;;; +0;800;560;;; +0;800;592;;; +0;800;608;;; +0;800;832;;; +0;800;880;;; +0;800;896;;; +0;800;928;;; +0;800;944;;; +0;800;960;;; +0;800;976;;; +0;800;992;;; +0;800;1008;;; +0;800;1024;;; +0;816;286;;; +0;816;352;;; +0;816;368;;; +0;816;384;;; +0;816;432;;; +0;816;448;;; +0;816;464;;; +0;816;480;;; +0;816;496;;; +0;816;528;;; +0;816;544;;; +0;816;560;;; +0;816;592;;; +0;816;608;;; +0;816;832;;; +0;816;880;;; +0;816;896;;; +0;832;286;;; +0;832;400;;; +0;832;416;;; +0;832;528;;; +0;832;544;;; +0;832;816;;; +0;832;912;;; +0;848;286;;; +0;848;400;;; +0;848;416;;; +0;848;528;;; +0;848;544;;; +0;848;816;;; +0;848;912;;; +0;864;286;;; +0;864;400;;; +0;864;416;;; +0;864;528;;; +0;864;544;;; +0;864;816;;; +0;864;912;;; +0;880;286;;; +0;880;400;;; +0;880;416;;; +0;880;528;;; +0;880;544;;; +0;880;816;;; +0;880;912;;; +0;896;400;;; +0;896;416;;; +0;896;528;;; +0;896;544;;; +0;896;656;;; +0;896;672;;; +0;896;912;;; +0;912;286;;; +0;912;400;;; +0;912;416;;; +0;912;528;;; +0;912;544;;; +0;912;656;;; +0;912;672;;; +0;912;912;;; +0;928;286;;; +0;928;400;;; +0;928;416;;; +0;928;528;;; +0;928;544;;; +0;928;656;;; +0;928;672;;; +0;928;832;;; +0;928;880;;; +0;928;896;;; +0;944;286;;; +0;944;400;;; +0;944;416;;; +0;944;528;;; +0;944;544;;; +0;944;656;;; +0;944;672;;; +0;944;784;;; +0;944;832;;; +0;944;880;;; +0;960;286;;; +0;960;320;;; +0;960;336;;; +0;960;352;;; +0;960;368;;; +0;960;400;;; +0;960;416;;; +0;960;432;;; +0;960;448;;; +0;960;464;;; +0;960;496;;; +0;960;512;;; +0;960;528;;; +0;960;544;;; +0;960;560;;; +0;960;576;;; +0;960;624;;; +0;960;640;;; +0;960;688;;; +0;960;704;;; +0;960;720;;; +0;960;752;;; +0;960;768;;; +0;960;784;;; +0;960;832;;; +0;960;880;;; +0;976;320;;; +0;976;336;;; +0;976;352;;; +0;976;368;;; +0;976;400;;; +0;976;416;;; +0;976;432;;; +0;976;448;;; +0;976;464;;; +0;976;496;;; +0;976;512;;; +0;976;528;;; +0;976;544;;; +0;976;560;;; +0;976;576;;; +0;976;624;;; +0;976;640;;; +0;976;688;;; +0;976;704;;; +0;976;720;;; +0;976;752;;; +0;976;768;;; +0;976;816;;; +0;976;832;;; +0;976;880;;; +0;976;896;;; +0;992;320;;; +0;992;336;;; +0;992;352;;; +0;992;368;;; +0;992;400;;; +0;992;416;;; +0;992;528;;; +0;992;544;;; +0;992;656;;; +0;992;672;;; +0;992;784;;; +0;992;800;;; +0;992;912;;; +0;1008;288;;; +0;1008;400;;; +0;1008;416;;; +0;1008;528;;; +0;1008;544;;; +0;1008;656;;; +0;1008;672;;; +0;1008;784;;; +0;1008;800;;; +0;1008;912;;; +0;1024;288;;; +0;1024;400;;; +0;1024;416;;; +0;1024;528;;; +0;1024;544;;; +0;1024;656;;; +0;1024;672;;; +0;1024;784;;; +0;1024;800;;; +0;1024;912;;; +0;1040;288;;; +0;1040;656;;; +0;1040;672;;; +0;1040;912;;; +0;1056;288;;; +0;1056;656;;; +0;1056;672;;; +0;1056;784;;; +0;1056;800;;; +0;1056;912;;; +0;1072;288;;; +0;1072;400;;; +0;1072;416;;; +0;1072;528;;; +0;1072;544;;; +0;1072;656;;; +0;1072;672;;; +0;1072;784;;; +0;1072;800;;; +0;1072;912;;; +0;1088;288;;; +0;1088;400;;; +0;1088;416;;; +0;1088;528;;; +0;1088;544;;; +0;1088;656;;; +0;1088;672;;; +0;1088;784;;; +0;1088;800;;; +0;1088;912;;; +0;1104;288;;; +0;1104;400;;; +0;1104;416;;; +0;1104;528;;; +0;1104;544;;; +0;1104;656;;; +0;1104;688;;; +0;1104;704;;; +0;1104;720;;; +0;1104;736;;; +0;1104;752;;; +0;1104;768;;; +0;1104;800;;; +0;1104;912;;; +0;1120;304;;; +0;1120;320;;; +0;1120;336;;; +0;1120;352;;; +0;1120;368;;; +0;1120;384;;; +0;1120;432;;; +0;1120;448;;; +0;1120;464;;; +0;1120;480;;; +0;1120;496;;; +0;1120;512;;; +0;1120;560;;; +0;1120;576;;; +0;1120;592;;; +0;1120;608;;; +0;1120;624;;; +0;1120;640;;; +0;1120;816;;; +0;1120;832;;; +0;1120;880;;; +0;1120;896;;; +0;1136;192;;; +0;1136;224;;; +0;1136;240;;; +0;1136;272;;; +0;1136;288;;; +0;1136;304;;; +0;1136;320;;; +0;1136;336;;; +0;1136;352;;; +0;1136;368;;; +0;1136;384;;; +0;1136;688;;; +0;1136;704;;; +0;1136;720;;; +0;1136;736;;; +0;1136;752;;; +0;1136;768;;; +0;1136;816;;; +0;1136;832;;; +0;1136;880;;; +0;1136;896;;; +0;1136;1008;;; +0;1136;1024;;; +0;1152;176;;; +0;1152;400;;; +0;1152;672;;; +0;1152;784;;; +0;1152;800;;; +0;1152;912;;; +0;1152;992;;; +0;1152;1040;;; +0;1168;160;;; +0;1168;400;;; +0;1168;672;;; +0;1168;784;;; +0;1168;800;;; +0;1168;912;;; +0;1168;960;;; +0;1168;976;;; +0;1168;992;;; +0;1168;1040;;; +0;1184;160;;; +0;1184;400;;; +0;1184;672;;; +0;1184;784;;; +0;1184;800;;; +0;1184;912;;; +0;1184;944;;; +0;1184;1024;;; +0;1200;160;;; +0;1200;400;;; +0;1200;672;;; +0;1200;784;;; +0;1200;800;;; +0;1200;912;;; +0;1200;928;;; +0;1200;1024;;; +0;1216;160;;; +0;1216;288;;; +0;1216;400;;; +0;1216;672;;; +0;1216;784;;; +0;1216;800;;; +0;1216;912;;; +0;1216;928;;; +0;1216;1024;;; +0;1232;160;;; +0;1232;400;;; +0;1232;672;;; +0;1232;784;;; +0;1232;800;;; +0;1232;912;;; +0;1232;928;;; +0;1232;992;;; +0;1232;1008;;; +0;1248;160;;; +0;1248;400;;; +0;1248;672;;; +0;1248;992;;; +0;1264;176;;; +0;1264;192;;; +0;1264;400;;; +0;1264;672;;; +0;1264;992;;; +0;1280;176;;; +0;1280;192;;; +0;1280;208;;; +0;1280;224;;; +0;1280;240;;; +0;1280;256;;; +0;1280;304;;; +0;1280;320;;; +0;1280;336;;; +0;1280;352;;; +0;1280;368;;; +0;1280;384;;; +0;1280;688;;; +0;1280;704;;; +0;1280;720;;; +0;1280;736;;; +0;1280;752;;; +0;1280;768;;; +0;1280;816;;; +0;1280;832;;; +0;1280;848;;; +0;1280;864;;; +0;1280;880;;; +0;1280;896;;; +0;1280;944;;; +0;1280;960;;; +0;1280;976;;; +19;112;976;;; +19;256;288;;; +19;256;544;;; +19;384;448;;; +19;480;288;;; +20;64;1008;;; +20;176;560;;; +20;560;352;;; +20;928;352;;; +21;480;320;;; +21;576;352;;; +14;432;448;;; +14;608;382;;; +1;160;384;;; +1;160;864;;; +1;176;384;;; +1;176;864;;; +1;320;368;;; +1;320;736;;; +1;336;368;;; +1;336;736;;; +1;480;864;;; +1;496;864;;; +1;552;1024;;; +1;584;1024;;; +1;640;352;;; +1;640;480;;; +1;640;864;;; +1;656;352;;; +1;656;480;;; +1;656;864;;; +1;800;864;;; +1;816;864;;; +1;960;608;;; +1;976;608;;; +1;1120;864;;; +1;1136;864;;; +3;32;272;;; +3;32;288;;; +3;32;784;;; +3;32;800;;; +3;32;912;;; +3;32;928;;; +3;400;784;;; +3;400;800;;; +3;560;144;;; +3;560;160;;; +3;560;272;;; +3;560;288;;; +3;560;1040;;; +3;608;368;;; +3;720;912;;; +3;720;928;;; +3;1040;400;;; +3;1040;416;;; +3;1040;528;;; +3;1040;544;;; +3;1248;784;;; +3;1248;800;;; +3;1248;912;;; +3;1248;928;;; +4;48;272;;; +4;48;288;;; +4;48;784;;; +4;48;800;;; +4;48;912;;; +4;48;928;;; +4;416;784;;; +4;416;800;;; +4;576;144;;; +4;576;160;;; +4;576;272;;; +4;576;288;;; +4;576;1040;;; +4;736;912;;; +4;736;928;;; +4;1056;400;;; +4;1056;416;;; +4;1056;528;;; +4;1056;544;;; +4;1264;784;;; +4;1264;800;;; +4;1264;912;;; +4;1264;928;;; +2;160;368;;; +2;160;848;;; +2;176;368;;; +2;176;848;;; +2;320;720;;; +2;336;720;;; +2;480;848;;; +2;496;848;;; +2;640;336;;; +2;640;848;;; +2;656;336;;; +2;656;848;;; +2;800;848;;; +2;816;848;;; +2;960;592;;; +2;976;592;;; +2;1120;848;;; +2;1136;848;;; +15;192;544;;; +15;368;448;;; +15;528;382;;; +16;928;304;;; +18;176;414;;; +18;192;288;;; +18;416;448;;; +18;448;288;;; +199;80;976;compass;eight;d8_compass;; +199;272;464;smallkeyChest;eight;d8_smallkey_4;; +199;272;832;ruby50;;d8_ruby50_0;; +199;464;304;ruby50;;d8_ruby50_1;; +199;544;704;dmap;eight;d8_dmap;; +199;704;176;potion;;d8_potion;; +199;880;864;greenZol;;d8_chest_zol;; +199;1184;176;magicRod;;d8_magic_rod;; +199;1264;960;stonebeak;eight;d8_stoneBeak;; +28;192;320;;;; +28;224;320;;;; +28;240;320;;;; +28;256;320;;;; +28;1152;208;;;; +28;1168;208;;;; +28;1184;208;;;; +28;1200;208;;;; +28;1216;192;;;; +28;1216;208;;;; +28;1232;192;;;; +289;88;176;d8_nkey +289;88;704;d8_spawn_key_0 +289;248;600;d8_spawn_key_5 +289;256;464;d8_smallkey_4 +289;368;496;d8_smallkey_2 +289;864;360;d8_smallkey_3 +289;1048;368;d8_smallkey_6 +289;1080;824;d8_smallkey_1 +261;40;272;;d8_door_19;1; +261;40;288;;d8_door_19;3; +261;40;784;;d8_door_5;1; +261;40;800;;d8_door_5;3; +261;40;912;;d8_door_6;1; +261;40;928;;d8_door_6;3; +261;160;376;;d8_door_16;;d8_door_16 +261;160;856;;d8_door_4;; +261;176;376;1;d8_door_16;2;d8_door_16_key +261;176;856;;d8_door_4;2; +261;320;360;;d8_door_17;; +261;320;728;;d8_door_3;; +261;336;360;;d8_door_17;2; +261;336;728;;d8_door_3;2; +261;408;784;;d8_door_2;1; +261;408;800;;d8_door_2;3; +261;480;856;;d8_door_0;; +261;496;856;;d8_door_0;2; +261;568;144;2;d8_door_20;1; +261;568;160;2;d8_door_20;3; +261;568;272;2;d8_ndoor;1; +261;568;288;3;d8_ndoor;3;d8_ndoor_key +261;640;344;1;d8_door_15;; +261;640;472;;d8_door_18;; +261;640;856;;d8_door_1;; +261;656;344;1;d8_door_15;2;d8_door_15 +261;656;472;;d8_door_18;2; +261;656;856;;d8_door_1;2; +261;728;912;;d8_door_11;1; +261;728;928;;d8_door_11;3; +261;800;856;;d8_door_10;; +261;816;856;;d8_door_10;2; +261;960;600;1;d8_door_12;;d8_door_12 +261;976;600;;d8_door_12;2; +261;1048;400;;d8_door_13;1; +261;1048;416;;d8_door_13;3; +261;1120;856;;d8_door_8;; +261;1136;856;;d8_door_8;2; +261;1240;272;;d8_door_14;1; +261;1240;288;;d8_door_14;3; +261;1256;784;;d8_door_9;1; +261;1256;800;;d8_door_9;3; +261;1256;912;;d8_door_7;1; +261;1256;928;;d8_door_7;3; +174;496;1104;dungeon_8 +153;240;304;;;d8_2d_5L;dungeon8_2d_5.map;d8_2d_5L;;1;False +153;416;288;;;d8_left;overworld.map;d8_left;3;;False +153;512;640;;;d8_2d_1L;dungeon8_2d_1.map;d8_2d_1L;2;1;False +153;568;992;;;d8_blaino_knockout;overworld.map;;3;6;False +153;568;1032;;;d8_vacuum_entry;;;3;6;False +153;568;1048;;;d8;overworld.map;d8;1;; +153;576;336;;;d8_2d_4L;dungeon8_2d_4.map;d8_2d_4L;;1;False +153;720;512;;;d8_2d_3L;dungeon8_2d_3.map;d8_2d_3L;1;1;False +153;768;48;;;d8_2d_2L;dungeon8_2d_2.map;d8_2d_2L;;1;False +153;768;768;;;d8_2d_5R;dungeon8_2d_5.map;d8_2d_5R;-1;1;False +153;896;286;;;d8_right;overworld.map;d8_right;3;;False +153;944;688;;;d8_2d_4R;dungeon8_2d_4.map;d8_2d_4R;;1;False +153;1056;608;;;d8_2d_2R;dungeon8_2d_2.map;d8_2d_2R;3;1;False +153;1152;688;;;d8_2d_6R;dungeon8_2d_6.map;d8_2d_6R;2;1;False +153;1152;1024;;;d8_2d_1R;dungeon8_2d_1.map;d8_2d_1R;2;1;False +153;1168;224;;;d8_2d_3R;dungeon8_2d_3.map;d8_2d_3R;2;1;False +300;568;1040;;;;;; +245;496;1072;eight;; +325;992;464;;;;; +325;1008;448;;;;; +325;1008;464;;;;; +325;1024;480;;;;; +325;1040;464;;;;; +325;1040;480;;;;; +325;1056;480;;;;; +325;1072;464;;;;; +325;1088;464;;;;; +325;1088;480;;;;; +282;992;384; +282;1008;304; +282;1008;320; +282;1008;336; +282;1008;352; +282;1008;384; +282;1024;304; +282;1024;320; +282;1024;336; +282;1024;352; +282;1024;384; +282;1040;304; +282;1040;320; +282;1040;336; +282;1040;352; +282;1056;304; +282;1056;320; +282;1056;336; +282;1056;352; +282;1072;304; +282;1072;320; +282;1072;336; +282;1072;352; +282;1072;384; +282;1088;304; +282;1088;320; +282;1088;336; +282;1088;352; +282;1088;368; +282;1088;384; +282;1104;304; +282;1104;320; +282;1104;336; +282;1104;352; +282;1104;368; +282;1104;384; +328;480;464;;d8_wall_2;;; +328;560;544;;d8_wall_1;3;; +328;608;656;;d8_wall_0;1;; +328;960;480;;d8_wall_5;;; +328;976;480;;d8_wall_5;2;; +329;496;464;;d8_wall_2;2;; +329;560;528;;d8_wall_1;1;; +329;608;672;;d8_wall_0;3;; +329;960;736;;d8_wall_3;;; +329;976;736;;d8_wall_3;2;; +329;1040;784;;d8_wall_4;1;; +329;1040;800;;d8_wall_4;3;; +337;1232;224;d8_switch;True; +337;1248;224;d8_switch;True; +337;1264;224;d8_switch;True; +284;528;1072;;;; +248;976;672;d8_black_room_0;; +332;1048;528 +351;432;418;beak_d8_2 +351;1088;417;beak_d8_1 +351;1152;753;beak_d8_3 +52;176;336;;;;;; +52;400;432;;;;;; +52;544;48;;;;;; +52;544;80;;;;;; +52;544;976;;;;;; +52;592;48;;;;;; +52;592;80;;;;;; +52;592;976;;;;;; +52;800;288;;;;;-8.-10.16.11; +52;800;768;;;;;; +52;800;784;;;;;; +52;800;800;;;;;; +52;816;768;;;;;; +52;816;784;;;;;; +52;816;800;;;;;; +52;832;768;;;;;; +52;832;784;;;;;; +52;832;800;;;;;; +52;928;800;;;;;; +52;944;800;;;;;; +52;944;816;;;;;; +52;944;896;;;;;; +52;944;912;;;;;; +52;960;800;;;;;; +52;960;816;;;;;; +52;960;896;;;;;; +52;960;912;;;;;; +52;976;288;;;;;-8.-10.16.11; +52;992;896;;;;;; +52;1104;816;;;;;; +52;1136;160;;;;;; +52;1280;160;;;;;; +331;1040;720;d8_switch +464;704;1008 +464;752;960 +471;224;512 +471;400;880 +471;1264;688 +480;48;240;27;d8_floor_layer_2 +480;272;720;12;d8_floor_layer_0 +480;704;752;; +480;1088;864;23;d8_floor_layer_1 +475;1040;336 +475;1072;336 +466;544;576 +466;560;464 +466;576;608 +466;608;576 +478;192;592 +478;304;592 +478;352;864 +478;368;832 +478;384;336 +478;400;368 +478;416;864 +478;560;432 +478;592;496 +478;720;464 +478;1184;976 +478;1216;944 +478;1216;992 +478;1248;976 +440;128;1024;dungeon8.map;d8_vacuum_entry; +477;88;720 +477;368;336 +477;568;864 +477;864;576 +428;112;684;1;False; +428;272;868;3;; +428;288;860;1;False; +428;384;468;3;; +428;434;468;3;; +428;704;812;1;False; +428;756;864;2;; +428;912;428;1;False; +428;928;428;1;False; +437;1088;608;True +422;992;560;;3;;2 +422;992;640;;3;2; +422;1104;560;3;;;2 +422;1104;640;3;;2; +424;64;976;; +424;528;704;; +424;560;704;; +424;672;304;; +424;672;320;; +424;704;320;; +424;720;336;; +424;848;480;; +424;848;496;; +424;1008;864;; +424;1024;448;; +424;1024;496;; +424;1024;880;; +424;1072;448;; +424;1072;496;; +424;1200;720;; +424;1216;752;; +252;88;736;d8_et_2 +252;360;360;d8_et_8 +252;424;840;d8_et_1 +252;520;444;d8_et_5 +252;568;824;d8_et_0 +252;720;1016;d8_torch_0 +252;736;1016;d8_spawn_door +252;776;468;d8_et_4 +252;1048;384;d8_et_7 +252;1048;504;d8_et_3 +252;1272;1032;d8_et_6 +22;40;792;;;; +22;416;288;;;; +22;648;856;;;; +22;672;816;;;; +22;672;832;;;; +22;688;832;;;; +22;728;920;;;; +22;768;832;;;; +22;808;856;;;; +22;968;480;;;; +342;32;720;;;;;; +342;32;736;;;;;; +342;48;192;;;;;; +342;48;208;;;;;; +342;48;224;;;;;; +342;64;192;;;;;; +342;64;224;;;;;; +342;64;240;;;;;; +342;64;256;;;;;; +342;80;192;;;;;; +342;80;208;;;;;; +342;80;224;;;;;; +342;80;240;;;;;; +342;80;256;;;;;; +342;80;688;;;;;; +342;80;752;;;;;; +342;80;768;;;;;; +342;96;192;;;;;; +342;96;208;;;;;; +342;96;224;;;;;; +342;96;240;;;;;; +342;96;256;;;;;; +342;96;688;;;;;; +342;96;752;;;;;; +342;96;768;;;;;; +342;112;192;;;;;; +342;112;224;;;;;; +342;112;240;;;;;; +342;112;256;;;;;; +342;128;192;;;;;; +342;128;208;;;;;; +342;128;224;;;;;; +342;128;240;;;;;; +342;128;256;;;;;; +342;144;256;;;;;; +342;144;720;;;;;; +342;144;736;;;;;; +342;192;688;;;;;; +342;192;704;;;;;; +342;192;720;;;;;; +342;192;736;;;;;; +342;192;752;;;;;; +342;192;768;;;;;; +342;192;880;;;;;; +342;208;688;;;;;; +342;208;704;;;;;; +342;208;720;;;;;; +342;208;880;;;;;; +342;224;480;;;;;; +342;224;496;;;;;; +342;224;720;;;;;; +342;224;816;;;;;; +342;224;832;;;;;; +342;224;848;;;;;; +342;224;864;;;;;; +342;224;880;;;;;; +342;240;720;;;;;; +342;240;896;;;;;; +342;256;720;;;;;; +342;256;816;;;;;; +342;256;848;;;;;; +342;272;880;;;;;; +342;288;816;;;;;; +342;288;848;;;;;; +342;304;480;;;;;; +342;304;496;;;;;; +342;304;512;;;;;; +342;304;896;;;;;; +342;880;432;;;;;; +342;880;448;;;;;; +342;880;464;;;;;; +342;880;480;;;;;; +342;880;496;;;;;; +342;880;512;;;;;; +342;896;464;;;;;; +342;896;512;;;;;; +342;992;816;;;;;; +342;992;832;;;;;; +342;1008;816;;;;;; +342;1008;832;;;;;; +342;1008;848;;;;;; +342;1024;816;;;;;; +342;1024;832;;;;;; +342;1024;848;;;;;; +342;1024;864;;;;;; +342;1040;832;;;;;; +342;1040;848;;;;;; +342;1040;864;;;;;; +342;1040;880;;;;;; +342;1056;848;;;;;; +342;1056;864;;;;;; +342;1056;880;;;;;; +342;1056;896;;;;;; +342;1072;864;;;;;; +342;1072;880;;;;;; +342;1072;896;;;;;; +342;1088;880;;;;;; +342;1088;896;;;;;; +342;1104;896;;;;;; +342;1152;720;;;;;; +342;1152;736;;;;;; +342;1168;736;;;;;; +342;1168;752;;;;;; +342;1184;752;;;;;; +342;1200;688;;;;;; +342;1200;704;;;;;; +342;1200;944;;;;;; +342;1200;960;;;;;; +342;1200;992;;;;;; +342;1200;1008;;;;;; +342;1216;688;;;;;; +342;1216;704;;;;;; +342;1216;720;;;;;; +342;1216;736;;;;;; +342;1216;768;;;;;; +342;1232;688;;;;;; +342;1232;704;;;;;; +342;1232;720;;;;;; +342;1232;736;;;;;; +342;1232;768;;;;;; +342;1232;960;;;;;; +342;1248;688;;;;;; +342;1248;704;;;;;; +342;1248;720;;;;;; +342;1248;736;;;;;; +342;1248;960;;;;;; +208;404;434;d8_statue_eye;16;False;8; +340;528;496;;;;;; +340;544;448;;;;;; +340;576;480;;;;;; +340;608;512;;;;;; +340;624;496;;;;;; +343;512;464; +343;560;512; +343;624;472; +200;208;896;w;;heart;; +200;368;592;w;;bomb_10;; +200;368;624;w;;heart_3;; +200;384;608;w;;arrow;; +200;512;336;w;;arrow;; +200;568;72;;d8_instrument;instrument7;; +200;736;864;w;;powder_10;; +200;752;208;w;;bomb_10;; +200;752;240;w;;heart_3;; +200;768;192;w;;powder_10;; +200;768;224;w;;arrow;; +200;912;592;w;;heart_3;; +200;944;768;w;;heart_3;; +200;1040;848;w;;heart_3;; +200;1056;320;w;;powder;; +200;1072;304;w;;heart_3;; +200;1104;464;w;;bomb_10;; +162;192;320;;18;;8;;;;; +162;192;576;;18;80;8;;;;; +162;208;352;;18;;8;;;;; +162;224;320;;18;48;8;;;;; +162;272;560;18;2;8;;;;;; +162;288;336;18;;8;;;;;; +162;352;320;;18;32;8;;;;; +162;384;304;18;2;8;;;;;; +162;440;304;-18;2;8;32;;;;; +162;448;336;;18;32;8;;;;; +162;536;64;-18;2;8;;;;;; +162;600;432;-18;2;8;;;;;; +162;608;64;18;2;8;;;;;; +162;624;448;;18;;8;;;;; +162;672;448;;18;;8;;;;; +162;696;192;-18;2;8;;;;;; +162;696;256;-18;2;8;64;;;;; +162;696;496;-18;2;8;;;;;; +162;704;208;;18;;8;;;;; +162;704;248;;-18;;8;;;;; +162;704;448;;18;64;8;;;;; +162;704;488;;-18;48;8;;;;; +162;720;192;18;2;8;;;;;; +162;720;256;18;2;8;;;;;; +162;720;304;18;2;8;;;;;; +162;752;496;18;2;8;;;;;; +162;768;816;;18;32;8;;;;; +162;784;448;;18;;8;;;;; +162;784;760;;-18;;8;;;;; +162;792;304;-18;;8;64;;;;; +162;832;648;;-18;;8;;;;; +162;864;648;;-18;;8;;;;; +162;864;704;;18;;8;;;;; +162;880;688;18;2;8;;;;;; +162;896;760;;-18;;8;;;;; +162;896;816;;18;32;8;;;;; +162;928;768;18;2;8;;;;;; +162;992;304;18;;8;;;;;; +162;1016;720;-18;2;8;32;;;;; +162;1024;712;;-18;48;8;;;;; +162;1024;752;;18;;8;;;;; +162;1056;752;;18;;8;;;;; +162;1072;720;18;2;8;32;;;;; +162;1152;208;;18;64;8;;;;; +162;1152;256;;18;32;8;;;;; +162;1192;272;-18;;8;8;;;;; +162;1200;288;;18;;8;;;;; +162;1232;192;;18;;8;;;;; +162;1232;240;;18;;8;;;;; +162;1264;240;;18;;8;;;;; +168;-8;280;d8_door_19;(!d8_enter_6|d8_cue); +168;-8;792;d8_door_5;!d8_enter_mboss_bone|d8_mboss_bone; +168;-8;920;d8_door_6;!d8_enter_mboss_bone|d8_mboss_bone; +168;152;424;d8_door_16;d8_door_16_key&(!d8_enter_6|d8_cue); +168;168;920;d8_door_4;!d8_enter_mboss_bone|d8_mboss_bone; +168;248;632;d8_lamp_spawn;d8_lamp_0&d8_lamp_1;False +168;328;336;d8_door_17;d8_et_8; +168;328;752;d8_door_3;!d8_enter_1|d8_hinox; +168;432;792;d8_door_2;(d8_et_1|!d8_enter_0)&(!d8_enter_1|d8_hinox); +168;488;880;d8_door_0;d8_et_0; +168;592;152;d8_door_20;(!d8_enter_7|d8_nightmareHeart)&(!d8_enter_I|d8_instrument); +168;592;280;d8_ndoor;d8_ndoor_key&(!d8_enter_7|d8_nightmareHeart); +168;648;496;d8_door_18;(d8_et_4|d8_enter_3)&(d8_et_5|!d8_enter_3); +168;648;880;d8_door_1;d8_et_0; +168;752;920;d8_door_11;!d8_enter_2|d8_button_0; +168;808;880;d8_door_10;!d8_enter_2|d8_button_0; +168;944;336;d8_snakes_killed;d8_snake_0&d8_snake_1; +168;1024;408;d8_door_13;d8_et_3|!d8_enter_8; +168;1040;688;d8_black_room_0;d8_wall_3|d8_wall_4; +168;1128;832;d8_door_8;!d8_enter_mboss_smasher|d8_smasher; +168;1288;792;d8_door_9;(!d8_enter_mboss_smasher|d8_smasher)&(!d8_enter_5|d8_button_1); +168;1288;920;d8_door_7;(!d8_enter_mboss_smasher|d8_smasher)&(!d8_enter_4|d8_et_6); +168;1304;280;d8_door_14;d8_blaino; +334;624;432;d8_keyhole_block_0 +334;720;496;d8_keyhole_block_1 +334;752;576;d8_keyhole_block_3 +334;832;512;d8_keyhole_block_2 +167;128;424;d8_enter_6;0 +167;168;936;d8_enter_mboss_bone;0 +167;376;360;d8_et_8;0 +167;384;792;d8_enter_1;0 +167;440;840;d8_et_1;0 +167;472;152;d8_enter_I; +167;472;264;d8_enter_7;0 +167;488;920;d8_enter_0;0 +167;520;460;d8_et_5;0 +167;520;476;d8_enter_3;0 +167;648;832;d8_enter_2;0 +167;680;792;d8_button_0;0 +167;776;508;d8_et_4;0 +167;1000;408;d8_et_3;0 +167;1088;848;d8_floor_layer_1;0 +167;1144;496;d8_enter_8;0 +167;1152;640;d8_enter_5;0 +167;1168;1064;d8_enter_4;0 +167;1272;1064;d8_et_6;0 +167;1304;728;d8_button_1;0 +167;1304;848;d8_smasher;0 +167;1304;872;d8_enter_mboss_smasher;0 +303;64;208;;;;; +303;112;208;;;;; +303;192;640;;;;True;d8_lamp_0 +303;208;736;;;;; +303;304;640;;;;True;d8_lamp_1 +303;512;48;;;;; +303;512;128;;;;; +303;512;512;;;;; +303;528;320;;;;; +303;528;560;;;;; +303;576;448;;;;; +303;608;320;;;;; +303;608;560;;;;; +303;624;48;;;;; +303;624;128;;;;; +303;672;1024;;;;; +303;688;432;;;;True; +303;768;432;;;;True; +303;784;1024;;;;; +303;848;464;;;;True; +303;928;464;;;;True; +295;48;320 +295;48;336 +295;48;352 +295;48;368 +295;64;320 +295;64;336 +295;64;352 +295;64;368 +295;64;384 +295;80;320 +295;80;336 +295;80;352 +295;80;368 +295;96;320 +295;96;336 +295;96;352 +295;96;368 +295;112;304 +295;112;320 +295;112;336 +295;112;352 +295;112;368 +295;128;320 +295;128;336 +295;128;352 +295;128;368 +295;352;896 +295;368;896 +295;384;432 +295;384;864 +295;384;880 +295;384;896 +295;400;400 +295;400;416 +295;400;448 +295;400;864 +295;400;896 +295;416;432 +295;416;896 +295;432;560 +295;432;576 +295;432;592 +295;432;608 +295;432;624 +295;432;640 +295;432;896 +295;448;560 +295;448;576 +295;448;896 +295;464;384 +295;464;400 +295;464;416 +295;464;432 +295;464;448 +295;464;464 +295;464;480 +295;464;496 +295;464;512 +295;464;528 +295;464;544 +295;464;560 +295;464;576 +295;464;816 +295;464;896 +295;480;384 +295;480;560 +295;480;576 +295;480;816 +295;496;384 +295;496;560 +295;496;576 +295;496;816 +295;512;176 +295;512;192 +295;512;208 +295;512;224 +295;512;240 +295;512;304 +295;512;752 +295;512;768 +295;512;784 +295;512;800 +295;512;816 +295;528;176 +295;528;192 +295;528;208 +295;528;224 +295;528;240 +295;528;304 +295;528;752 +295;528;768 +295;528;816 +295;544;192 +295;544;208 +295;544;224 +295;544;240 +295;544;304 +295;544;320 +295;544;336 +295;544;352 +295;544;368 +295;544;560 +295;544;752 +295;544;816 +295;544;832 +295;544;848 +295;560;192 +295;560;208 +295;560;224 +295;560;240 +295;560;368 +295;560;560 +295;560;752 +295;560;848 +295;576;192 +295;576;208 +295;576;224 +295;576;240 +295;576;368 +295;576;560 +295;576;752 +295;576;848 +295;592;192 +295;592;208 +295;592;224 +295;592;240 +295;592;304 +295;592;320 +295;592;336 +295;592;352 +295;592;368 +295;592;560 +295;592;752 +295;592;816 +295;592;832 +295;592;848 +295;608;176 +295;608;192 +295;608;208 +295;608;224 +295;608;240 +295;608;304 +295;608;752 +295;608;816 +295;624;304 +295;624;752 +295;624;816 +295;640;384 +295;640;752 +295;656;384 +295;656;752 +295;672;176 +295;672;192 +295;672;208 +295;672;224 +295;672;240 +295;672;368 +295;672;384 +295;672;560 +295;672;720 +295;672;816 +295;672;832 +295;688;224 +295;688;336 +295;688;352 +295;688;368 +295;688;384 +295;688;560 +295;688;688 +295;688;704 +295;688;720 +295;688;736 +295;688;752 +295;688;832 +295;704;224 +295;704;384 +295;704;560 +295;704;688 +295;704;704 +295;704;720 +295;704;736 +295;720;224 +295;720;368 +295;720;384 +295;720;560 +295;720;704 +295;720;720 +295;720;736 +295;720;752 +295;736;352 +295;736;368 +295;736;384 +295;736;560 +295;736;688 +295;736;704 +295;736;720 +295;736;736 +295;736;752 +295;736;768 +295;752;304 +295;752;320 +295;752;336 +295;752;352 +295;752;368 +295;752;384 +295;752;560 +295;752;704 +295;752;720 +295;752;736 +295;768;352 +295;768;368 +295;768;384 +295;768;560 +295;768;688 +295;768;704 +295;768;720 +295;768;736 +295;768;832 +295;784;352 +295;784;368 +295;784;384 +295;784;560 +295;784;720 +295;784;736 +295;832;560 +295;832;896 +295;848;560 +295;848;896 +295;864;560 +295;880;560 +295;896;560 +295;912;560 +295;912;576 +295;912;592 +295;912;608 +295;912;832 +295;912;848 +295;912;864 +295;912;880 +295;912;896 +295;928;560 +295;944;560 +170;160;376;d8_enter_6;;;; +170;160;856;d8_enter_mboss_bone;;32;; +170;192;784;d8_leave_0;3;32;; +170;224;448;d8_leave_1;1;;; +170;240;672;d8_leave_0;1;32;; +170;320;448;d8_leave_1;2;;; +170;320;728;d8_leave_0;2;32;; +170;408;784;d8_enter_1;1;;; +170;408;800;d8_enter_0;3;;; +170;480;464;d8_enter_3;;;;True +170;480;856;d8_enter_0;;;; +170;496;464;d8_enter_3;2;;; +170;560;528;d8_enter_3;1;;; +170;560;544;d8_enter_3;3;;;True +170;568;144;d8_enter_I;1;;; +170;568;272;d8_enter_7;1;;; +170;608;672;d8_leave_1;1;;; +170;624;720;d8_leave_1;2;;; +170;640;472;d8_enter_3;;;; +170;640;856;d8_enter_2;;;;True +170;648;432;d8_enter_3;2;;;True +170;656;856;d8_enter_2;2;;; +170;672;640;d8_leave_2;;;; +170;672;656;d8_leave_2;3;32;; +170;728;912;d8_enter_2;1;;; +170;768;816;d8_enter_2;3;32;; +170;800;856;d8_enter_2;;;; +170;1048;528;d8_enter_8;1;;; +170;1136;856;d8_enter_mboss_smasher;2;;; +170;1146;682;d8_enter_5;2;;; +170;1146;1030;d8_enter_4;2;;; +170;1256;784;d8_enter_5;1;;; +170;1256;800;d8_enter_mboss_smasher;3;;; +170;1256;912;d8_enter_mboss_smasher;1;;; +170;1256;928;d8_enter_4;3;;; +10;80;1008;;; +10;96;1008;;; +10;192;608;;; +10;208;608;;; +10;224;608;;; +10;272;608;;; +10;288;608;;; +10;304;608;;; +10;800;304;;; +10;816;304;;; +10;832;304;;; +10;848;304;;; +10;864;304;;; +10;880;304;;; +10;896;304;;; +10;912;304;;; +10;944;352;;; +11;48;1008;;; +11;64;960;;; +11;80;960;;; +11;96;960;;; +11;192;414;;; +11;208;288;;; +11;208;414;;; +11;208;544;;; +11;224;288;;; +11;224;414;;; +11;224;544;;; +11;240;288;;; +11;240;544;;; +11;464;288;;; +11;512;320;;; +11;544;382;;; +11;560;382;;; +11;576;382;;; +11;592;382;;; +11;624;320;;; +11;672;414;;; +11;688;414;;; +11;704;414;;; +11;752;414;;; +11;768;414;;; +11;784;414;;; +12;48;976;;; +12;48;992;;; +12;112;960;;; +12;176;416;;; +12;176;432;;; +12;176;448;;; +12;176;464;;; +12;176;480;;; +12;176;496;;; +12;176;512;;; +12;176;528;;; +12;176;544;;; +12;192;304;;; +12;272;624;;; +12;272;640;;; +12;432;432;;; +12;560;304;;; +12;560;320;;; +12;560;336;;; +12;608;336;;; +12;608;352;;; +12;608;368;;; +12;928;320;;; +12;928;336;;; +13;112;992;;; +13;192;432;;; +13;192;448;;; +13;192;464;;; +13;192;480;;; +13;192;496;;; +13;192;512;;; +13;192;528;;; +13;224;624;;; +13;224;640;;; +13;256;304;;; +13;368;432;;; +13;480;304;;; +13;528;336;;; +13;528;352;;; +13;528;368;;; +13;576;304;;; +13;576;320;;; +25;192;576;;;; +25;208;352;;;; +25;208;432;;;; +25;208;448;;;; +25;208;464;;;; +25;208;480;;;; +25;208;496;;;; +25;208;512;;;; +25;208;528;;;; +25;208;576;;;; +25;224;352;;;; +25;224;528;;;; +25;224;576;;;; +25;240;432;;;; +25;240;528;;;; +25;240;576;;;; +25;256;432;;;; +25;256;528;;;; +25;256;576;;;; +25;272;432;;;; +25;272;544;;;; +25;272;560;;;; +25;272;576;;;; +25;288;320;;;; +25;288;336;;;; +25;288;352;;;; +25;288;368;;;; +25;288;432;;;; +25;304;432;;;; +25;320;320;;;; +25;320;336;;;; +25;320;344;;;; +25;320;432;;;; +25;336;320;;;; +25;336;336;;;; +25;336;344;;;; +25;336;432;;;; +25;352;320;;;; +25;368;320;;;; +25;384;304;;;; +25;384;320;;;; +25;432;304;;;; +25;432;320;;;; +25;432;336;;;; +25;448;336;;;; +25;464;336;;;; +25;528;64;;;; +25;528;80;;;; +25;528;96;;;; +25;544;96;;;; +25;592;96;;;; +25;592;432;;;; +25;592;448;;;; +25;608;64;;;; +25;608;80;;;; +25;608;96;;;; +25;624;448;;;; +25;640;448;;;; +25;640;456;;;; +25;656;400;;;; +25;656;448;;;; +25;656;456;;;; +25;672;400;;;; +25;672;448;;;; +25;688;176;;;; +25;688;192;;;; +25;688;208;;;; +25;688;240;;;; +25;688;256;;;; +25;688;272;;;; +25;688;288;;;; +25;688;304;;;; +25;688;320;;;; +25;688;400;;;; +25;688;480;;;; +25;688;496;;;; +25;704;208;;;; +25;704;240;;;; +25;704;400;;;; +25;704;448;;;; +25;704;480;;;; +25;720;176;;;; +25;720;192;;;; +25;720;208;;;; +25;720;240;;;; +25;720;256;;;; +25;720;272;;;; +25;720;288;;;; +25;720;304;;;; +25;720;320;;;; +25;720;400;;;; +25;720;448;;;; +25;720;480;;;; +25;736;400;;;; +25;736;448;;;; +25;736;480;;;; +25;752;400;;;; +25;752;448;;;; +25;752;480;;;; +25;752;496;;;; +25;752;752;;;; +25;752;768;;;; +25;752;784;;;; +25;752;800;;;; +25;752;816;;;; +25;768;400;;;; +25;768;816;;;; +25;784;304;;;; +25;784;320;;;; +25;784;400;;;; +25;784;448;;;; +25;784;752;;;; +25;784;816;;;; +25;800;320;;;; +25;800;640;;;; +25;800;656;;;; +25;800;672;;;; +25;800;752;;;; +25;816;320;;;; +25;816;640;;;; +25;816;672;;;; +25;816;688;;;; +25;816;752;;;; +25;832;320;;;; +25;832;640;;;; +25;832;752;;;; +25;848;320;;;; +25;848;688;;;; +25;848;704;;;; +25;848;752;;;; +25;864;320;;;; +25;864;640;;;; +25;864;704;;;; +25;864;752;;;; +25;880;320;;;; +25;880;640;;;; +25;880;656;;;; +25;880;672;;;; +25;880;688;;;; +25;880;704;;;; +25;880;752;;;; +25;896;320;;;; +25;896;752;;;; +25;896;816;;;; +25;912;320;;;; +25;912;336;;;; +25;912;352;;;; +25;912;368;;;; +25;912;816;;;; +25;928;368;;;; +25;928;752;;;; +25;928;768;;;; +25;928;784;;;; +25;944;368;;;; +25;992;304;;;; +25;1008;704;;;; +25;1008;720;;;; +25;1008;736;;;; +25;1008;752;;;; +25;1024;704;;;; +25;1024;752;;;; +25;1040;704;;;; +25;1056;704;;;; +25;1056;752;;;; +25;1072;704;;;; +25;1072;720;;;; +25;1072;736;;;; +25;1072;752;;;; +25;1152;256;;;; +25;1168;256;;;; +25;1184;256;;;; +25;1184;272;;;; +25;1184;288;;;; +25;1200;288;;;; +25;1216;240;;;; +25;1216;256;;;; +25;1216;272;;;; +25;1216;288;;;; +25;1224;272;;;; +25;1224;288;;;; +25;1232;240;;;; +25;1256;272;;;; +25;1256;288;;;; +25;1264;240;;;; +25;1264;272;;;; +25;1264;288;;;; +511;1208;344;d8_blaino;d8_blaino_knockout +502;32;304;d8_cue;d8_enter_6 +500;848;336;d8_snake_0;;True +500;896;368;d8_snake_1;;True +498;400;720;d8_hinox;2 +506;1192;848;d8_smasher +496;32;856;d8_enter_mboss_bone;d8_mboss_bone +223;48;960;0;;;;;;; +223;224;704;0;;;;;;; +223;224;736;0;;;;;;; +223;240;448;0;;;;;;; +223;240;704;0;;;;;;; +223;240;736;0;;;;;;; +223;256;480;;;;;;;;d8_leave_1 +223;256;704;0;;;;;;; +223;256;736;0;;;;;;; +223;272;480;;;;;;;;d8_leave_1 +223;272;704;0;;;;;;; +223;272;736;0;;;;;;; +223;288;448;0;;;;;;; +223;288;688;;;;;;;;d8_leave_0 +223;288;752;;;;;;;;d8_leave_0 +223;368;480;0;;;;;;; +223;368;864;0;;;;;;; +223;384;480;0;;;;;;; +223;400;832;0;;;;;;; +223;416;480;0;;;;;;; +223;416;560;;;;;;;; +223;416;576;;;;;;;; +223;416;592;;;;;;;; +223;416;608;;;;;;;; +223;416;624;;;;;;;; +223;416;640;;;;;;;; +223;432;480;0;;;;;;; +223;432;864;0;;;;;;; +223;512;608;0;;;;;;; +223;512;736;0;;;;;;; +223;528;608;0;;;;;;; +223;528;736;0;;;;;;; +223;544;464;0;;;;;;; +223;544;624;0;;;;;;; +223;544;736;0;;;;;;; +223;560;624;0;;;;;;; +223;560;736;0;;;;;;; +223;576;512;0;;;;;;; +223;576;624;0;;;;;;; +223;576;736;0;;;;;;; +223;592;624;0;;;;;;; +223;592;688;;;;;;;;d8_leave_1 +223;592;704;;;;;;;;d8_leave_1 +223;592;720;;;;;;;;d8_leave_1 +223;592;736;0;;;;;;; +223;608;416;0;;;;;;; +223;608;480;0;;;;;;; +223;608;624;0;;;;;;; +223;608;736;;;;;;;; +223;624;416;0;;;;;;; +223;624;624;0;;;;;;; +223;624;688;0;;;;;;; +223;624;704;0;;;;;;; +223;624;736;;;;;;;; +223;640;416;0;;;;;;; +223;640;624;0;;;;;;; +223;640;704;0;;;;;;; +223;640;736;;;;;;;; +223;656;416;0;;;;;;; +223;656;624;0;;;;;;; +223;656;704;0;;;;;;; +223;656;736;;;;;;;; +223;672;624;0;;;;;;; +223;672;704;0;;;;;;; +223;672;736;;;;;;;; +223;688;640;;;;;;;;d8_leave_2 +223;704;512;0;;;;;;; +223;704;528;0;;;;;;; +223;704;656;0;;;;;;; +223;704;672;0;;;;;;; +223;720;416;0;;;;;;; +223;720;528;0;;;;;;; +223;720;688;;;;;;;; +223;736;416;0;;;;;;; +223;736;512;0;;;;;;; +223;736;528;0;;;;;;; +223;736;640;0;;;;;;; +223;736;656;0;;;;;;; +223;736;672;0;;;;;;; +223;752;688;;;;;;;; +223;768;624;0;;;;;;; +223;768;640;0;;;;;;; +223;768;656;0;;;;;;; +223;768;672;0;;;;;;; +223;784;704;;;;;;;; +223;800;416;0;;;;;;; +223;800;432;0;;;;;;; +223;800;688;0;;;;;;; +223;800;720;0;;;;;;; +223;816;656;0;;;;;;; +223;816;720;0;;;;;;; +223;832;608;0;;;;;;; +223;832;720;0;;;;;;; +223;848;608;0;;;;;;; +223;864;464;;;;;;;; +223;864;480;;;;;;;; +223;864;496;;;;;;;; +223;864;512;;;;;;;; +223;864;608;0;;;;;;; +223;864;784;0;;;;;;; +223;864;800;0;;;;;;; +223;880;608;0;;;;;;; +223;880;624;0;;;;;;; +223;880;768;0;;;;;;; +223;880;784;0;;;;;;; +223;880;800;0;;;;;;; +223;1008;368;0;;;;;;; +223;1024;368;0;;;;;;; +223;1040;368;0;;;;;;; +223;1056;368;0;;;;;;; +223;1056;832;0;;;;;;; +223;1072;368;0;;;;;;; +223;1072;848;0;;;;;;; +223;1184;688;;;;;;;; +223;1200;240;0;;;;;;; +223;1216;224;0;;;;;;; +287;528;1104;89 +522;560;208;d8_nightmare +164;424;360;d8_et_8;1;dialogBox;sound_secrete; +164;432;824;d8_et_1;1;dialogBox;sound_secrete; +164;472;128;d8_enter_I;1;dialogBox;d8_instrument_music; +164;552;488;d8_et_5;1;dialogBox;sound_secrete; +164;568;808;d8_et_0;1;dialogBox;d8_et_0_sound; +164;568;984;d8_blaino;1;dungeonTeleporter;.d8_teleport; +164;696;792;d8_button_0;1;dialogBox;sound_secrete; +164;776;488;d8_et_4;1;dialogBox;sound_secrete; +164;1144;472;d8_et_3;1;dialogBox;sound_secrete; +164;1208;344;d8_blaino;1;dungeonTeleporter;.d8_teleport; +164;1256;1016;d8_et_6;1;dialogBox;sound_secrete; +164;1304;744;d8_button_1;1;dialogBox;sound_secrete; +166;48;720;d8_et_2;1;d8_spawn_key_0 +166;144;192;d8_floor_layer_2;1;d8_spawn_chest_3 +166;304;576;d8_lamp_spawn;1;d8_spawn_chest_2 +166;304;704;d8_floor_layer_0;1;d8_spawn_chest_0 +166;368;464;d8_statue_eye;1;d8_spawn_key_2 +166;784;944;d8_spawn_door;1;d8_secret_door +166;944;320;d8_snakes_killed;1;d8_spawn_chest_1 +166;1008;848;d8_floor_layer_1;1;d8_spawn_key_1 +166;1048;384;d8_et_7;1;d8_spawn_key_3 +231;368;384;;arrow_1;;;; +231;384;384;;;;;; +231;416;384;;fairy;;;; +231;432;384;;arrow_1;;;; +231;448;384;;;;;; +231;672;896;;;;;; +231;672;960;;;;;; +231;672;992;;;;;; +231;688;816;;;;;; +231;688;848;;;;;; +231;688;864;;;;;; +231;688;896;;;;;; +231;704;848;;;;;; +231;704;864;;;;;; +231;720;816;;;;;; +231;720;832;;;;;; +231;720;864;;;;;; +231;720;880;;;;;; +231;736;816;;;;;; +231;736;832;;;;;; +231;736;848;;;;;; +231;736;880;;;;;; +231;752;832;;;;;; +231;752;880;;;;;; +231;768;848;;;;;; +231;768;864;;;;;; +231;784;896;;fairy;;;; +231;784;960;;;;;; +231;784;992;;;;;; +231;1024;576;;;;;; +231;1024;592;;;;;; +231;1024;608;;;;;; +231;1024;624;;;;;; +231;1040;608;;;;;; +231;1056;592;;;;;; +231;1072;576;;;;;; +231;1072;592;;;;;; +231;1072;608;;;;;; +231;1072;624;;;;;; +231;1184;1008;;;;;; +231;1200;976;;;;;; +231;1216;976;;;;;; +231;1232;944;;;;;; +231;1264;736;;;;;; +249;176;544;0.6;0.1 +249;656;416;0.6;0.1 +249;816;416;0.6;0.1 +160;192;352; +160;208;320; +160;224;432; +160;304;320; +160;560;96; +160;576;96; +160;608;448; +160;688;448; +160;704;320; +160;768;448; +160;768;752; +160;832;688; +160;848;640; +160;912;752; +160;1040;752; +160;1248;192; +160;1248;240; +321;16;832;;3;;; +321;16;880;;3;;; +321;48;672;;;;; +321;64;928;;;;; +321;64;1040;;2;;; +321;96;928;;;;; +321;96;1040;;2;;; +321;128;672;;;;; +321;160;832;;1;;; +321;160;880;;1;;; +321;1184;672;;;;; +321;1200;928;;;;; +321;1216;288;;;;; +321;1232;192;;;;; +321;1232;240;;;;; +321;1232;672;;;;; +321;1232;928;;;;; +321;1264;192;;;;; +321;1264;240;;;;; +321;1264;288;;;;; +461;672;1024;d8_torch_0 +461;784;1024;d8_torch_0 +246;176;416; +246;176;432; +246;176;448; +246;176;464; +246;176;480; +246;176;496; +246;176;512; +246;176;528; +246;176;544; +246;176;560; +246;192;336; +246;192;352; +246;192;416; +246;192;432; +246;192;448; +246;192;464; +246;192;480; +246;192;496; +246;192;512; +246;192;528; +246;192;544; +246;192;560; +246;208;336; +246;208;416; +246;208;544; +246;208;560; +246;224;336; +246;224;416; +246;224;432; +246;224;544; +246;224;560; +246;240;336; +246;240;544; +246;240;560; +246;256;336; +246;256;544; +246;256;560; +246;272;336; +246;288;304; +246;304;304; +246;320;304; +246;336;304; +246;352;304; +246;368;304; +246;448;288; +246;448;304; +246;448;320; +246;464;288; +246;464;304; +246;464;320; +246;480;288; +246;480;304; +246;480;320; +246;544;64; +246;544;80; +246;560;48; +246;560;64; +246;560;80; +246;560;96; +246;576;48; +246;576;64; +246;576;80; +246;576;96; +246;592;64; +246;592;80; +246;608;432; +246;608;448; +246;624;432; +246;640;432; +246;656;416; +246;656;432; +246;672;416; +246;672;432; +246;688;416; +246;688;448; +246;704;192; +246;704;256; +246;704;272; +246;704;288; +246;704;304; +246;704;320; +246;704;416; +246;704;432; +246;704;496; +246;720;432; +246;720;496; +246;720;512; +246;736;432; +246;736;496; +246;752;416; +246;752;432; +246;768;416; +246;768;448; +246;768;752; +246;768;768; +246;768;784; +246;768;800; +246;784;416; +246;784;432; +246;784;768; +246;784;784; +246;784;800; +246;800;304; +246;816;304; +246;832;304; +246;832;656; +246;832;672; +246;832;688; +246;848;304; +246;848;640; +246;848;656; +246;848;672; +246;864;304; +246;864;656; +246;864;672; +246;864;688; +246;880;304; +246;896;304; +246;896;768; +246;896;784; +246;896;800; +246;912;304; +246;912;752; +246;912;768; +246;912;784; +246;912;800; +246;928;304; +246;928;320; +246;928;336; +246;928;352; +246;944;304; +246;944;320; +246;944;336; +246;944;352; +246;960;304; +246;976;304; +246;1024;720; +246;1024;736; +246;1040;720; +246;1040;736; +246;1040;752; +246;1056;720; +246;1056;736; +246;1152;224; +246;1152;240; +246;1168;224; +246;1168;240; +246;1184;224; +246;1184;240; +246;1200;224; +246;1232;208; +246;1232;224; +246;1248;208; +246;1248;224; +246;1248;240; +246;1264;208; +246;1264;224; +247;192;288; +247;192;304; +247;208;288; +247;208;304; +247;208;320; +247;224;288; +247;224;304; +247;240;288; +247;240;304; +247;256;288; +247;256;304; +247;1152;192; +247;1168;176; +247;1168;192; +247;1184;176; +247;1184;192; +247;1200;176; +247;1200;192; +247;1216;176; +247;1232;176; +247;1248;176; +247;1248;192; diff --git a/bin/Data/Maps/dungeon8.map.data b/bin/Data/Maps/dungeon8.map.data new file mode 100644 index 0000000..4acddd5 --- /dev/null +++ b/bin/Data/Maps/dungeon8.map.data @@ -0,0 +1,69 @@ +83 +67 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon8_2d_1.map b/bin/Data/Maps/dungeon8_2d_1.map new file mode 100644 index 0000000..62f69b4 --- /dev/null +++ b/bin/Data/Maps/dungeon8_2d_1.map @@ -0,0 +1,657 @@ +3 +1 +1 +tileset 2d.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,74,66,84,78,78,78,78,78,78,78,84,78,78,78,78,78,78,74,66,75,, +,74,66,113,101,86,101,86,101,86,101,113,84,78,78,78,78,78,84,66,75,, +,74,66,113,113,101,113,101,113,101,113,113,113,80,84,84,84,79,113,66,75,, +,74,66,113,113,113,113,113,113,113,113,113,104,104,104,104,104,104,113,66,75,, +,74,73,70,113,113,113,73,113,113,113,113,113,113,113,113,113,104,113,66,75,, +,78,78,74,113,73,113,78,113,71,73,73,70,113,113,113,113,113,71,73,75,, +,78,78,74,,78,,78,,75,78,78,74,,,,,,75,78,78,, +,78,78,74,112,78,112,78,112,75,78,78,74,112,112,112,112,112,75,78,78,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,0,0, +0,3,,,,,,,,,,,,,,,,,,,4,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,1,,,,,,,,,,,,,,,,,,,2,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +95 +0;16;16;;; +0;16;32;;; +0;16;48;;; +0;16;64;;; +0;32;80;;; +0;48;16;;; +0;48;80;;; +0;48;96;;; +0;48;112;;; +0;48;128;;; +0;64;16;;; +0;80;16;;; +0;80;96;;; +0;80;112;;; +0;80;128;;; +0;96;16;;; +0;112;16;;; +0;112;80;;; +0;112;96;;; +0;112;112;;; +0;112;128;;; +0;128;16;;; +0;144;16;;; +0;144;96;;; +0;144;112;;; +0;144;128;;; +0;160;16;;; +0;160;96;;; +0;176;16;;; +0;176;96;;; +0;192;32;;; +0;192;96;;; +0;192;112;;; +0;192;128;;; +0;208;48;;; +0;224;48;;; +0;240;48;;; +0;256;48;;; +0;272;48;;; +0;288;16;;; +0;288;32;;; +0;288;96;;; +0;288;112;;; +0;288;128;;; +0;304;96;;; +0;320;16;;; +0;320;32;;; +0;320;48;;; +0;320;64;;; +0;320;80;;; +286;-8;40;;;; +153;32;8;;;d8_2d_1L;dungeon8.map;d8_2d_1L;3;;False +153;304;8;;;d8_2d_1R;dungeon8.map;d8_2d_1R;3;;False +300;32;16;;;;;; +300;64;112;;;;;; +300;96;112;;;;;; +300;128;112;;;;;; +300;208;112;;;;;; +300;224;112;;;;;; +300;240;112;;;;;; +300;256;112;;;;;; +300;272;112;;;;;; +300;304;16;;;;;; +258;32;16; +258;32;32; +258;32;48; +258;32;64; +258;192;64; +258;208;64; +258;224;64; +258;240;64; +258;256;64; +258;272;64; +258;272;80; +258;304;16; +258;304;32; +258;304;48; +258;304;64; +258;304;80; +259;192;64; +492;64;112;850 +492;96;112; +492;128;112;1500 +492;224;112;650 +492;256;112;900 +295;64;112;;;;;; +295;96;112;;;;;; +295;128;112;;;;;; +295;208;112;;;;;; +295;224;112;;;;;; +295;240;112;;;;;; +295;256;112;;;;;; +295;272;112;;;;;; +257;-8;16 +287;-8;64;32 diff --git a/bin/Data/Maps/dungeon8_2d_1.map.data b/bin/Data/Maps/dungeon8_2d_1.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/dungeon8_2d_1.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon8_2d_2.map b/bin/Data/Maps/dungeon8_2d_2.map new file mode 100644 index 0000000..d675859 --- /dev/null +++ b/bin/Data/Maps/dungeon8_2d_2.map @@ -0,0 +1,659 @@ +3 +1 +1 +tileset 2d.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,78,78,78,78,78,78,84,84,84,84,84,84,84,78,78,78,84,84,84,78,, +,78,78,78,86,101,101,113,113,113,113,113,113,113,101,86,101,113,113,96,78,, +,78,74,101,101,113,113,113,71,73,73,73,104,104,113,101,113,113,113,104,75,, +,78,78,73,113,113,73,113,80,84,84,84,95,104,113,113,113,113,113,104,75,, +,78,101,84,84,84,84,113,113,113,113,113,113,113,113,113,113,113,73,104,75,, +,78,113,113,113,113,113,113,113,113,113,113,113,73,113,113,113,113,74,104,75,, +,78,104,73,113,113,113,113,113,71,73,73,73,74,,,,,74,104,75,, +,78,104,78,73,73,73,73,73,78,78,78,78,74,112,112,112,112,74,104,75,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,,,,,,,,,,,,,,,,,,,4,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,1,,,,,,,,,,,,,,,,,,,2,0, +0,0,,0,0,0,0,0,0,0,0,0,0,0,,,,,0,,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +97 +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;16;128;;; +0;32;48;;; +0;32;64;;; +0;48;32;;; +0;48;64;;; +0;48;80;;; +0;48;112;;; +0;64;16;;; +0;64;80;;; +0;64;128;;; +0;80;16;;; +0;80;80;;; +0;80;128;;; +0;96;16;;; +0;96;64;;; +0;96;80;;; +0;96;128;;; +0;112;16;;; +0;112;128;;; +0;128;16;;; +0;128;48;;; +0;128;64;;; +0;128;128;;; +0;144;16;;; +0;144;48;;; +0;144;64;;; +0;144;112;;; +0;160;16;;; +0;160;48;;; +0;160;64;;; +0;160;112;;; +0;176;16;;; +0;176;48;;; +0;176;64;;; +0;176;112;;; +0;192;16;;; +0;192;64;;; +0;192;112;;; +0;208;16;;; +0;208;96;;; +0;208;112;;; +0;208;128;;; +0;224;16;;; +0;240;16;;; +0;256;16;;; +0;272;16;;; +0;288;16;;; +0;288;80;;; +0;288;96;;; +0;288;112;;; +0;288;128;;; +0;304;16;;; +0;304;32;;; +0;320;32;;; +0;320;48;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +0;320;112;;; +0;320;128;;; +153;32;136;;;d8_2d_2L;dungeon8.map;d8_2d_2L;1;;False +153;304;136;;;d8_2d_2R;dungeon8.map;d8_2d_2R;1;;False +300;224;112;;;;;; +300;240;112;;;;;; +300;256;112;;;;;; +300;272;112;;;;;; +284;-8;40;;;; +258;32;112; +258;32;128; +258;192;48; +258;208;48; +258;208;64; +258;304;48; +258;304;64; +258;304;80; +258;304;96; +258;304;112; +258;304;128; +259;32;112; +259;192;48; +259;208;48; +259;304;80; +492;224;112;375 +492;256;112; +484;64;64 +484;96;112 +24;192;64;;;; +24;304;32;;;; +295;224;112;;;;;; +295;240;112;;;;;; +295;256;112;;;;;; +295;272;112;;;;;; +257;-8;16 +287;-8;64;32 diff --git a/bin/Data/Maps/dungeon8_2d_2.map.data b/bin/Data/Maps/dungeon8_2d_2.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/dungeon8_2d_2.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon8_2d_3.map b/bin/Data/Maps/dungeon8_2d_3.map new file mode 100644 index 0000000..058f0a2 --- /dev/null +++ b/bin/Data/Maps/dungeon8_2d_3.map @@ -0,0 +1,645 @@ +3 +1 +1 +tileset 2d.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,74,66,84,78,78,78,78,78,78,84,84,84,78,78,78,78,78,84,66,75,, +,74,66,113,101,101,106,101,86,101,113,113,113,101,86,101,86,101,113,66,75,, +,74,66,113,113,113,106,113,101,113,113,113,113,113,101,113,101,113,113,66,75,, +,74,73,113,113,113,92,113,113,113,71,70,113,113,113,113,113,113,113,73,78,, +,78,74,113,113,113,113,113,113,113,75,74,113,113,113,113,113,113,113,75,78,, +,78,74,113,113,113,113,113,113,113,75,74,113,113,113,113,113,113,113,75,78,, +,78,74,,,,,,,,75,74,,,,,,,,75,78,, +,78,74,112,112,112,112,112,112,112,75,74,112,112,112,112,112,112,112,75,78,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,0,0, +0,3,,,,,,,,,,,,,,,,,,,4,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,1,,,,,,,,,,,,,,,,,,,2,0, +0,0,0,,,,,,,,0,0,,,,,,,,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +83 +0;16;16;;; +0;16;32;;; +0;16;48;;; +0;32;64;;; +0;32;80;;; +0;32;96;;; +0;32;112;;; +0;32;128;;; +0;48;16;;; +0;64;16;;; +0;80;16;;; +0;96;16;;; +0;96;64;;; +0;112;16;;; +0;128;16;;; +0;144;16;;; +0;160;16;;; +0;160;64;;; +0;160;80;;; +0;160;96;;; +0;160;112;;; +0;160;128;;; +0;176;16;;; +0;176;64;;; +0;176;80;;; +0;176;96;;; +0;176;112;;; +0;176;128;;; +0;192;16;;; +0;208;16;;; +0;224;16;;; +0;240;16;;; +0;256;16;;; +0;272;16;;; +0;288;16;;; +0;304;64;;; +0;304;80;;; +0;304;96;;; +0;304;112;;; +0;304;128;;; +0;320;16;;; +0;320;32;;; +0;320;48;;; +286;-8;40;;;; +153;32;8;;;d8_2d_3L;dungeon8.map;d8_2d_3L;3;;False +153;304;8;;;d8_2d_3R;dungeon8.map;d8_2d_3R;3;;False +300;32;16;;;;;; +300;64;112;;;;;; +300;96;112;;;;;; +300;128;112;;;;;; +300;208;112;;;;;; +300;240;112;;;;;; +300;272;112;;;;;; +300;304;16;;;;;; +258;32;16; +258;32;32; +258;32;48; +258;304;16; +258;304;32; +258;304;48; +492;80;112; +492;128;112;300 +492;240;112;1000 +492;288;112;1250 +295;48;112;;;;;; +295;64;112;;;;;; +295;80;112;;;;;; +295;96;112;;;;;; +295;112;112;;;;;; +295;128;112;;;;;; +295;144;112;;;;;; +295;192;112;;;;;; +295;208;112;;;;;; +295;224;112;;;;;; +295;240;112;;;;;; +295;256;112;;;;;; +295;272;112;;;;;; +295;288;112;;;;;; +257;-8;16 +346;64;80;48;;;2500; +346;208;64;;32;;1500; +346;256;96;;-32;;1500; +287;-8;64;32 diff --git a/bin/Data/Maps/dungeon8_2d_3.map.data b/bin/Data/Maps/dungeon8_2d_3.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/dungeon8_2d_3.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon8_2d_4.map b/bin/Data/Maps/dungeon8_2d_4.map new file mode 100644 index 0000000..0b33272 --- /dev/null +++ b/bin/Data/Maps/dungeon8_2d_4.map @@ -0,0 +1,686 @@ +3 +1 +1 +tileset 2d.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,49,56,56,56,56,56,49,49,49,49,49,49,56,56,56,56,56,49,49,49,, +,46,113,113,113,113,113,48,49,56,56,56,49,113,113,113,113,113,49,49,49,, +,46,66,45,113,113,113,56,56,113,113,113,56,56,113,113,45,113,113,113,48,, +,46,66,46,113,113,113,113,113,113,113,113,113,113,113,113,56,113,45,76,48,, +,46,66,46,113,113,113,113,113,76,45,45,45,45,113,113,113,113,46,76,48,, +,46,66,46,113,113,113,113,113,76,48,49,49,46,113,113,113,56,56,76,48,, +,46,66,46,113,113,113,113,113,113,48,49,49,46,45,45,113,113,113,113,48,, +,46,66,46,45,45,45,45,45,45,49,49,49,49,49,49,45,45,45,66,48,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,,,,,,,,,,,,,,,,,,,4,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,1,,,,,,,,,,,,,,,,,,,2,0, +0,0,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +124 +0;16;32;;; +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;16;128;;; +0;32;16;;; +0;48;16;;; +0;48;48;;; +0;48;64;;; +0;48;80;;; +0;48;96;;; +0;48;112;;; +0;48;128;;; +0;64;16;;; +0;64;128;;; +0;80;16;;; +0;80;128;;; +0;96;16;;; +0;96;128;;; +0;112;32;;; +0;112;48;;; +0;112;128;;; +0;128;48;;; +0;128;128;;; +0;144;32;;; +0;144;128;;; +0;160;32;;; +0;160;80;;; +0;160;96;;; +0;160;112;;; +0;176;32;;; +0;176;80;;; +0;192;32;;; +0;192;48;;; +0;192;80;;; +0;208;16;;; +0;208;48;;; +0;208;80;;; +0;208;96;;; +0;224;16;;; +0;224;112;;; +0;240;16;;; +0;240;112;;; +0;256;16;;; +0;256;48;;; +0;256;64;;; +0;256;128;;; +0;272;16;;; +0;272;96;;; +0;272;128;;; +0;288;32;;; +0;288;64;;; +0;288;80;;; +0;288;96;;; +0;288;128;;; +0;304;32;;; +0;320;48;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +0;320;112;;; +0;320;128;;; +286;-8;40;;;; +153;32;136;;;d8_2d_4L;dungeon8.map;d8_2d_4L;1;;False +153;304;136;;;d8_2d_4R;dungeon8.map;d8_2d_4R;1;;False +300;32;128;;;;;; +300;304;128;;;;;; +258;32;48; +258;32;64; +258;32;80; +258;32;96; +258;32;112; +258;32;128; +258;144;80; +258;144;96; +258;304;64; +258;304;80; +258;304;96; +258;304;128; +259;32;48; +259;144;80; +259;304;64; +259;304;128; +484;224;96 +22;304;128;;;; +354;64;64 +354;64;80 +354;64;96 +354;64;112 +354;80;80 +354;80;96 +354;80;112 +354;96;32 +354;96;48 +354;96;96 +354;96;112 +354;112;64 +354;112;80 +354;112;96 +354;112;112 +354;128;96 +354;128;112 +354;208;32 +354;208;64 +354;224;32 +354;224;48 +354;224;64 +354;240;32 +354;240;48 +354;240;64 +354;240;80 +354;256;32 +354;256;80 +354;256;96 +354;272;32 +354;272;48 +354;272;64 +354;272;80 +354;288;48 +354;288;112 +257;-8;16 +287;-8;64;32 diff --git a/bin/Data/Maps/dungeon8_2d_4.map.data b/bin/Data/Maps/dungeon8_2d_4.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/dungeon8_2d_4.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon8_2d_5.map b/bin/Data/Maps/dungeon8_2d_5.map new file mode 100644 index 0000000..a63af8f --- /dev/null +++ b/bin/Data/Maps/dungeon8_2d_5.map @@ -0,0 +1,658 @@ +3 +1 +1 +tileset 2d.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,49,49,56,56,56,56,56,56,56,49,49,49,49,49,49,49,49,49,49,49,, +,49,46,113,113,113,113,113,113,113,48,49,49,49,49,49,49,49,49,49,49,, +,49,53,113,113,113,113,113,113,113,48,49,49,56,56,56,56,49,49,49,49,, +,46,113,113,113,113,113,113,113,113,48,49,53,113,113,113,113,56,56,49,49,, +,46,66,45,113,113,113,113,113,113,56,53,113,113,113,113,113,113,113,54,49,, +,46,66,46,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,48,, +,46,66,49,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,66,48,, +,46,66,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,66,48,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,,,,,,,,,,,,,,,,,,,4,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,1,,,,,,,,,,,,,,,,,,,2,0, +0,0,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +96 +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;16;128;;; +0;32;32;;; +0;32;48;;; +0;48;16;;; +0;48;80;;; +0;48;96;;; +0;48;112;;; +0;48;128;;; +0;64;16;;; +0;64;112;;; +0;80;16;;; +0;80;112;;; +0;96;16;;; +0;96;112;;; +0;112;16;;; +0;112;112;;; +0;128;16;;; +0;128;112;;; +0;144;16;;; +0;144;112;;; +0;160;32;;; +0;160;48;;; +0;160;64;;; +0;160;80;;; +0;160;112;;; +0;176;80;;; +0;176;112;;; +0;192;64;;; +0;192;112;;; +0;208;48;;; +0;208;112;;; +0;224;48;;; +0;224;112;;; +0;240;48;;; +0;240;112;;; +0;256;48;;; +0;256;112;;; +0;272;64;;; +0;272;112;;; +0;288;64;;; +0;288;112;;; +0;288;128;;; +0;304;80;;; +0;320;96;;; +0;320;112;;; +0;320;128;;; +286;-8;40;;;; +153;32;136;;;d8_2d_5L;dungeon8.map;d8_2d_5L;1;;False +153;304;136;;;d8_2d_5R;dungeon8.map;d8_2d_5R;1;;False +300;32;128;;;;;; +300;304;128;;;;;; +258;32;80; +258;32;96; +258;32;112; +258;32;128; +258;304;112; +258;304;128; +259;32;80; +259;304;112; +484;64;32 +484;112;32 +484;224;80 +484;256;80 +354;48;48 +354;64;48 +354;64;80 +354;64;96 +354;80;48 +354;80;80 +354;80;96 +354;96;48 +354;96;80 +354;96;96 +354;112;48 +354;112;80 +354;112;96 +354;128;48 +354;144;48 +354;192;80 +354;208;64 +354;208;80 +354;208;96 +354;224;64 +354;224;96 +354;240;64 +354;240;96 +354;256;64 +354;256;96 +354;272;80 +354;272;96 +257;-8;16 +287;-8;64;32 diff --git a/bin/Data/Maps/dungeon8_2d_5.map.data b/bin/Data/Maps/dungeon8_2d_5.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/dungeon8_2d_5.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon8_2d_6.map b/bin/Data/Maps/dungeon8_2d_6.map new file mode 100644 index 0000000..dca0ef5 --- /dev/null +++ b/bin/Data/Maps/dungeon8_2d_6.map @@ -0,0 +1,656 @@ +3 +1 +1 +tileset 2d.png +22 +10 +3 +,,,,,,,,,,,,,,,,,,,,,, +,46,66,48,49,49,49,49,49,49,56,56,49,49,49,49,49,49,46,66,48,, +,46,66,81,65,81,65,81,65,81,113,113,113,113,54,49,56,56,53,66,48,, +,46,66,113,81,113,81,113,81,113,113,113,113,113,113,49,113,113,113,66,48,, +,46,66,113,113,113,113,44,45,113,45,45,76,113,113,56,76,45,45,45,49,, +,46,66,113,113,113,113,56,56,113,48,46,76,113,113,113,113,56,56,49,49,, +,46,66,113,113,113,113,113,113,113,48,46,76,113,113,113,113,113,113,48,49,, +,46,66,113,113,113,83,113,113,83,48,46,76,113,113,113,83,83,45,49,49,, +,49,45,45,45,45,49,45,45,49,49,49,45,45,45,45,49,49,49,49,49,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,, +0,0,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,0,0, +0,3,,,,,,,,,,,,,,,,,,,4,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0, +0,1,,,,,,,,,,,,,,,,,,,2,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +94 +0;16;16;;; +0;16;32;;; +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;32;128;;; +0;48;16;;; +0;48;128;;; +0;64;16;;; +0;64;128;;; +0;80;16;;; +0;80;128;;; +0;96;16;;; +0;96;128;;; +0;112;16;;; +0;112;64;;; +0;112;80;;; +0;112;128;;; +0;128;16;;; +0;128;64;;; +0;128;80;;; +0;128;128;;; +0;144;16;;; +0;144;128;;; +0;160;16;;; +0;160;64;;; +0;160;80;;; +0;160;96;;; +0;160;112;;; +0;176;16;;; +0;176;64;;; +0;176;80;;; +0;176;96;;; +0;176;112;;; +0;192;16;;; +0;192;128;;; +0;208;16;;; +0;208;128;;; +0;224;32;;; +0;224;128;;; +0;240;48;;; +0;240;64;;; +0;240;128;;; +0;256;32;;; +0;256;128;;; +0;272;32;;; +0;272;64;;; +0;272;80;;; +0;272;128;;; +0;288;16;;; +0;288;32;;; +0;288;64;;; +0;288;80;;; +0;288;112;;; +0;304;64;;; +0;304;96;;; +0;320;16;;; +0;320;32;;; +0;320;48;;; +286;-8;40;;;; +153;32;8;;;d8_2d_6L;dungeon8.map;d8_2d_6L;3;;False +153;304;8;;;d8_2d_6R;dungeon8.map;d8_2d_6R;3;;False +300;32;16;;;;;; +300;304;16;;;;;; +258;32;16; +258;32;32; +258;32;48; +258;32;64; +258;32;80; +258;32;96; +258;32;112; +258;192;64; +258;192;80; +258;192;96; +258;192;112; +258;256;64; +258;304;16; +258;304;32; +258;304;48; +259;192;64; +259;256;64; +427;112;52;3;; +484;128;112 +484;288;96 +257;-8;16 +346;64;64;;48;;2500; +346;224;96;48;;;2500; +287;-8;64;32 +348;96;112 +348;144;112 +348;256;112 +348;272;112 diff --git a/bin/Data/Maps/dungeon8_2d_6.map.data b/bin/Data/Maps/dungeon8_2d_6.map.data new file mode 100644 index 0000000..8b63be4 --- /dev/null +++ b/bin/Data/Maps/dungeon8_2d_6.map.data @@ -0,0 +1,12 @@ +22 +10 +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon_color.map b/bin/Data/Maps/dungeon_color.map new file mode 100644 index 0000000..cd1c689 --- /dev/null +++ b/bin/Data/Maps/dungeon_color.map @@ -0,0 +1,1819 @@ +3 +1 +2 +dungeon color.png +62 +43 +3 +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,42,13,41,,,,,,,,,,,,,,,, +,35,43,43,43,43,43,43,43,43,36,35,43,43,43,43,43,43,43,43,36,,,,,,,,,,,,,,,,,,,,,35,43,36,46,43,47,35,43,36,,35,43,43,43,43,43,43,43,43,36,, +,41,5,5,5,5,5,5,5,5,42,41,5,21,,,,,23,5,42,,,,,,,,,,,,,,,,,,,,,41,5,42,5,5,5,41,5,42,,41,5,5,5,5,5,5,5,5,42,, +,41,5,5,5,5,5,5,5,5,42,41,5,21,,,,,23,5,42,,,,,,,,,,,,,,,,,,,,,41,5,42,32,4,33,41,5,46,36,41,5,5,5,5,5,5,5,5,42,, +,41,5,5,5,5,5,5,5,5,29,31,5,21,,,,,23,5,42,,,,,,,,,,,,,,,,,,,,,41,5,46,43,14,43,47,5,5,29,31,5,5,5,5,5,5,5,5,42,, +,41,5,5,5,5,5,5,5,5,24,27,5,10,22,22,22,22,9,5,42,,,,,,,,,,,,,,,,,,,,,41,5,5,4,5,4,5,5,5,24,27,5,5,5,5,5,5,5,5,42,, +,41,5,5,5,5,5,5,5,5,42,41,5,5,5,5,5,5,5,5,42,,,,,,,,,,,,,,,,,,,,,41,5,5,5,5,5,5,5,48,38,41,5,5,5,5,5,5,5,5,42,, +,41,5,5,5,5,5,5,5,5,42,41,5,5,5,5,5,5,5,5,42,,,,,,,,,,,,,,,,,,,,,41,5,5,4,5,4,5,5,42,,41,5,5,5,5,5,5,5,5,42,, +,37,44,44,44,25,28,44,44,44,38,37,44,44,44,44,44,44,44,44,38,,,,,,,,,,,,,,,,,,,,,37,44,44,44,44,44,44,44,38,,37,44,44,44,25,28,44,44,44,38,, +,35,43,43,43,26,30,43,43,43,36,35,43,43,43,43,43,43,43,43,36,35,43,43,43,43,43,43,43,43,36,35,43,43,43,43,43,43,43,43,36,,35,43,43,43,43,43,43,36,,35,43,43,43,26,30,43,43,43,36,, +,41,45,45,5,5,5,5,39,5,42,41,5,5,5,5,5,5,5,5,42,41,5,5,5,5,5,5,5,5,42,41,5,8,5,5,5,5,17,5,42,35,47,5,5,5,5,5,5,46,36,41,5,5,5,5,5,5,5,5,42,, +,41,53,53,5,5,5,5,39,5,42,41,5,5,4,5,5,4,5,5,42,41,5,5,5,5,5,5,5,5,42,41,12,40,11,5,5,19,50,18,42,41,5,5,4,4,4,4,5,5,42,41,5,5,5,5,5,5,5,5,42,, +,41,53,53,45,45,45,45,45,5,29,31,5,5,5,5,5,5,5,5,42,41,5,5,5,5,5,5,5,5,29,31,5,7,5,4,4,5,16,5,42,41,5,5,4,5,4,4,5,5,29,31,5,5,5,5,5,5,5,5,42,, +,41,53,53,53,53,53,53,53,5,24,27,5,5,5,5,5,5,5,5,42,41,5,5,5,5,5,5,5,5,24,27,5,3,5,4,4,5,8,5,42,41,5,5,4,5,5,4,5,5,24,27,5,5,5,5,5,5,5,5,42,, +,41,51,51,51,51,51,51,51,5,42,41,5,5,4,5,5,4,5,5,42,41,5,5,5,5,5,5,5,5,42,41,1,20,0,5,5,12,40,11,42,41,5,5,4,4,4,4,5,5,42,41,5,5,5,5,5,5,5,5,42,, +,41,5,39,39,39,39,39,39,5,42,41,5,5,5,5,5,5,5,5,42,41,5,5,5,5,5,5,5,5,42,41,5,2,5,5,5,5,7,5,42,37,49,5,5,5,5,5,5,48,38,41,5,5,5,5,5,5,5,5,42,, +,37,44,44,44,44,44,44,44,44,38,37,44,44,44,25,28,44,44,44,38,37,44,44,44,25,28,44,44,44,38,37,44,44,44,44,44,44,44,44,38,,37,44,44,25,28,44,44,38,,37,44,44,44,44,44,44,44,44,38,, +,,,,,,,,,,,35,43,43,43,26,30,43,43,36,,35,43,43,43,26,30,43,43,43,36,35,43,43,43,43,43,43,43,43,36,35,43,43,43,26,30,43,43,43,36,,,,,,,,,,,, +,,,,,,,,,,,41,5,5,5,5,5,5,5,42,,41,5,5,51,5,5,51,51,5,42,41,5,5,5,5,5,5,5,5,42,41,5,5,5,5,5,5,5,5,42,,,,,,,,,,,, +,,,,,,,,,,,41,5,4,4,4,4,4,5,46,36,41,5,5,34,34,34,34,34,5,42,41,5,5,5,5,5,5,5,5,42,41,5,5,34,34,34,34,5,5,42,,,,,,,,,,,, +,,,,,,,,,,,41,5,4,5,4,5,4,5,5,29,31,5,34,34,34,34,34,34,5,29,31,5,5,5,5,5,5,5,5,42,41,45,34,34,34,34,34,34,45,42,,,,,,,,,,,, +,,,,,,,,,,,41,5,4,4,4,4,4,5,5,24,27,5,34,34,34,34,34,34,5,24,27,5,5,5,5,5,5,5,5,42,41,51,34,34,34,34,34,34,51,42,,,,,,,,,,,, +,,,,,,,,,,,41,5,4,5,4,5,4,5,48,38,41,5,34,34,34,34,34,5,5,42,41,5,5,5,5,5,5,5,5,42,41,5,5,34,34,34,34,5,5,42,,,,,,,,,,,, +,,,,,,,,,,,41,5,4,4,4,4,4,5,42,,41,5,45,45,45,45,45,5,5,42,41,5,5,5,5,5,5,5,5,42,41,5,5,5,5,5,5,5,5,42,,,,,,,,,,,, +,,,,,,,,,,,37,44,44,44,44,44,44,44,38,,37,44,44,44,44,44,44,44,44,38,37,44,44,44,25,28,44,44,44,38,37,44,44,44,25,28,44,44,44,38,,,,,,,,,,,, +,,,,,,,,,,,35,43,43,43,43,43,43,43,43,36,35,43,43,43,43,43,43,43,43,36,35,43,43,43,26,30,43,43,43,36,35,43,43,43,26,30,43,43,43,36,,,,,,,,,,,, +,,,,,,,,,,,41,5,5,5,5,5,5,5,5,42,41,5,5,5,5,5,5,5,5,42,41,5,34,34,5,5,5,34,5,42,41,5,17,5,5,5,5,5,5,42,,,,,,,,,,,, +,,,,,,,,,,,41,5,5,5,5,5,5,5,5,42,41,5,4,4,4,4,4,4,5,46,47,5,34,34,5,5,5,34,5,46,47,19,50,18,5,5,5,5,5,42,,,,,,,,,,,, +,,,,,,,,,,,41,5,5,5,5,5,5,5,5,29,31,5,4,5,5,5,5,4,5,5,5,5,34,34,34,34,34,34,5,5,5,5,16,5,5,5,5,5,5,42,,,,,,,,,,,, +,,,,,,,,,,,41,5,5,5,5,5,5,5,5,24,27,5,4,5,5,5,5,4,5,5,5,5,34,34,34,34,34,34,5,5,5,5,5,5,5,5,5,8,5,42,,,,,,,,,,,, +,,,,,,,,,,,41,5,5,5,5,5,5,5,5,42,41,5,4,4,4,4,4,4,5,48,49,5,34,34,34,34,34,34,5,48,49,5,5,5,5,5,12,40,11,42,,,,,,,,,,,, +,,,,,,,,,,,41,5,5,5,5,5,5,5,5,42,41,5,5,5,5,5,5,5,5,42,41,5,34,5,5,5,34,34,5,42,41,5,5,5,5,5,5,7,5,42,,,,,,,,,,,, +,,,,,,,,,,,37,44,44,44,25,28,44,44,44,38,37,44,44,44,15,44,44,44,44,38,37,44,44,44,25,28,44,44,44,38,37,44,44,44,25,28,44,44,44,38,,,,,,,,,,,, +,,,,,,,,,,,35,43,43,43,26,30,43,43,43,36,35,43,43,43,15,43,43,43,43,36,35,43,43,43,26,30,43,43,43,36,35,43,43,43,26,30,43,43,43,36,,,,,,,,,,,, +,,,,,,,,,,,41,5,4,4,4,4,4,4,5,42,41,5,5,5,5,5,5,5,5,42,41,5,5,5,5,5,5,5,5,42,41,5,5,5,5,5,5,5,5,42,,,,,,,,,,,, +,,,,,,,,,,,41,4,5,5,5,5,5,5,4,42,41,5,5,5,5,5,5,5,5,42,41,34,34,34,34,34,34,5,5,42,41,5,5,5,5,5,5,5,5,42,,,,,,,,,,,, +,,,,,,,,,,,41,4,5,5,5,5,5,5,4,42,41,5,5,5,5,5,5,5,5,42,41,34,34,34,34,34,34,5,5,29,31,5,5,5,45,45,5,5,5,42,,,,,,,,,,,, +,,,,,,,,,,,41,4,5,5,5,5,5,5,4,42,41,5,5,5,5,5,5,5,5,42,41,5,5,5,34,34,34,5,5,24,27,5,5,5,51,51,5,5,5,42,,,,,,,,,,,, +,,,,,,,,,,,41,4,5,5,5,6,5,5,4,42,41,5,5,5,5,5,5,5,5,42,41,5,5,5,34,34,34,5,5,42,41,5,5,5,5,5,5,5,5,42,,,,,,,,,,,, +,,,,,,,,,,,41,5,4,4,4,4,4,4,5,42,41,5,5,5,5,5,5,5,5,42,41,5,5,5,34,34,34,5,5,42,41,5,5,5,5,5,5,5,5,42,,,,,,,,,,,, +,,,,,,,,,,,37,44,44,44,44,44,44,44,44,38,37,44,44,44,44,44,44,44,44,38,37,44,44,44,44,44,44,44,44,38,37,44,44,44,44,44,44,44,44,38,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,0,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,0,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,0,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,0,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,0,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0, +0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,0,,,,,,,,,,,0, +0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0, +,,,,,,,,,,0,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,,,, +,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +1158 +169;352;304;dc_button_0 +0;16;48;;; +0;16;64;;; +0;16;80;;; +0;16;96;;; +0;16;112;;; +0;16;128;;; +0;16;176;;; +0;16;192;;; +0;16;208;;; +0;16;224;;; +0;16;240;;; +0;16;256;;; +0;32;32;;; +0;32;144;;; +0;32;160;;; +0;32;272;;; +0;48;32;;; +0;48;144;;; +0;48;160;;; +0;48;272;;; +0;64;32;;; +0;64;144;;; +0;64;160;;; +0;64;272;;; +0;80;32;;; +0;80;272;;; +0;96;32;;; +0;96;272;;; +0;112;32;;; +0;112;144;;; +0;112;160;;; +0;112;272;;; +0;128;32;;; +0;128;144;;; +0;128;160;;; +0;128;272;;; +0;144;32;;; +0;144;144;;; +0;144;160;;; +0;144;272;;; +0;160;48;;; +0;160;64;;; +0;160;112;;; +0;160;128;;; +0;160;176;;; +0;160;192;;; +0;160;240;;; +0;160;256;;; +0;176;48;;; +0;176;64;;; +0;176;112;;; +0;176;128;;; +0;176;176;;; +0;176;192;;; +0;176;240;;; +0;176;256;;; +0;176;304;;; +0;176;320;;; +0;176;336;;; +0;176;352;;; +0;176;368;;; +0;176;384;;; +0;176;432;;; +0;176;448;;; +0;176;464;;; +0;176;480;;; +0;176;496;;; +0;176;512;;; +0;176;560;;; +0;176;576;;; +0;176;592;;; +0;176;608;;; +0;176;624;;; +0;176;640;;; +0;192;32;;; +0;192;144;;; +0;192;160;;; +0;192;272;;; +0;192;288;;; +0;192;400;;; +0;192;416;;; +0;192;528;;; +0;192;544;;; +0;192;656;;; +0;208;32;;; +0;208;144;;; +0;208;160;;; +0;208;272;;; +0;208;288;;; +0;208;400;;; +0;208;416;;; +0;208;528;;; +0;208;544;;; +0;208;656;;; +0;224;32;;; +0;224;144;;; +0;224;160;;; +0;224;272;;; +0;224;288;;; +0;224;400;;; +0;224;416;;; +0;224;528;;; +0;224;544;;; +0;224;656;;; +0;240;32;;; +0;240;144;;; +0;240;160;;; +0;240;400;;; +0;240;416;;; +0;240;656;;; +0;256;32;;; +0;256;144;;; +0;256;160;;; +0;256;400;;; +0;256;416;;; +0;256;656;;; +0;272;32;;; +0;272;144;;; +0;272;160;;; +0;272;272;;; +0;272;288;;; +0;272;400;;; +0;272;416;;; +0;272;528;;; +0;272;544;;; +0;272;656;;; +0;288;32;;; +0;288;144;;; +0;288;160;;; +0;288;272;;; +0;288;288;;; +0;288;400;;; +0;288;416;;; +0;288;528;;; +0;288;544;;; +0;288;656;;; +0;304;32;;; +0;304;144;;; +0;304;160;;; +0;304;272;;; +0;304;304;;; +0;304;320;;; +0;304;368;;; +0;304;384;;; +0;304;416;;; +0;304;528;;; +0;304;544;;; +0;304;656;;; +0;320;48;;; +0;320;64;;; +0;320;80;;; +0;320;96;;; +0;320;112;;; +0;320;128;;; +0;320;176;;; +0;320;192;;; +0;320;208;;; +0;320;224;;; +0;320;240;;; +0;320;256;;; +0;320;320;;; +0;320;368;;; +0;320;432;;; +0;320;448;;; +0;320;496;;; +0;320;512;;; +0;320;560;;; +0;320;576;;; +0;320;592;;; +0;320;608;;; +0;320;624;;; +0;320;640;;; +0;336;176;;; +0;336;192;;; +0;336;208;;; +0;336;224;;; +0;336;240;;; +0;336;256;;; +0;336;304;;; +0;336;320;;; +0;336;368;;; +0;336;384;;; +0;336;432;;; +0;336;448;;; +0;336;496;;; +0;336;512;;; +0;336;560;;; +0;336;576;;; +0;336;592;;; +0;336;608;;; +0;336;624;;; +0;336;640;;; +0;352;160;;; +0;352;272;;; +0;352;288;;; +0;352;400;;; +0;352;416;;; +0;352;528;;; +0;352;544;;; +0;352;656;;; +0;368;160;;; +0;368;272;;; +0;368;288;;; +0;368;400;;; +0;368;416;;; +0;368;528;;; +0;368;544;;; +0;368;656;;; +0;384;160;;; +0;384;272;;; +0;384;288;;; +0;384;400;;; +0;384;416;;; +0;384;528;;; +0;384;544;;; +0;384;656;;; +0;400;160;;; +0;400;400;;; +0;400;416;;; +0;400;656;;; +0;416;160;;; +0;416;400;;; +0;416;416;;; +0;416;528;;; +0;416;544;;; +0;416;656;;; +0;432;160;;; +0;432;272;;; +0;432;288;;; +0;432;400;;; +0;432;416;;; +0;432;528;;; +0;432;544;;; +0;432;656;;; +0;448;160;;; +0;448;272;;; +0;448;288;;; +0;448;400;;; +0;448;416;;; +0;448;528;;; +0;448;544;;; +0;448;656;;; +0;464;160;;; +0;464;272;;; +0;464;288;;; +0;464;400;;; +0;464;416;;; +0;464;528;;; +0;464;544;;; +0;464;656;;; +0;480;176;;; +0;480;192;;; +0;480;240;;; +0;480;256;;; +0;480;304;;; +0;480;320;;; +0;480;368;;; +0;480;384;;; +0;480;432;;; +0;480;448;;; +0;480;496;;; +0;480;512;;; +0;480;560;;; +0;480;576;;; +0;480;592;;; +0;480;608;;; +0;480;624;;; +0;480;640;;; +0;496;176;;; +0;496;192;;; +0;496;240;;; +0;496;256;;; +0;496;304;;; +0;496;320;;; +0;496;368;;; +0;496;384;;; +0;496;432;;; +0;496;448;;; +0;496;496;;; +0;496;512;;; +0;496;560;;; +0;496;576;;; +0;496;592;;; +0;496;608;;; +0;496;624;;; +0;496;640;;; +0;512;160;;; +0;512;272;;; +0;512;288;;; +0;512;400;;; +0;512;416;;; +0;512;528;;; +0;512;544;;; +0;512;656;;; +0;528;160;;; +0;528;272;;; +0;528;288;;; +0;528;400;;; +0;528;416;;; +0;528;528;;; +0;528;544;;; +0;528;656;;; +0;544;160;;; +0;544;272;;; +0;544;288;;; +0;544;400;;; +0;544;416;;; +0;544;528;;; +0;544;544;;; +0;544;656;;; +0;560;160;;; +0;560;272;;; +0;560;288;;; +0;560;656;;; +0;576;160;;; +0;576;272;;; +0;576;288;;; +0;576;656;;; +0;592;160;;; +0;592;272;;; +0;592;288;;; +0;592;400;;; +0;592;416;;; +0;592;528;;; +0;592;544;;; +0;592;656;;; +0;608;160;;; +0;608;272;;; +0;608;288;;; +0;608;400;;; +0;608;416;;; +0;608;528;;; +0;608;544;;; +0;608;656;;; +0;624;160;;; +0;624;272;;; +0;624;288;;; +0;624;400;;; +0;624;416;;; +0;624;528;;; +0;624;544;;; +0;624;656;;; +0;640;176;;; +0;640;192;;; +0;640;208;;; +0;640;224;;; +0;640;240;;; +0;640;256;;; +0;640;304;;; +0;640;320;;; +0;640;336;;; +0;640;352;;; +0;640;368;;; +0;640;384;;; +0;640;432;;; +0;640;448;;; +0;640;496;;; +0;640;512;;; +0;640;560;;; +0;640;576;;; +0;640;624;;; +0;640;640;;; +0;656;48;;; +0;656;64;;; +0;656;80;;; +0;656;96;;; +0;656;112;;; +0;656;128;;; +0;656;192;;; +0;656;208;;; +0;656;224;;; +0;656;240;;; +0;656;304;;; +0;656;320;;; +0;656;336;;; +0;656;352;;; +0;656;368;;; +0;656;384;;; +0;656;432;;; +0;656;448;;; +0;656;496;;; +0;656;512;;; +0;656;560;;; +0;656;576;;; +0;656;624;;; +0;656;640;;; +0;672;32;;; +0;672;144;;; +0;672;176;;; +0;672;256;;; +0;672;288;;; +0;672;400;;; +0;672;416;;; +0;672;528;;; +0;672;544;;; +0;672;656;;; +0;688;48;;; +0;688;144;;; +0;688;160;;; +0;688;272;;; +0;688;288;;; +0;688;400;;; +0;688;416;;; +0;688;528;;; +0;688;544;;; +0;688;656;;; +0;704;144;;; +0;704;160;;; +0;704;272;;; +0;704;288;;; +0;704;400;;; +0;704;416;;; +0;704;528;;; +0;704;544;;; +0;704;656;;; +0;720;144;;; +0;720;160;;; +0;720;656;;; +0;736;144;;; +0;736;160;;; +0;736;656;;; +0;752;48;;; +0;752;144;;; +0;752;160;;; +0;752;272;;; +0;752;288;;; +0;752;400;;; +0;752;416;;; +0;752;528;;; +0;752;544;;; +0;752;656;;; +0;768;32;;; +0;768;144;;; +0;768;160;;; +0;768;272;;; +0;768;288;;; +0;768;400;;; +0;768;416;;; +0;768;528;;; +0;768;544;;; +0;768;656;;; +0;784;48;;; +0;784;64;;; +0;784;112;;; +0;784;128;;; +0;784;176;;; +0;784;256;;; +0;784;288;;; +0;784;400;;; +0;784;416;;; +0;784;528;;; +0;784;544;;; +0;784;656;;; +0;800;64;;; +0;800;112;;; +0;800;192;;; +0;800;240;;; +0;800;304;;; +0;800;320;;; +0;800;336;;; +0;800;352;;; +0;800;368;;; +0;800;384;;; +0;800;432;;; +0;800;448;;; +0;800;464;;; +0;800;480;;; +0;800;496;;; +0;800;512;;; +0;800;560;;; +0;800;576;;; +0;800;592;;; +0;800;608;;; +0;800;624;;; +0;800;640;;; +0;816;48;;; +0;816;64;;; +0;816;112;;; +0;816;128;;; +0;816;176;;; +0;816;192;;; +0;816;240;;; +0;816;256;;; +0;832;32;;; +0;832;144;;; +0;832;160;;; +0;832;272;;; +0;848;32;;; +0;848;144;;; +0;848;160;;; +0;848;272;;; +0;864;32;;; +0;864;144;;; +0;864;160;;; +0;864;272;;; +0;880;32;;; +0;880;272;;; +0;896;32;;; +0;896;272;;; +0;912;32;;; +0;912;144;;; +0;912;160;;; +0;912;272;;; +0;928;32;;; +0;928;144;;; +0;928;160;;; +0;928;272;;; +0;944;32;;; +0;944;144;;; +0;944;160;;; +0;944;272;;; +0;960;48;;; +0;960;64;;; +0;960;80;;; +0;960;96;;; +0;960;112;;; +0;960;128;;; +0;960;176;;; +0;960;192;;; +0;960;208;;; +0;960;224;;; +0;960;240;;; +0;960;256;;; +20;704;64;;; +21;736;64;;; +14;288;96;;; +1;160;96;;; +1;160;224;;; +1;176;96;;; +1;176;224;;; +1;320;352;;; +1;320;480;;; +1;336;352;;; +1;336;480;;; +1;480;224;;; +1;480;352;;; +1;496;224;;; +1;496;352;;; +1;640;608;;; +1;656;608;;; +1;800;96;;; +1;800;224;;; +1;816;96;;; +1;816;224;;; +3;80;144;;; +3;80;160;;; +3;240;272;;; +3;240;288;;; +3;240;528;;; +3;240;544;;; +3;400;272;;; +3;400;288;;; +3;560;400;;; +3;560;416;;; +3;560;528;;; +3;560;544;;; +3;720;272;;; +3;720;288;;; +3;720;400;;; +3;720;416;;; +3;720;528;;; +3;720;544;;; +3;880;144;;; +3;880;160;;; +4;96;144;;; +4;96;160;;; +4;256;272;;; +4;256;288;;; +4;256;528;;; +4;256;544;;; +4;416;272;;; +4;416;288;;; +4;576;400;;; +4;576;416;;; +4;576;528;;; +4;576;544;;; +4;736;272;;; +4;736;288;;; +4;736;400;;; +4;736;416;;; +4;736;528;;; +4;736;544;;; +4;896;144;;; +4;896;160;;; +2;160;80;;; +2;160;208;;; +2;176;80;;; +2;176;208;;; +2;320;336;;; +2;320;464;;; +2;336;336;;; +2;336;464;;; +2;480;208;;; +2;480;336;;; +2;496;208;;; +2;496;336;;; +2;640;592;;; +2;656;592;;; +2;800;80;;; +2;800;208;;; +2;816;80;;; +2;816;208;;; +15;208;96;;; +199;528;624;smallkeyChest;dColor;dc_smallkey_0;; +199;720;48;nightmarekey;dColor;dc_nightmarekey;; +352;368;336;1 +352;368;352;1 +352;368;368;1 +352;384;320; +352;384;336; +352;384;352; +352;384;368; +352;400;320;2 +352;400;336;2 +352;400;352;2 +352;400;368;2 +352;416;320;1 +352;416;336;1 +352;416;352;1 +352;416;368;1 +352;432;320; +352;432;336; +352;432;352; +352;432;368; +352;448;320;2 +352;448;336;2 +352;448;352;2 +352;512;576; +352;512;592; +352;528;432; +352;528;448; +352;528;464; +352;528;480; +352;528;496; +352;528;512; +352;528;576; +352;528;592; +352;544;432; +352;544;448; +352;544;464; +352;544;480; +352;544;496; +352;544;576; +352;544;592; +352;560;464; +352;560;480;2 +352;560;496; +352;560;576; +352;560;592;2 +352;560;608; +352;560;624; +352;560;640; +352;576;464; +352;576;480; +352;576;496;1 +352;576;576; +352;576;592; +352;576;608;1 +352;576;624; +352;576;640; +352;592;464; +352;592;480; +352;592;496; +352;592;512; +352;592;576; +352;592;592; +352;592;608; +352;592;624; +352;592;640; +352;608;432; +352;608;448; +352;608;464; +352;608;480; +352;608;496; +352;608;512; +352;688;336;2 +352;688;352;2 +352;704;320; +352;704;336;1 +352;704;352;1 +352;704;368;2 +352;720;320;2 +352;720;336; +352;720;352; +352;720;368;1 +352;736;320;1 +352;736;336;2 +352;736;352;2 +352;736;368; +352;752;320; +352;752;336;1 +352;752;352;1 +352;752;368; +352;768;336; +352;768;352; +130;864;176;;;;;; +130;880;176;;;;;; +130;880;192;;;;;; +130;896;176;;;;;; +130;896;192;;;;;; +130;896;208;;;;;; +130;912;176;;;;;; +130;912;192;;;;;; +130;928;176;;;;;; +129;192;480;;;;;; +129;192;496;;;;;; +129;208;480;;;;;; +129;208;496;;;;;; +129;208;512;;;;;; +129;224;496;;;;;; +129;224;512;;;;;; +129;272;496;;;;;; +129;272;512;;;;;; +129;288;480;;;;;; +129;288;496;;;;;; +129;288;512;;;;;; +129;304;480;;;;;; +129;304;496;;;;;; +129;672;624;;;;;; +129;688;624;;;;;; +129;704;624;;;;;; +129;704;640;;;;;; +129;752;624;;;;;; +129;752;640;;;;;; +129;768;624;;;;;; +129;784;624;;;;;; +129;832;192;;;;;; +129;832;208;;;;;; +129;832;224;;;;;; +129;832;240;;;;;; +129;832;256;;;;;; +129;848;208;;;;;; +129;848;224;;;;;; +129;848;240;;;;;; +129;864;224;;;;;; +128;208;448;;;;;; +128;224;448;;;;;; +128;240;432;;;;;; +128;240;448;;;;;; +128;256;432;;;;;; +128;256;448;;;;;; +128;272;448;;;;;; +128;288;448;;;;;; +128;672;576;;;;;; +128;688;576;;;;;; +128;704;560;;;;;; +128;704;576;;;;;; +128;752;560;;;;;; +128;752;576;;;;;; +128;768;576;;;;;; +128;784;576;;;;;; +128;896;256;;;;;; +128;912;240;;;;;; +128;912;256;;;;;; +128;928;224;;;;;; +128;928;240;;;;;; +128;928;256;;;;;; +128;944;208;;;;;; +128;944;224;;;;;; +128;944;240;;;;;; +128;944;256;;;;;; +289;512;624;dc_smallkey_0 +289;568;248;dc_smallkey_1 +289;720;112;dc_nightmarekey +289;720;224;dc_smallkey_2 +261;88;144;2;dc_door_9;1; +261;88;160;3;dc_door_9;3;dc_nightmare_key +261;160;88;2;dc_door_10;; +261;160;216;;dc_door_8;; +261;176;88;2;dc_door_10;2; +261;176;216;1;dc_door_8;2;dc_door_8_key +261;248;272;;dc_door_7;1; +261;248;288;;dc_door_7;3; +261;320;344;;dc_door_6;; +261;320;472;;dc_door_0;; +261;336;344;;dc_door_6;2; +261;336;472;;dc_door_0;2; +261;408;272;;dc_door_5;1; +261;408;288;;dc_door_5;3; +261;480;344;;dc_door_4;; +261;496;344;;dc_door_4;2; +261;568;400;;dc_door_3;1; +261;568;416;1;dc_door_3;3;dc_door_3_key +261;640;600;;dc_door_2;; +261;656;600;;dc_door_2;2; +261;728;528;;dc_door_1;1; +261;728;544;;dc_door_1;3; +261;800;88;;dc_door_12;; +261;800;216;;dc_door_13;; +261;816;88;;dc_door_12;2; +261;816;216;;dc_door_13;2; +261;888;144;;dc_door_11;1; +261;888;160;1;dc_door_11;3;dc_door_11_key +269;400;528;;dc_wall;1;; +269;400;544;;dc_wall;3;; +153;256;624;;;dc_entry;overworld.map;dc_entry;;1; +245;200;688;dColor;; +335;48;256;dungeon_color_barriere;; +335;64;256;dungeon_color_barriere;; +335;80;256;dungeon_color_barriere;; +335;96;256;dungeon_color_barriere;; +335;112;256;dungeon_color_barriere;; +335;128;176;dungeon_color_barriere;True; +335;128;192;dungeon_color_barriere;True; +335;128;256;dungeon_color_barriere;; +284;176;688;;;; +248;336;544;dc_wall;; +337;208;320;dc_switch_1;2;0;;10 +337;208;352;dc_switch_1;2;1;3;81 +337;208;384;dc_switch_1;2;0;6;136 +337;240;320;dc_switch_1;2;1;1;21 +337;240;352;dc_switch_1;2;0;4;170 +337;240;384;dc_switch_1;2;1;7;336 +337;272;320;dc_switch_1;2;0;2;34 +337;272;352;dc_switch_1;2;1;5;276 +337;272;384;dc_switch_1;2;0;8;160 +337;368;448;dc_switch_0;2;1;;7 +337;368;496;dc_switch_0;2;0;2;13 +337;448;448;dc_switch_0;2;0;1;11 +337;448;496;dc_switch_0;2;1;3;14 +337;704;192;dc_switch_2;3;1;;7 +337;704;240;dc_switch_2;3;0;2;13 +337;752;192;dc_switch_2;3;0;1;11 +337;752;240;dc_switch_2;3;;3;14 +331;568;528 +350;224;289;beak_dc_1 +350;416;417;beak_dc_1 +350;720;161;beak_dc_1 +51;208;576;;;;;; +51;208;592;;;;;; +51;208;608;;;;;; +51;224;576;;;;;; +51;272;576;;;;;; +51;288;576;;;;;; +51;288;592;;;;;; +51;288;608;;;;;; +51;704;48;;;;;; +51;736;48;;;;;; +330;32;256;dungeon_color_barriere +472;384;336; +472;416;352;False +472;544;608;False +472;544;640;False +472;576;496; +472;704;336; +472;752;352; +471;208;496;1 +471;256;448; +471;288;496;1 +471;688;576; +471;688;624;1 +471;768;576; +471;768;624;1 +471;848;240;1 +471;896;176;2 +471;944;256; +473;560;208;1;dc_karakoro_2;dc_karakoros_1 +473;560;224;;dc_karakoro_4;dc_karakoros_1 +473;576;208;;dc_karakoro_3;dc_karakoros_1 +473;576;224;2;dc_karakoro_5;dc_karakoros_1 +473;704;480;;dc_karakoro_0;dc_chest_beak +473;736;480;1;dc_karakoro_1;dc_chest_beak +424;368;208 +424;400;176 +423;224;192;; +423;224;240;; +423;272;192;; +423;272;240;; +423;368;224;; +423;384;208;; +423;448;224;; +423;464;208;; +252;240;472;dc_et_0 +252;432;192;dc_et_2 +252;688;600;dc_et_1 +252;880;224;dc_et_4 +22;488;216;;;; +22;648;464;;;; +22;648;480;;;; +22;728;408;;;; +22;728;544;;;; +393;248;60;color_fairy +341;32;176;;;;;; +341;32;192;;;;;; +341;32;208;;;;;; +341;32;224;;;;;; +341;32;240;;;;;; +341;48;176;;;;;; +341;48;192;;;;;; +341;48;208;;;;;; +341;48;224;;;;;; +341;48;240;;;;;; +341;64;208;;;;;; +341;64;224;;;;;; +341;64;240;;;;;; +341;80;208;;;;;; +341;80;224;;;;;; +341;80;240;;;;;; +341;96;208;;;;;; +341;96;224;;;;;; +341;96;240;;;;;; +341;112;208;;;;;; +341;112;224;;;;;; +341;112;240;;;;;; +341;128;208;;;;;; +341;128;224;;;;;; +341;128;240;;;;;; +341;368;384;;14;;;1; +341;384;304;;14;;;1; +341;384;384;;14;;;1; +341;400;384;;14;;;1; +341;416;384;;14;;;1; +341;432;304;;14;;;1; +341;432;384;;14;;;1; +341;448;304;;14;;;1; +341;672;336;;;;;; +341;672;352;;;;;; +341;720;592;;;;;; +341;720;608;;;;;; +341;736;592;;;;;; +341;736;608;;;;;; +341;784;336;;;;;; +341;784;352;;;;;; +339;528;192;;;;;; +339;528;240;;;;;;2 +339;608;192;;;;;;1 +339;608;240;;;;;; +339;688;448;;;;;;1 +339;768;496;;;;;; +342;144;216;2 +342;352;344; +342;408;304;1 +342;464;344;2 +342;568;512;3 +342;624;600;2 +342;728;560;1 +200;360;604;;dc_rubyGreen_11;rubyGreen;; +200;368;588;;dc_rubyGreen_5;rubyGreen;; +200;368;620;;dc_rubyGreen_18;rubyGreen;; +200;376;572;;dc_rubyGreen_0;rubyGreen;; +200;376;604;;dc_rubyGreen_12;rubyGreen;; +200;376;636;;dc_rubyGreen_24;rubyGreen;; +200;384;588;;dc_rubyGreen_6;rubyGreen;; +200;384;620;;dc_rubyGreen_19;rubyGreen;; +200;392;572;;dc_rubyGreen_1;rubyGreen;; +200;392;604;;dc_rubyGreen_13;rubyGreen;; +200;392;636;;dc_rubyGreen_25;rubyGreen;; +200;400;588;;dc_rubyGreen_7;rubyGreen;; +200;400;620;;dc_rubyGreen_20;rubyGreen;; +200;408;572;;dc_rubyGreen_2;rubyGreen;; +200;408;604;;dc_rubyGreen_14;rubyGreen;; +200;408;636;;dc_rubyGreen_26;rubyGreen;; +200;416;588;;dc_rubyGreen_8;rubyGreen;; +200;416;620;;dc_rubyGreen_21;rubyGreen;; +200;424;572;;dc_rubyGreen_3;rubyGreen;; +200;424;604;;dc_rubyGreen_15;rubyGreen;; +200;424;636;;dc_rubyGreen_27;rubyGreen;; +200;432;588;;dc_rubyGreen_9;rubyGreen;; +200;432;620;;dc_rubyGreen_22;rubyGreen;; +200;440;572;;dc_rubyGreen_4;rubyGreen;; +200;440;604;;dc_rubyGreen_16;rubyGreen;; +200;440;636;;dc_rubyGreen_28;rubyGreen;; +200;448;588;;dc_rubyGreen_10;rubyGreen;; +200;448;620;;dc_rubyGreen_23;rubyGreen;; +200;456;604;;dc_rubyGreen_17;rubyGreen;; +168;-8;152;dc_door_9;(dc_nightmare_key&!dc_enter_nightmare)|dc_nightmare_killed; +168;144;448;dc_door_0;!dc_room_0_enter|dc_et_0; +168;168;24;dc_door_10;dc_nightmare_killed&!dc_enter_fairy; +168;168;152;dc_door_8;dc_door_8_key; +168;272;280;dc_door_7;dc_switch_1|!dc_room_3_enter; +168;328;320;dc_door_6;dc_button_0&(!dc_room_3_enter|dc_switch_1); +168;432;280;dc_door_5;dc_button_0; +168;488;320;dc_door_4;!dc_room_4_enter|dc_stone_hinox; +168;568;184;dc_karakoros_1;dc_karakoro_2&dc_karakoro_3&dc_karakoro_4&dc_karakoro_5; +168;592;408;dc_door_3;dc_door_3_key&(!dc_room_4_enter|dc_stone_hinox); +168;648;664;dc_door_2;(!dc_room_1_enter|dc_et_1)&(!dc_room_2_enter); +168;768;448;dc_chest_beak;dc_karakoro_0&dc_karakoro_1; +168;808;8;dc_door_12;dc_door_11_key&(!dc_room_5_enter|dc_giant_buzz_blob); +168;808;280;dc_door_13;!dc_room_6_enter|dc_et_4; +168;808;536;dc_door_1;!dc_room_1_enter|dc_et_1; +168;968;152;dc_door_11;dc_door_11_key&(!dc_room_5_enter|dc_giant_buzz_blob); +167;-32;152;dc_enter_nightmare;0 +167;144;472;dc_room_0_enter; +167;144;496;dc_et_0; +167;152;344;dc_room_3_enter;0 +167;168;0;dc_enter_fairy;0 +167;328;296;dc_button_0; +167;544;408;dc_room_4_enter; +167;648;688;dc_room_2_enter; +167;824;296;dc_room_6_enter; +167;824;584;dc_et_1; +167;824;608;dc_room_1_enter; +167;840;296;dc_et_4; +167;992;152;dc_room_5_enter;0 +302;192;304;;;;; +302;192;384;;;;; +302;192;560;;;;; +302;192;640;;;;; +302;224;432;;;;; +302;272;432;;;;; +302;288;304;;;;; +302;288;384;;;;; +302;304;560;;;;; +302;304;640;;;;; +302;672;48;;;;; +302;688;176;;;;; +302;688;256;;;;; +302;768;48;;;;; +302;768;176;;;;; +302;768;256;;;;; +307;64;160;;;;; +307;112;160;;;;; +307;208;32;;;;; +307;208;160;;;;; +307;288;32;;;;; +307;288;160;;;;; +307;384;160;;;;; +307;432;160;;;;; +307;528;160;;;;; +307;544;544;;;;; +307;592;544;;;;; +307;608;160;;;;; +307;688;416;;;;; +307;688;544;;;;; +307;768;416;;;;; +307;768;544;;;;; +307;864;160;;;;; +307;912;160;;;;; +308;480;192;;;;; +308;480;240;;;;; +308;800;448;;;;; +308;800;496;;;;; +309;208;144;;;;; +309;288;144;;;;; +309;688;144;;;;; +309;688;528;;;;; +309;752;144;;;;; +309;768;528;;;;; +310;336;192;;;;; +310;336;240;;;;; +170;88;144;dc_enter_nightmare;1;;; +170;176;88;dc_enter_fairy;2;;; +170;248;528;dc_room_0_enter;1;;; +170;320;344;dc_room_3_enter;;;; +170;568;400;dc_room_4_enter;1;;; +170;568;528;dc_room_2_enter;1;;;True +170;640;600;dc_room_2_enter;;;; +170;728;544;dc_room_1_enter;3;;; +170;784;80;movestone_reset_middle;2;;32; +170;800;88;movestone_reset;2;;; +170;816;216;dc_room_6_enter;2;;; +170;888;144;dc_room_5_enter;1;;; +11;224;96;;; +11;240;96;;; +11;256;96;;; +11;272;96;;; +12;288;48;;; +12;288;64;;; +12;288;80;;; +13;208;48;;; +13;208;64;;; +13;208;80;;; +25;688;64;;;; +25;688;80;;;; +25;704;80;;;; +25;736;80;;;; +25;752;64;;;; +25;752;80;;;; +507;880;48;dc_giant_buzz_blob +506;560;292;dc_stone_hinox +223;384;192;0;;;;;;; +223;400;208;0;;;;;;; +223;416;224;0;;;;;;; +223;432;240;0;;;;;;; +223;704;496;0;;;;;;; +223;720;480;0;;;;;;; +223;736;464;0;;;;;;; +223;752;96;;;;;;;;movestone_reset +223;752;112;;;;;;;;movestone_reset_middle +223;752;128;;;;;;;;movestone_reset +287;224;688;96 +519;80;64;dc_nightmare_killed +395;240;560;npc_color_blue; +395;256;560;npc_color_red;True +164;192;0;dc_enter_fairy;1;dialogBox;dc_fairy_music; +164;256;472;dc_et_0;1;dialogBox;sound_secrete; +164;328;280;dc_button_0;1;dialogBox;sound_secrete; +164;768;600;dc_et_1;1;dialogBox;sound_secrete; +164;896;240;dc_et_4;1;dialogBox;sound_secrete; +166;168;280;dc_switch_1;1;dc_switch_1_sound +166;464;192;dc_et_2;1;dc_spawn_chest_2 +166;464;448;dc_switch_0;1;dc_spawn_chest_0 +166;560;208;dc_karakoros_1;1;dc_spawn_key_0 +166;736;208;dc_switch_2;1;dc_spawn_key_1 +166;784;448;dc_chest_beak;1;dc_spawn_chest_1 +231;192;176;;;;;; +231;192;192;;;;;; +231;192;240;;;;;; +231;192;256;;heart;;;; +231;192;432;;powder_1;;;; +231;192;448;;;;;; +231;192;512;;;;;; +231;208;176;;;;;; +231;208;256;;;;;; +231;208;432;;;;;; +231;288;176;;;;;; +231;288;256;;;;;; +231;288;432;;;;;; +231;304;176;;fairy;;;; +231;304;192;;;;;; +231;304;240;;;;;; +231;304;256;;;;;; +231;304;432;;ruby;;;; +231;304;448;;;;;; +231;304;512;;;;;; +231;352;240;;;;;; +231;352;256;;;;;; +231;352;304;;;;;; +231;384;208;;;;;; +231;400;224;;;;;; +231;416;240;;;;;; +231;448;240;;;;;; +231;464;240;;;;;; +231;464;256;;;;;; +231;464;384;;;;;; +231;544;512;;bomb_1;;;; +231;672;560;;;;;; +231;672;640;;ruby;;;; +231;688;560;;;;;; +231;688;640;;;;;; +231;768;560;;;;;; +231;768;640;;;;;; +231;784;560;;powder_1;;;; +231;784;640;;;;;; +353;512;320 +353;512;384 +353;560;352 +353;576;352 +353;624;320 +353;624;384 +160;720;80; +246;704;64; +246;720;64; +246;720;80; +246;736;64; +108;224;48;;;;;; +108;224;64;;;;;; +108;224;80;;;;;; +108;240;48;;;;;; +108;240;64;;;;;; +108;240;80;;;;;; +108;256;48;;;;;; +108;256;64;;;;;; +108;256;80;;;;;; +108;272;48;;;;;; +108;272;64;;;;;; +108;272;80;;;;;; diff --git a/bin/Data/Maps/dungeon_color.map.data b/bin/Data/Maps/dungeon_color.map.data new file mode 100644 index 0000000..43b6f6d --- /dev/null +++ b/bin/Data/Maps/dungeon_color.map.data @@ -0,0 +1,45 @@ +62 +43 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/dungeon_end.map.data b/bin/Data/Maps/dungeon_end.map.data new file mode 100644 index 0000000..ac712ae --- /dev/null +++ b/bin/Data/Maps/dungeon_end.map.data @@ -0,0 +1,18 @@ +10 +16 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/egg_boss_room.map b/bin/Data/Maps/egg_boss_room.map new file mode 100644 index 0000000..9d750bf --- /dev/null +++ b/bin/Data/Maps/egg_boss_room.map @@ -0,0 +1,587 @@ +3 +0 +0 +egg.png +10 +8 +3 +,5,10,10,10,10,10,10,6,, +5,18,7,7,7,7,7,7,17,6, +12,7,7,7,7,7,7,7,7,13, +12,7,7,7,9,14,7,7,7,13, +12,7,7,7,15,8,7,7,7,13, +12,7,7,7,7,7,7,7,7,13, +4,16,7,7,7,7,7,7,19,3, +,4,11,11,11,11,11,11,3,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +31 +0;0;32;;; +0;0;48;;; +0;0;64;;; +0;0;80;;; +0;16;16;;; +0;16;96;;; +0;32;0;;; +0;32;112;;; +0;48;0;;; +0;48;112;;; +0;64;112;;; +0;80;112;;; +0;96;0;;; +0;96;112;;; +0;112;0;;; +0;112;112;;; +0;128;16;;; +0;128;96;;; +0;144;32;;; +0;144;48;;; +0;144;64;;; +0;144;80;;; +153;72;-8;;;;final stairs.map;final_entry;3;5;False +153;72;80;;;egg_boss_entry;overworld.map;;1;6;False +133;72;32;spawn_final_stairs +285;-40;0;;;; +287;-40;24;17 +522;72;56;killed_final_boss +164;64;0;final_remove_wall;;c1;; +164;80;0;final_remove_wall;;c1;; +164;184;0;killed_final_boss;1;dialogBox;final_boss_death; diff --git a/bin/Data/Maps/egg_boss_room.map.data b/bin/Data/Maps/egg_boss_room.map.data new file mode 100644 index 0000000..c90cdd4 --- /dev/null +++ b/bin/Data/Maps/egg_boss_room.map.data @@ -0,0 +1,10 @@ +10 +8 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/egg_entry.map b/bin/Data/Maps/egg_entry.map new file mode 100644 index 0000000..a8b6767 --- /dev/null +++ b/bin/Data/Maps/egg_entry.map @@ -0,0 +1,715 @@ +3 +0 +1 +egg.png +10 +17 +3 +,4,11,16,20,20,19,11,3,, +,5,10,18,20,20,17,10,6,, +5,18,21,21,21,21,21,21,17,6, +12,21,21,21,21,21,21,21,21,13, +12,21,21,21,21,21,21,21,21,13, +12,21,21,21,21,21,21,21,21,13, +12,21,21,21,21,21,21,21,21,13, +4,16,21,21,20,20,21,21,19,3, +,4,11,16,20,20,19,11,3,, +,5,10,18,20,20,17,10,6,, +5,18,20,20,20,20,20,20,17,6, +12,20,20,20,20,20,20,20,20,13, +12,20,20,20,20,20,20,20,20,13, +12,20,20,20,20,20,20,20,20,13, +12,20,20,20,20,20,20,20,20,13, +4,16,20,20,20,20,20,20,19,3, +,4,11,11,2,1,11,11,3,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +132 +0;0;48;;; +0;0;64;;; +0;0;80;;; +0;0;96;;; +0;0;176;;; +0;0;192;;; +0;0;208;;; +0;0;224;;; +0;16;32;;; +0;16;112;;; +0;16;160;;; +0;16;240;;; +0;32;16;;; +0;32;128;;; +0;32;144;;; +0;32;256;;; +0;48;16;;; +0;48;128;;; +0;48;144;;; +0;48;256;;; +0;96;16;;; +0;96;128;;; +0;96;144;;; +0;96;256;;; +0;112;16;;; +0;112;128;;; +0;112;144;;; +0;112;256;;; +0;128;32;;; +0;128;112;;; +0;128;160;;; +0;128;240;;; +0;144;48;;; +0;144;64;;; +0;144;80;;; +0;144;96;;; +0;144;176;;; +0;144;192;;; +0;144;208;;; +0;144;224;;; +3;64;256;;; +4;80;256;;; +174;48;280;egg_entry +153;72;264;;;egg_entry;overworld.map;egg_entry;1;; +299;72;256;;;;;; +341;16;48;;;;;; +341;16;64;;;;;; +341;16;80;;;;;; +341;16;96;;;;;; +341;32;32;;;;;; +341;32;48;;;;;; +341;32;80;;;;;; +341;32;96;;;;;; +341;32;112;;;;;; +341;48;32;;;;;; +341;48;48;;;;;; +341;48;64;;;;;; +341;48;80;;;;;; +341;48;96;;;;;; +341;48;112;;;;;; +341;64;32;;;;;; +341;64;48;;;;;; +341;64;64;;;;;; +341;64;80;;;;;; +341;64;96;;;;;; +341;80;32;;;;;; +341;80;48;;;;;; +341;80;64;;;;;; +341;80;80;;;;;; +341;80;96;;;;;; +341;96;32;;;;;; +341;96;48;;;;;; +341;96;64;;;;;; +341;96;80;;;;;; +341;96;96;;;;;; +341;96;112;;;;;; +341;112;32;;;;;; +341;112;48;;;;;; +341;112;80;;;;;; +341;112;96;;;;;; +341;112;112;;;;;; +341;128;48;;;;;; +341;128;64;;;;;; +341;128;80;;;;;; +341;128;96;;;;;; +343;16;48;egg_lower_floor.map;egg_entry +343;16;64;egg_lower_floor.map;egg_entry +343;16;80;egg_lower_floor.map;egg_entry +343;16;96;egg_lower_floor.map;egg_entry +343;32;32;egg_lower_floor.map;egg_entry +343;32;48;egg_lower_floor.map;egg_entry +343;32;80;egg_lower_floor.map;egg_entry +343;32;96;egg_lower_floor.map;egg_entry +343;32;112;egg_lower_floor.map;egg_entry +343;48;32;egg_lower_floor.map;egg_entry +343;48;48;egg_lower_floor.map;egg_entry +343;48;64;egg_lower_floor.map;egg_entry +343;48;80;egg_lower_floor.map;egg_entry +343;48;96;egg_lower_floor.map;egg_entry +343;48;112;egg_lower_floor.map;egg_entry +343;64;32;egg_lower_floor.map;egg_entry +343;64;48;egg_lower_floor.map;egg_entry +343;64;64;egg_lower_floor.map;egg_entry +343;64;80;egg_lower_floor.map;egg_entry +343;64;96;egg_lower_floor.map;egg_entry +343;80;32;egg_lower_floor.map;egg_entry +343;80;48;egg_lower_floor.map;egg_entry +343;80;64;egg_lower_floor.map;egg_entry +343;80;80;egg_lower_floor.map;egg_entry +343;80;96;egg_lower_floor.map;egg_entry +343;96;32;egg_lower_floor.map;egg_entry +343;96;48;egg_lower_floor.map;egg_entry +343;96;64;egg_lower_floor.map;egg_entry +343;96;80;egg_lower_floor.map;egg_entry +343;96;96;egg_lower_floor.map;egg_entry +343;96;112;egg_lower_floor.map;egg_entry +343;112;32;egg_lower_floor.map;egg_entry +343;112;48;egg_lower_floor.map;egg_entry +343;112;80;egg_lower_floor.map;egg_entry +343;112;96;egg_lower_floor.map;egg_entry +343;112;112;egg_lower_floor.map;egg_entry +343;128;48;egg_lower_floor.map;egg_entry +343;128;64;egg_lower_floor.map;egg_entry +343;128;80;egg_lower_floor.map;egg_entry +343;128;96;egg_lower_floor.map;egg_entry +285;0;280;;;; +302;0;144;;;;True; +302;32;64;;;;True; +302;112;64;;;;True; +302;144;144;;;;True; +287;24;280;17 +249;0;-112;0.65;0.1 diff --git a/bin/Data/Maps/egg_entry.map.data b/bin/Data/Maps/egg_entry.map.data new file mode 100644 index 0000000..6657011 --- /dev/null +++ b/bin/Data/Maps/egg_entry.map.data @@ -0,0 +1,19 @@ +10 +17 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/egg_lower_floor.map b/bin/Data/Maps/egg_lower_floor.map new file mode 100644 index 0000000..bf93352 --- /dev/null +++ b/bin/Data/Maps/egg_lower_floor.map @@ -0,0 +1,837 @@ +3 +0 +0 +egg.png +30 +40 +3 +,,,,,5,10,10,10,10,10,10,10,10,6,,,,,,,,,,,,,,,, +,,,,,12,5,10,10,10,10,10,10,6,13,,,,,,,,,,,,,,,, +,,,,,12,12,5,10,10,10,10,6,13,13,,,,,,,,,,,,,,,, +,,,,,12,12,12,5,10,10,6,13,13,13,,,,,,,,,,,,,,,, +,,,,,12,12,12,12,21,21,13,13,13,13,,,,7,7,7,7,7,7,7,,,,,, +,,,,,12,12,12,4,11,11,3,13,13,13,,,,7,7,7,7,7,7,19,,,,,, +,,,,,18,12,4,16,7,7,19,3,13,17,12,7,7,7,7,7,7,7,7,13,,,,,, +,,,,,10,18,0,12,7,7,13,0,17,10,4,11,11,16,7,7,19,11,11,3,,,,,, +7,17,10,10,6,5,10,10,18,7,7,17,10,10,6,5,10,10,18,7,7,17,10,10,6,5,10,10,18,7, +7,7,7,7,13,12,7,7,7,7,7,7,7,7,13,12,7,7,7,7,7,7,7,7,13,12,7,7,7,7, +7,7,7,7,17,18,7,7,7,7,7,7,7,7,17,18,7,7,7,7,7,7,7,7,17,18,7,7,7,7, +7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, +7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, +7,7,7,7,19,16,7,7,7,7,7,7,7,7,19,16,7,7,7,7,7,7,7,7,19,16,7,7,7,7, +7,7,7,7,13,12,7,7,7,7,7,7,7,7,13,12,7,7,7,7,7,7,7,7,13,12,7,7,7,7, +7,19,11,11,3,4,11,11,16,7,7,19,11,11,3,4,11,11,16,7,7,19,11,11,3,4,11,11,16,7, +7,17,10,10,6,5,10,10,18,7,7,17,10,10,6,5,10,10,18,7,7,17,10,10,6,5,10,10,18,7, +7,7,7,7,13,12,7,7,7,7,7,7,7,7,13,12,7,7,7,7,7,7,7,7,13,12,7,7,7,7, +7,7,7,7,17,18,7,7,7,7,7,7,7,7,17,18,7,7,7,7,7,7,7,7,17,18,7,7,7,7, +7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, +7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, +7,7,7,7,19,16,7,7,7,7,7,7,7,7,19,16,7,7,7,7,7,7,7,7,19,16,7,7,7,7, +7,7,7,7,13,12,7,7,7,7,7,7,7,7,13,12,7,7,7,7,7,7,7,7,13,12,7,7,7,7, +7,19,11,11,3,4,11,11,16,7,7,19,11,11,3,4,11,11,16,7,7,19,11,11,3,4,11,11,16,7, +,,,,,,5,10,18,7,7,17,10,6,,5,10,10,18,7,7,17,10,10,6,,,,,, +,,,,,5,18,7,7,7,7,7,7,17,6,12,7,7,7,7,7,7,7,7,13,,,,,, +,,,,,12,7,7,7,7,7,7,7,7,13,,,,,,,,,,,,,,,, +,,,,,12,7,7,7,7,7,7,7,7,13,,,,,,,,,,,,,,,, +,,,,,12,7,7,7,7,7,7,7,7,13,,,,22,22,22,22,22,22,22,,,,,, +,,,,,12,7,7,7,7,7,7,7,7,13,,22,22,22,22,22,22,22,22,22,,,,,, +,,,,,4,16,7,7,7,7,7,7,19,3,,22,22,22,22,22,22,22,22,22,,,,,, +,,,,,,4,11,16,7,7,19,11,3,,,22,22,22,22,22,22,22,22,22,,,,,, +,,,,,,5,10,18,20,20,17,10,6,,22,22,22,22,22,22,22,22,22,22,,,,,, +,,,,,5,18,20,20,20,20,20,20,17,6,22,22,22,22,22,22,22,22,22,22,,,,,, +,,,,,12,20,20,20,20,20,20,20,20,13,22,22,22,22,22,22,22,22,22,22,,,,,, +,,,,,12,20,20,20,20,20,20,20,20,13,22,22,22,22,22,22,22,22,22,22,,,,,, +,,,,,12,20,20,20,20,20,20,20,20,13,22,22,22,22,22,22,22,22,22,22,,,,,, +,,,,,12,20,20,20,20,20,20,20,20,13,22,22,22,22,22,22,22,22,22,22,,,,,, +,,,,,4,16,20,20,20,20,20,20,19,3,22,22,22,22,22,22,22,22,22,22,,,,,, +,,,,,,4,11,11,2,1,11,11,3,,22,22,22,22,22,22,22,22,22,22,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +185 +171;144;124;32;4;egg_lamps_1;1;False; +0;80;144;;; +0;80;160;;; +0;80;208;;; +0;80;224;;; +0;80;272;;; +0;80;288;;; +0;80;336;;; +0;80;352;;; +0;80;416;;; +0;80;432;;; +0;80;448;;; +0;80;464;;; +0;80;544;;; +0;80;560;;; +0;80;576;;; +0;80;592;;; +0;96;128;;; +0;96;240;;; +0;96;256;;; +0;96;368;;; +0;96;400;;; +0;96;480;;; +0;96;528;;; +0;96;608;;; +0;112;48;;; +0;112;64;;; +0;112;80;;; +0;112;128;;; +0;112;240;;; +0;112;256;;; +0;112;368;;; +0;112;384;;; +0;112;496;;; +0;112;512;;; +0;112;624;;; +0;128;32;;; +0;128;96;;; +0;128;112;;; +0;128;128;;; +0;128;240;;; +0;128;256;;; +0;128;368;;; +0;128;384;;; +0;128;496;;; +0;128;512;;; +0;128;624;;; +0;144;32;;; +0;160;32;;; +0;176;32;;; +0;176;96;;; +0;176;112;;; +0;176;128;;; +0;176;240;;; +0;176;256;;; +0;176;368;;; +0;176;384;;; +0;176;496;;; +0;176;512;;; +0;176;624;;; +0;192;48;;; +0;192;64;;; +0;192;80;;; +0;192;128;;; +0;192;240;;; +0;192;256;;; +0;192;368;;; +0;192;384;;; +0;192;496;;; +0;192;512;;; +0;192;624;;; +0;208;128;;; +0;208;240;;; +0;208;256;;; +0;208;368;;; +0;208;400;;; +0;208;480;;; +0;208;528;;; +0;208;608;;; +0;224;144;;; +0;224;160;;; +0;224;208;;; +0;224;224;;; +0;224;272;;; +0;224;288;;; +0;224;336;;; +0;224;352;;; +0;224;416;;; +0;224;432;;; +0;224;448;;; +0;224;464;;; +0;224;544;;; +0;224;560;;; +0;224;576;;; +0;224;592;;; +0;240;144;;; +0;240;160;;; +0;240;208;;; +0;240;224;;; +0;240;272;;; +0;240;288;;; +0;240;336;;; +0;240;352;;; +0;256;128;;; +0;256;240;;; +0;256;256;;; +0;256;368;;; +0;272;128;;; +0;272;240;;; +0;272;256;;; +0;272;368;;; +0;288;128;;; +0;288;240;;; +0;288;256;;; +0;288;368;;; +0;336;128;;; +0;336;240;;; +0;336;256;;; +0;336;368;;; +0;352;128;;; +0;352;240;;; +0;352;256;;; +0;352;368;;; +0;368;128;;; +0;368;240;;; +0;368;256;;; +0;368;368;;; +0;384;144;;; +0;384;160;;; +0;384;208;;; +0;384;224;;; +0;384;272;;; +0;384;288;;; +0;384;336;;; +0;384;352;;; +3;144;624;;; +4;160;624;;; +153;152;312;;;egg_entry;overworld.map;;3;6;False +153;152;632;;;;overworld.map;egg_entry;1;;False +299;152;624;;;;;; +159;-32;32 +341;144;64;;;;;; +341;160;64;;;;;; +343;144;64;egg_boss_room.map;egg_boss_entry +343;160;64;egg_boss_room.map;egg_boss_entry +285;-32;0;;;; +162;144;88;;-18;32;8;;;;; +167;48;96;egg_lamps_1;0 +167;48;432;egg_lamps_0;0 +302;80;512;;;;True; +302;112;112;;;;;egg_lamps_1 +302;112;432;;;;;egg_lamps_0 +302;192;112;;;;;egg_lamps_1 +302;192;432;;;;;egg_lamps_0 +302;224;512;;;;True; +170;144;124;egg_lamps_1;3;32;4;True +170;144;380;egg_lamps_0;1;32;8;True +170;144;380;egg_lamps_0;3;32;8; +170;144;508;egg_lamps_0;3;32;8;True +170;144;508;egg_lamps_0;1;32;8; +25;128;48;;;; +25;128;64;;;; +25;128;80;;;; +25;144;48;;;; +25;144;80;;;; +25;160;48;;;; +25;160;80;;;; +25;176;48;;;; +25;176;64;;;; +25;176;80;;;; +287;0;648;17 +246;128;144; +246;128;160; +246;144;96; +246;144;112; +246;144;128; +246;144;144; +246;144;160; +246;160;96; +246;160;112; +246;160;128; +246;160;144; +246;160;160; +246;176;144; +246;176;160; diff --git a/bin/Data/Maps/egg_lower_floor.map.data b/bin/Data/Maps/egg_lower_floor.map.data new file mode 100644 index 0000000..3d171e7 --- /dev/null +++ b/bin/Data/Maps/egg_lower_floor.map.data @@ -0,0 +1,42 @@ +30 +40 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/final stairs.map b/bin/Data/Maps/final stairs.map new file mode 100644 index 0000000..55dd82a --- /dev/null +++ b/bin/Data/Maps/final stairs.map @@ -0,0 +1,596 @@ +3 +0 +0 +egg.png +5 +17 +3 +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,29, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +13 +171;128;0;;;activate_fountain;1;; +30;32;-14;;; +153;32;260;;;final_entry;;;1;5;False +134;40;272;final_move_background +137;40;0;despawn_stairs +136;32;8;activate_fountain +135;-24;-81;spawn_windfish +287;-32;256;88 +364;32;-40;final;-8.32.32.32;True;; +175;-16;32;;;final_test_instrument +175;32;-13;;;final_stair_stand +175;32;248;;;final_stair_walk +175;80;32;;;final_test diff --git a/bin/Data/Maps/final stairs.map.data b/bin/Data/Maps/final stairs.map.data new file mode 100644 index 0000000..1cdf13a --- /dev/null +++ b/bin/Data/Maps/final stairs.map.data @@ -0,0 +1,19 @@ +5 +17 +;;;;; +;;;;; +;;;;; +;;;;; +;;;;; +;;;;; +;;;;; +;;;;; +;;;;; +;;;;; +;;;;; +;;;;; +;;;;; +;;;;; +;;;;; +;;;;; +;;;;; diff --git a/bin/Data/Maps/hauntedhouse.map b/bin/Data/Maps/hauntedhouse.map new file mode 100644 index 0000000..f3ab673 --- /dev/null +++ b/bin/Data/Maps/hauntedhouse.map @@ -0,0 +1,616 @@ +3 +0 +0 +house.png +10 +8 +3 +19,47,100,47,47,47,47,47,47,21, +45,96,81,51,51,96,96,96,51,46, +45,96,61,51,51,51,49,91,49,46, +45,51,29,51,51,51,51,51,51,46, +45,51,51,96,51,51,51,51,96,46, +45,51,96,96,96,51,51,51,51,46, +45,96,96,51,51,51,51,51,51,46, +20,48,48,48,39,38,48,48,48,22, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +60 +382;32;144; +283;16;16; +283;16;32; +283;16;96; +283;32;80; +283;32;96; +283;48;64; +283;48;80; +283;64;80; +283;80;16; +283;96;16; +283;112;16; +283;128;64; +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;0;64;;; +0;0;80;;; +0;0;96;;; +0;16;0;;; +0;16;112;;; +0;32;112;;; +0;48;0;;; +0;48;112;;; +0;64;0;;; +0;72;128;;; +0;80;0;;; +0;96;0;;; +0;96;112;;; +0;112;0;;; +0;112;112;;; +0;128;0;;; +0;128;112;;; +0;144;16;;; +0;144;32;;; +0;144;48;;; +0;144;64;;; +0;144;80;;; +0;144;96;;; +3;64;112;;; +4;80;112;;; +2;32;13;;; +153;72;120;;;hauntedhouse;overworld.map;hauntedhouse;1;; +299;72;112;;;;;50; +285;0;144;;;;85 +302;128;16;;;;True; +9;32;33;;; +9;32;48;;; +9;96;32;;; +9;112;32;;; +9;128;32;;; +287;0;176;71 +164;128;96;ghost_shell;1;pot2;.shell.shell_17..; +164;128;96;ghost_shell;;pot2;....; +232;112;80;;;;;; +232;112;96;;;;;; +232;128;48;;;;;; +232;128;80;;;;;; +175;72;104;;;ghost_house_sequence +205;32;5;npc_house_chest;;;1 diff --git a/bin/Data/Maps/hauntedhouse.map.data b/bin/Data/Maps/hauntedhouse.map.data new file mode 100644 index 0000000..c90cdd4 --- /dev/null +++ b/bin/Data/Maps/hauntedhouse.map.data @@ -0,0 +1,10 @@ +10 +8 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/helphouse1.map b/bin/Data/Maps/helphouse1.map new file mode 100644 index 0000000..4e7ff36 --- /dev/null +++ b/bin/Data/Maps/helphouse1.map @@ -0,0 +1,571 @@ +3 +0 +0 +house.png +6 +5 +3 +2,18,100,18,18,5, +15,51,81,51,51,16, +15,51,51,51,51,16, +15,51,51,51,51,16, +3,17,39,38,17,4, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +24 +382;-32;96; +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;16;0;;; +0;16;64;;; +0;40;80;;; +0;48;0;;; +0;64;0;;; +0;64;64;;; +0;80;16;;; +0;80;32;;; +0;80;48;;; +3;32;64;;; +4;48;64;;; +2;32;16;;; +174;-64;0;houseMusic +153;40;72;;;1;overworld.map;1;1;; +285;-32;32;;;; +297;40;64;90;;215;225;150; +287;-32;0;50 +57;48;32;;;;;; +205;32;8;npc_house_chest;;;1 +205;48;32;ulrira;;; diff --git a/bin/Data/Maps/helphouse1.map.data b/bin/Data/Maps/helphouse1.map.data new file mode 100644 index 0000000..77f2083 --- /dev/null +++ b/bin/Data/Maps/helphouse1.map.data @@ -0,0 +1,7 @@ +6 +5 +;;;;;; +;;;;;; +;;;;;; +;;;;;; +;;;;;; diff --git a/bin/Data/Maps/helphouse2.map b/bin/Data/Maps/helphouse2.map new file mode 100644 index 0000000..3113477 --- /dev/null +++ b/bin/Data/Maps/helphouse2.map @@ -0,0 +1,571 @@ +3 +0 +0 +house.png +6 +5 +3 +2,18,100,18,18,5, +15,51,81,51,51,16, +15,51,51,51,51,16, +15,51,51,51,51,16, +3,17,39,38,17,4, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +24 +382;-32;96; +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;16;0;;; +0;16;64;;; +0;40;80;;; +0;48;0;;; +0;64;0;;; +0;64;64;;; +0;80;16;;; +0;80;32;;; +0;80;48;;; +3;32;64;;; +4;48;64;;; +2;32;16;;; +174;-64;0;houseMusic +153;40;72;;;2;overworld.map;2;1;; +285;-32;32;;;; +297;40;64;90;;215;225;150; +287;-32;0;50 +57;48;32;;;;;; +205;32;8;npc_house_chest;;;1 +205;48;32;ulrira;;; diff --git a/bin/Data/Maps/helphouse2.map.data b/bin/Data/Maps/helphouse2.map.data new file mode 100644 index 0000000..77f2083 --- /dev/null +++ b/bin/Data/Maps/helphouse2.map.data @@ -0,0 +1,7 @@ +6 +5 +;;;;;; +;;;;;; +;;;;;; +;;;;;; +;;;;;; diff --git a/bin/Data/Maps/helphouse3.map b/bin/Data/Maps/helphouse3.map new file mode 100644 index 0000000..15e51f3 --- /dev/null +++ b/bin/Data/Maps/helphouse3.map @@ -0,0 +1,570 @@ +3 +0 +0 +house.png +6 +5 +3 +2,18,100,18,18,5, +15,51,81,51,51,16, +15,51,51,51,51,16, +15,51,51,51,51,16, +3,17,39,38,17,4, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +23 +382;-32;96; +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;16;0;;; +0;16;64;;; +0;48;0;;; +0;64;0;;; +0;64;64;;; +0;80;16;;; +0;80;32;;; +0;80;48;;; +3;32;64;;; +4;48;64;;; +2;32;16;;; +174;-64;0;houseMusic +153;40;72;;;3;overworld.map;3;1;; +285;-32;32;;;; +297;40;64;90;;215;225;150; +287;-32;0;50 +57;48;32;;;;;; +205;32;8;npc_house_chest;;;1 +205;48;32;ulrira;;; diff --git a/bin/Data/Maps/helphouse3.map.data b/bin/Data/Maps/helphouse3.map.data new file mode 100644 index 0000000..77f2083 --- /dev/null +++ b/bin/Data/Maps/helphouse3.map.data @@ -0,0 +1,7 @@ +6 +5 +;;;;;; +;;;;;; +;;;;;; +;;;;;; +;;;;;; diff --git a/bin/Data/Maps/helphouse4.map b/bin/Data/Maps/helphouse4.map new file mode 100644 index 0000000..b95996f --- /dev/null +++ b/bin/Data/Maps/helphouse4.map @@ -0,0 +1,571 @@ +3 +0 +0 +house.png +6 +5 +3 +2,18,100,18,18,5, +15,51,81,51,51,16, +15,51,51,51,51,16, +15,51,51,51,51,16, +3,17,39,38,17,4, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +24 +382;-32;96; +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;16;0;;; +0;16;64;;; +0;40;80;;; +0;48;0;;; +0;64;0;;; +0;64;64;;; +0;80;16;;; +0;80;32;;; +0;80;48;;; +3;32;64;;; +4;48;64;;; +2;32;16;;; +174;-64;0;houseMusic +153;40;72;;;4;overworld.map;4;1;; +285;-32;32;;;; +297;40;64;90;;215;225;150; +287;-32;0;50 +57;48;32;;;;;; +205;32;8;npc_house_chest;;;1 +205;48;32;ulrira;;; diff --git a/bin/Data/Maps/helphouse4.map.data b/bin/Data/Maps/helphouse4.map.data new file mode 100644 index 0000000..77f2083 --- /dev/null +++ b/bin/Data/Maps/helphouse4.map.data @@ -0,0 +1,7 @@ +6 +5 +;;;;;; +;;;;;; +;;;;;; +;;;;;; +;;;;;; diff --git a/bin/Data/Maps/helphouse5.map b/bin/Data/Maps/helphouse5.map new file mode 100644 index 0000000..a6eb621 --- /dev/null +++ b/bin/Data/Maps/helphouse5.map @@ -0,0 +1,571 @@ +3 +0 +0 +house.png +6 +5 +3 +2,18,100,18,18,5, +15,51,81,51,51,16, +15,51,51,51,51,16, +15,51,51,51,51,16, +3,17,39,38,17,4, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +24 +382;-32;96; +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;16;0;;; +0;16;64;;; +0;40;80;;; +0;48;0;;; +0;64;0;;; +0;64;64;;; +0;80;16;;; +0;80;32;;; +0;80;48;;; +3;32;64;;; +4;48;64;;; +2;32;16;;; +174;-64;0;houseMusic +153;40;72;;;5;overworld.map;5;1;; +285;-32;32;;;; +297;40;64;90;;215;225;150; +287;-32;0;50 +57;48;32;;;;;; +205;32;8;npc_house_chest;;;1 +205;48;32;ulrira;;; diff --git a/bin/Data/Maps/helphouse5.map.data b/bin/Data/Maps/helphouse5.map.data new file mode 100644 index 0000000..77f2083 --- /dev/null +++ b/bin/Data/Maps/helphouse5.map.data @@ -0,0 +1,7 @@ +6 +5 +;;;;;; +;;;;;; +;;;;;; +;;;;;; +;;;;;; diff --git a/bin/Data/Maps/helphouse6.map b/bin/Data/Maps/helphouse6.map new file mode 100644 index 0000000..9d1e0ce --- /dev/null +++ b/bin/Data/Maps/helphouse6.map @@ -0,0 +1,570 @@ +3 +0 +0 +house.png +6 +5 +3 +2,18,100,18,18,5, +15,51,81,51,51,16, +15,51,51,51,51,16, +15,51,51,51,51,16, +3,17,39,38,17,4, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +23 +382;-32;96; +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;16;0;;; +0;16;64;;; +0;48;0;;; +0;64;0;;; +0;64;64;;; +0;80;16;;; +0;80;32;;; +0;80;48;;; +3;32;64;;; +4;48;64;;; +2;32;16;;; +174;-64;0;houseMusic +153;40;72;;;6;overworld.map;6;1;; +285;-32;32;;;; +297;40;64;90;;215;225;150; +287;-32;0;50 +57;48;32;;;;;; +205;32;8;npc_house_chest;;;1 +205;48;32;ulrira;;; diff --git a/bin/Data/Maps/helphouse6.map.data b/bin/Data/Maps/helphouse6.map.data new file mode 100644 index 0000000..77f2083 --- /dev/null +++ b/bin/Data/Maps/helphouse6.map.data @@ -0,0 +1,7 @@ +6 +5 +;;;;;; +;;;;;; +;;;;;; +;;;;;; +;;;;;; diff --git a/bin/Data/Maps/helphouse7.map b/bin/Data/Maps/helphouse7.map new file mode 100644 index 0000000..0150664 --- /dev/null +++ b/bin/Data/Maps/helphouse7.map @@ -0,0 +1,570 @@ +3 +0 +0 +house.png +6 +5 +3 +2,18,100,18,18,5, +15,51,81,51,51,16, +15,51,51,51,51,16, +15,51,51,51,51,16, +3,17,39,38,17,4, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +23 +382;-32;96; +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;16;0;;; +0;16;64;;; +0;48;0;;; +0;64;0;;; +0;64;64;;; +0;80;16;;; +0;80;32;;; +0;80;48;;; +3;32;64;;; +4;48;64;;; +2;32;16;;; +174;-64;0;houseMusic +153;40;72;;;7;overworld.map;7;1;; +285;-32;32;;;; +297;40;64;90;;215;225;150; +287;-32;0;50 +57;48;32;;;;;; +205;32;8;npc_house_chest;;;1 +205;48;32;ulrira;;; diff --git a/bin/Data/Maps/helphouse7.map.data b/bin/Data/Maps/helphouse7.map.data new file mode 100644 index 0000000..77f2083 --- /dev/null +++ b/bin/Data/Maps/helphouse7.map.data @@ -0,0 +1,7 @@ +6 +5 +;;;;;; +;;;;;; +;;;;;; +;;;;;; +;;;;;; diff --git a/bin/Data/Maps/helphouse8.map b/bin/Data/Maps/helphouse8.map new file mode 100644 index 0000000..308b5ee --- /dev/null +++ b/bin/Data/Maps/helphouse8.map @@ -0,0 +1,570 @@ +3 +0 +0 +house.png +6 +5 +3 +2,18,100,18,18,5, +15,51,81,51,51,16, +15,51,51,51,51,16, +15,51,51,51,51,16, +3,17,39,38,17,4, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +23 +382;-32;96; +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;16;0;;; +0;16;64;;; +0;48;0;;; +0;64;0;;; +0;64;64;;; +0;80;16;;; +0;80;32;;; +0;80;48;;; +3;32;64;;; +4;48;64;;; +2;32;16;;; +174;-64;0;houseMusic +153;40;72;;;8;overworld.map;8;1;; +285;-32;32;;;; +297;40;64;90;;215;225;150; +287;-32;0;50 +57;48;32;;;;;; +205;32;8;npc_house_chest;;;1 +205;48;32;ulrira;;; diff --git a/bin/Data/Maps/helphouse8.map.data b/bin/Data/Maps/helphouse8.map.data new file mode 100644 index 0000000..77f2083 --- /dev/null +++ b/bin/Data/Maps/helphouse8.map.data @@ -0,0 +1,7 @@ +6 +5 +;;;;;; +;;;;;; +;;;;;; +;;;;;; +;;;;;; diff --git a/bin/Data/Maps/house mountain.map b/bin/Data/Maps/house mountain.map new file mode 100644 index 0000000..51a277d --- /dev/null +++ b/bin/Data/Maps/house mountain.map @@ -0,0 +1,616 @@ +3 +0 +0 +house.png +10 +8 +3 +25,43,100,43,43,43,43,43,43,23, +42,61,81,57,,,,,,41, +42,29,51,57,58,58,51,58,58,41, +42,55,51,60,51,51,51,51,51,41, +42,51,51,51,51,51,51,51,51,41, +42,51,51,51,51,51,51,51,51,41, +42,51,51,51,51,51,51,51,51,41, +24,44,44,44,39,38,44,44,44,26, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +60 +385;64;64 +385;96;48 +385;112;16 +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;0;64;;; +0;0;80;;; +0;0;96;;; +0;16;0;;; +0;16;112;;; +0;32;0;;; +0;32;112;;; +0;48;0;;; +0;48;112;;; +0;64;0;;; +0;80;0;;; +0;96;0;;; +0;96;112;;; +0;112;0;;; +0;112;112;;; +0;128;0;;; +0;128;112;;; +0;144;16;;; +0;144;32;;; +0;144;48;;; +0;144;64;;; +0;144;80;;; +0;144;96;;; +21;48;48;;; +3;64;112;;; +4;80;112;;; +2;32;16;;; +378;96;64;chicken_dude +153;72;120;;;house_mountain;overworld.map;house_mountain;1;; +299;72;112;;;;;; +22;72;112;;;; +285;-24;0;;;; +311;112;0;;;;; +10;16;48;;; +11;64;32;;; +11;80;32;;; +11;112;32;;; +11;128;32;;; +9;16;16;;; +9;16;32;;; +13;48;16;;; +13;48;32;;; +287;-24;24;86 +205;32;8;tarin_chest;;;1 +157;64;16; +157;80;16; +157;96;16; +157;112;16; +157;128;16; +108;64;16;;;;;; +108;80;16;;;;;; +108;96;16;;;;;; +108;112;16;;;;;; +108;128;16;;;;;; diff --git a/bin/Data/Maps/house mountain.map.data b/bin/Data/Maps/house mountain.map.data new file mode 100644 index 0000000..c90cdd4 --- /dev/null +++ b/bin/Data/Maps/house mountain.map.data @@ -0,0 +1,10 @@ +10 +8 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/house raft.map b/bin/Data/Maps/house raft.map new file mode 100644 index 0000000..cd00058 --- /dev/null +++ b/bin/Data/Maps/house raft.map @@ -0,0 +1,613 @@ +3 +0 +0 +house.png +10 +8 +3 +2,18,18,18,100,18,18,18,18,5, +15,53,61,53,81,56,51,51,51,16, +15,53,29,53,55,56,51,51,51,16, +15,53,53,53,56,51,51,51,51,16, +15,58,58,51,54,51,51,51,51,16, +15,51,51,51,51,51,97,91,51,16, +15,51,51,51,51,51,51,51,51,16, +3,17,17,17,39,38,17,17,17,4, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +57 +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;0;64;;; +0;0;80;;; +0;0;96;;; +0;16;0;;; +0;16;112;;; +0;32;0;;; +0;32;112;;; +0;48;0;;; +0;48;112;;; +0;72;128;;; +0;80;0;;; +0;96;0;;; +0;96;112;;; +0;112;0;;; +0;112;112;;; +0;128;0;;; +0;128;112;;; +0;144;16;;; +0;144;32;;; +0;144;48;;; +0;144;64;;; +0;144;80;;; +0;144;96;;; +14;64;64;;; +3;64;112;;; +4;80;112;;; +2;64;16;;; +153;72;120;;;house_raft;overworld.map;house_raft;1;; +299;72;112;;;;;; +285;0;144;;;; +313;32;112;;;;; +313;112;112;;;;; +10;64;32;;; +11;16;64;;; +11;32;64;;; +12;32;16;;; +12;32;32;;; +12;64;48;;; +12;80;16;;; +12;80;32;;; +12;96;80;;; +12;112;80;;; +13;32;16;;; +13;32;32;;; +13;96;80;;; +13;112;80;;; +287;32;144;9 +358;128;80;;npc_raft;npc_raft;; +232;96;16;;;;;; +232;96;32;;;;;; +232;112;16;;;;;; +232;112;32;;;;;; +232;128;16;;;;;; +232;128;32;;;;;; diff --git a/bin/Data/Maps/house raft.map.data b/bin/Data/Maps/house raft.map.data new file mode 100644 index 0000000..c90cdd4 --- /dev/null +++ b/bin/Data/Maps/house raft.map.data @@ -0,0 +1,10 @@ +10 +8 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/house1.map b/bin/Data/Maps/house1.map new file mode 100644 index 0000000..cf83172 --- /dev/null +++ b/bin/Data/Maps/house1.map @@ -0,0 +1,615 @@ +3 +0 +0 +house.png +10 +8 +3 +19,47,47,47,47,47,47,100,47,21, +45,53,53,53,53,53,51,81,49,46, +45,101,53,101,53,53,51,51,49,46, +45,102,53,102,53,53,51,51,51,46, +45,53,53,53,53,53,51,51,97,46, +45,51,51,51,51,51,51,90,89,46, +45,51,51,51,51,51,51,51,97,46, +20,48,48,48,39,38,48,48,48,22, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +59 +382;32;176; +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;0;64;;; +0;0;80;;; +0;0;96;;; +0;16;0;;; +0;16;112;;; +0;32;0;;; +0;32;112;;; +0;48;0;;; +0;48;112;;; +0;64;0;;; +0;72;128;;; +0;80;0;;; +0;96;0;;; +0;96;112;;; +0;112;112;;; +0;128;0;;; +0;128;112;;; +0;144;16;;; +0;144;32;;; +0;144;48;;; +0;144;64;;; +0;144;80;;; +0;144;96;;; +3;64;112;;; +4;80;112;;; +2;112;16;;; +174;208;0;houseMusic +153;72;120;;;h1;overworld.map;h1;1;; +299;72;112;;;;;; +285;144;144;;;; +9;16;32;;; +9;16;48;;; +9;48;32;;; +9;48;48;;; +9;112;80;;; +9;128;16;;; +9;128;32;;; +9;128;64;;; +9;128;80;;; +9;128;96;;; +287;176;0;9 +164;16;36;tarin_state;5;personNew;.tarin.tarin.sleep; +164;16;36;tarin_state;2;personNew;.tarin.tarin.sleep; +164;20;28;tarin_state;2;tarinZZZ;; +164;20;28;tarin_state;5;tarinZZZ;; +164;72;40;maria_state;;maria;; +164;72;120;tarin;0;pushDialog;npc02_leave; +164;112;64;tarin_state;;personNew;.tarin.tarin.; +164;112;64;tarin_state;3;personNew;.tarin.tarin.; +164;112;76;tarin_state;3;banana;; +164;114;75;maria_state;2;personNew;.marin_letter.marin_letter.idle.0$4$14$14; +232;16;95;;heart;;;; +232;31;95;;heart;;;; +173;0;144 +205;112;8;tarin_chest;;;1 diff --git a/bin/Data/Maps/house1.map.data b/bin/Data/Maps/house1.map.data new file mode 100644 index 0000000..c90cdd4 --- /dev/null +++ b/bin/Data/Maps/house1.map.data @@ -0,0 +1,10 @@ +10 +8 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/house10.map b/bin/Data/Maps/house10.map new file mode 100644 index 0000000..3bb5534 --- /dev/null +++ b/bin/Data/Maps/house10.map @@ -0,0 +1,669 @@ +3 +0 +0 +house.png +17 +8 +3 +19,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,21, +45,57,,,,,,,56,51,51,51,61,61,61,61,46, +45,57,,,,,,,56,51,51,51,29,29,29,29,46, +45,52,58,58,51,51,58,58,54,51,51,51,51,51,51,51,46, +45,51,51,51,51,51,51,51,51,51,51,51,51,97,97,51,46, +45,51,51,51,51,51,97,91,97,51,51,51,97,90,89,97,46, +45,51,51,51,51,51,51,51,51,51,51,51,51,97,97,51,46, +20,48,48,48,39,38,48,48,48,48,48,48,48,48,48,48,22, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +113 +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;0;64;;; +0;0;80;;; +0;0;96;;; +0;16;0;;; +0;16;112;;; +0;32;0;;; +0;32;112;;; +0;48;0;;; +0;48;112;;; +0;64;0;;; +0;72;128;;; +0;80;0;;; +0;96;0;;; +0;96;112;;; +0;112;0;;; +0;112;112;;; +0;128;0;;; +0;128;112;;; +0;144;0;;; +0;144;112;;; +0;160;0;;; +0;160;112;;; +0;176;0;;; +0;176;112;;; +0;192;0;;; +0;192;112;;; +0;208;0;;; +0;208;112;;; +0;224;0;;; +0;224;112;;; +0;240;0;;; +0;240;112;;; +0;256;16;;; +0;256;32;;; +0;256;48;;; +0;256;64;;; +0;256;80;;; +0;256;96;;; +14;128;48;;; +3;64;112;;; +4;80;112;;; +15;16;48;;; +174;288;0;rabbit_2_script +153;72;120;;;h10;overworld.map;h10;1;; +299;72;112;;;;;; +284;-32;0;;220;180; +311;48;0;;;;; +311;96;0;;;;; +11;32;48;;; +11;48;48;;; +11;96;48;;; +11;112;48;;; +9;96;80;;; +9;112;80;;; +9;128;80;;; +9;192;16;;; +9;192;32;;; +9;192;80;;; +9;208;16;;; +9;208;32;;; +9;208;64;;; +9;208;80;;; +9;208;96;;; +9;224;16;;; +9;224;32;;; +9;224;64;;; +9;224;80;;; +9;224;96;;; +9;240;16;;; +9;240;32;;; +9;240;80;;; +12;128;16;;; +12;128;32;;; +13;16;16;;; +13;16;32;;; +287;-32;32;9 +164;240;48;hide_rabbit_2;;personNew;.animal_rabbit.rabbit_2..; +232;16;64;;;;;; +232;16;80;;;;;; +232;16;96;;;;;; +232;32;64;;;;;; +232;32;80;;;;;; +232;32;96;;;;;; +232;48;64;;;;;; +232;48;80;;;;;; +232;48;96;;;;;; +157;32;16; +157;32;32; +157;48;16; +157;48;32; +157;64;16; +157;64;32; +157;80;16; +157;80;32; +157;96;16; +157;96;32; +157;112;16; +157;112;32; +108;32;16;;;;;; +108;32;32;;;;;; +108;48;16;;;;;; +108;48;32;;;;;; +108;64;16;;;;;; +108;64;32;;;;;; +108;80;16;;;;;; +108;80;32;;;;;; +108;96;16;;;;;; +108;96;32;;;;;; +108;112;16;;;;;; +108;112;32;;;;;; diff --git a/bin/Data/Maps/house10.map.data b/bin/Data/Maps/house10.map.data new file mode 100644 index 0000000..e9ebd26 --- /dev/null +++ b/bin/Data/Maps/house10.map.data @@ -0,0 +1,10 @@ +17 +8 +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/house11.map b/bin/Data/Maps/house11.map new file mode 100644 index 0000000..ab9d552 --- /dev/null +++ b/bin/Data/Maps/house11.map @@ -0,0 +1,609 @@ +3 +0 +0 +house.png +10 +8 +3 +13,36,36,36,100,100,100,36,36,11, +37,51,51,51,81,81,81,97,97,34, +37,51,51,51,51,51,51,51,49,34, +37,51,51,51,51,51,51,51,97,34, +37,1,1,1,51,51,51,90,89,34, +37,61,91,1,51,51,51,51,51,34, +37,29,1,1,51,51,49,51,51,34, +12,35,35,35,39,38,35,35,35,14, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +53 +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;0;64;;; +0;0;80;;; +0;0;96;;; +0;16;0;;; +0;16;112;;; +0;32;0;;; +0;32;112;;; +0;48;0;;; +0;48;112;;; +0;72;128;;; +0;96;112;;; +0;112;0;;; +0;112;112;;; +0;128;0;;; +0;128;112;;; +0;144;16;;; +0;144;32;;; +0;144;48;;; +0;144;64;;; +0;144;80;;; +0;144;96;;; +3;64;112;;; +4;80;112;;; +2;64;16;;; +2;80;16;;; +2;96;16;;; +153;72;120;;;h11;overworld.map;h11;1;; +299;72;112;;;;;; +284;-32;0;;220;180; +380;32;28 +9;16;80;;; +9;16;96;;; +9;32;80;;; +9;96;96;;; +9;112;64;;; +9;113;15;;; +9;128;16;;; +9;128;32;;; +9;128;48;;; +9;128;64;;; +287;-32;24;9 +379;80;56 +75;96;55;;;;;; +232;112;32;;;;;; +232;112;96;;;;;; +232;128;80;;;;;; +232;128;96;;;;;; +205;64;8;npc_house_chest;;;1 +205;80;8;npc_house_chest;;;1 +205;96;8;npc_house_chest;;;1 diff --git a/bin/Data/Maps/house11.map.data b/bin/Data/Maps/house11.map.data new file mode 100644 index 0000000..c90cdd4 --- /dev/null +++ b/bin/Data/Maps/house11.map.data @@ -0,0 +1,10 @@ +10 +8 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/house12.map b/bin/Data/Maps/house12.map new file mode 100644 index 0000000..bf3c783 --- /dev/null +++ b/bin/Data/Maps/house12.map @@ -0,0 +1,623 @@ +3 +0 +0 +house.png +10 +8 +3 +19,47,47,47,47,47,47,47,47,21, +45,,,,56,51,51,0,61,46, +45,,,,56,51,51,0,29,46, +45,58,51,58,54,51,51,0,0,46, +45,51,51,51,51,51,51,51,51,46, +45,51,51,51,51,51,77,78,91,46, +45,51,51,51,51,51,51,51,51,46, +20,48,48,48,39,38,48,48,48,22, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +67 +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;0;64;;; +0;0;80;;; +0;0;96;;; +0;16;0;;; +0;16;112;;; +0;32;0;;; +0;32;112;;; +0;48;0;;; +0;48;112;;; +0;64;0;;; +0;72;128;;; +0;80;0;;; +0;96;0;;; +0;96;112;;; +0;112;0;;; +0;112;112;;; +0;128;0;;; +0;128;112;;; +0;144;16;;; +0;144;32;;; +0;144;48;;; +0;144;64;;; +0;144;80;;; +0;144;96;;; +14;64;48;;; +3;64;112;;; +4;80;112;;; +153;72;120;;;h12;overworld.map;h12;1;; +299;72;112;;;;;; +284;-24;0;;220;180; +311;32;0;;;;; +311;112;0;;;;; +388;96;32; +11;16;48;;; +11;48;48;;; +9;96;80;;; +9;112;80;;; +9;128;16;;; +9;128;32;;; +9;128;80;;; +12;64;16;;; +12;64;32;;; +287;-24;24;54 +164;128;72;flower_traded;;vase_empty;; +164;128;72;flower_traded;1;vase_flower;; +358;104;66;;npc_letter_girl;npc_letter_girl;idle;0.12.14.24 +232;16;64;;;;;; +232;16;80;;;;;; +232;16;96;;;;;; +232;32;64;;;;;; +232;32;80;;;;;; +232;32;96;;;;;; +157;16;16; +157;16;32; +157;32;16; +157;32;32; +157;48;16; +157;48;32; +108;16;16;;;;;; +108;16;32;;;;;; +108;32;16;;;;;; +108;32;32;;;;;; +108;48;16;;;;;; +108;48;32;;;;;; diff --git a/bin/Data/Maps/house12.map.data b/bin/Data/Maps/house12.map.data new file mode 100644 index 0000000..c90cdd4 --- /dev/null +++ b/bin/Data/Maps/house12.map.data @@ -0,0 +1,10 @@ +10 +8 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/house13.map b/bin/Data/Maps/house13.map new file mode 100644 index 0000000..1b4da53 --- /dev/null +++ b/bin/Data/Maps/house13.map @@ -0,0 +1,625 @@ +3 +0 +0 +house.png +10 +8 +3 +25,43,43,43,43,43,43,43,43,23, +42,0,0,51,51,57,,,,41, +42,61,0,51,51,57,,,,41, +42,29,0,51,51,52,58,51,58,41, +42,0,0,51,51,51,51,51,51,41, +42,97,91,97,51,51,51,51,51,41, +42,51,51,51,51,51,51,51,51,41, +24,44,44,44,39,38,44,44,44,26, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +69 +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;0;64;;; +0;0;80;;; +0;0;96;;; +0;16;0;;; +0;16;112;;; +0;32;0;;; +0;32;112;;; +0;48;0;;; +0;48;112;;; +0;64;0;;; +0;72;128;;; +0;80;0;;; +0;96;0;;; +0;96;112;;; +0;112;0;;; +0;112;112;;; +0;128;0;;; +0;128;112;;; +0;144;16;;; +0;144;32;;; +0;144;48;;; +0;144;64;;; +0;144;80;;; +0;144;96;;; +3;64;112;;; +4;80;112;;; +15;80;48;;; +153;72;120;;;h13;overworld.map;h13;1;; +299;72;112;;;;;; +284;-24;0;;220;180; +167;-24;48;npc_spawn_zora; +311;32;0;;;;; +311;112;0;;;;; +10;16;79;;; +10;47;79;;; +11;16;81;;; +11;47;81;;; +11;96;48;;; +11;128;48;;; +9;16;32;;; +9;16;48;;; +9;32;80;;; +13;80;16;;; +13;80;32;;; +287;-24;24;9 +358;112;14;npc_spawn_zora;npc_zora;npc_zora;idle; +377;72;104;spawnMouseZora;mouseSeqZora +232;112;64;;;;;; +232;112;80;;;;;; +232;112;96;;;;;; +232;128;64;;;;;; +232;128;80;;;;;; +232;128;96;;;;;; +175;96;18;48;;npc_zora_script +157;96;16; +157;96;32; +157;112;16; +157;112;32; +157;128;16; +157;128;32; +108;96;16;;;;;; +108;96;32;;;;;; +108;112;16;;;;;; +108;112;32;;;;;; +108;128;16;;;;;; +108;128;32;;;;;; diff --git a/bin/Data/Maps/house13.map.data b/bin/Data/Maps/house13.map.data new file mode 100644 index 0000000..c90cdd4 --- /dev/null +++ b/bin/Data/Maps/house13.map.data @@ -0,0 +1,10 @@ +10 +8 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/house14.map b/bin/Data/Maps/house14.map new file mode 100644 index 0000000..d9e5c6a --- /dev/null +++ b/bin/Data/Maps/house14.map @@ -0,0 +1,614 @@ +3 +0 +0 +house.png +10 +8 +3 +19,47,47,47,47,100,100,47,47,21, +45,51,51,51,51,81,81,61,61,46, +45,51,51,51,51,51,51,29,29,46, +45,97,97,51,51,68,67,51,51,46, +45,90,89,51,51,86,85,90,89,46, +45,97,97,51,51,97,97,97,97,46, +45,51,51,53,53,53,53,51,51,46, +20,48,48,48,39,38,48,48,48,22, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +524 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +waterfallSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +57 +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;0;64;;; +0;0;80;;; +0;0;96;;; +0;16;0;;; +0;16;112;;; +0;32;0;;; +0;32;112;;; +0;48;0;;; +0;48;112;;; +0;64;0;;; +0;96;112;;; +0;112;0;;; +0;112;112;;; +0;128;0;;; +0;128;112;;; +0;144;16;;; +0;144;32;;; +0;144;48;;; +0;144;64;;; +0;144;80;;; +0;144;96;;; +3;64;112;;; +4;80;112;;; +2;80;16;;; +2;96;16;;; +153;72;120;;;h14;overworld.map;h14;1;; +300;72;112;;;;;; +284;-24;0;;220;180; +9;15;49;;; +9;16;64;;; +9;16;79;;; +9;31;49;;; +9;31;79;;; +9;32;64;;; +9;80;64;;; +9;81;79;;; +9;96;64;;; +9;97;79;;; +9;112;16;;; +9;112;32;;; +9;112;64;;; +9;112;79;;; +9;128;16;;; +9;128;32;;; +9;128;64;;; +9;128;79;;; +287;-24;24;9 +164;108;48;pineapple_gone;;item;..trade6.; +359;88;41;;npc_chef;npc_chef;idle;0.0.28.16 +232;16;16;;;;;; +232;32;16;;;;;; +232;48;16;;;;;; +205;80;8;npc_house_chest;;;1 +205;96;8;npc_house_chest;;;1 diff --git a/bin/Data/Maps/house14.map.data b/bin/Data/Maps/house14.map.data new file mode 100644 index 0000000..c90cdd4 --- /dev/null +++ b/bin/Data/Maps/house14.map.data @@ -0,0 +1,10 @@ +10 +8 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/house2.map b/bin/Data/Maps/house2.map new file mode 100644 index 0000000..a306caa --- /dev/null +++ b/bin/Data/Maps/house2.map @@ -0,0 +1,613 @@ +3 +0 +0 +house.png +10 +8 +3 +19,47,100,100,100,100,100,100,47,21, +45,51,95,81,81,81,81,81,51,46, +45,90,82,51,51,51,61,61,91,46, +45,51,51,51,51,51,29,29,51,46, +45,97,51,51,51,51,51,51,51,46, +45,91,51,69,69,69,69,51,51,46, +45,97,51,69,69,69,69,51,51,46, +20,48,48,48,39,38,48,48,48,22, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +57 +382;-24;72; +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;0;64;;; +0;0;80;;; +0;0;96;;; +0;16;0;;; +0;16;112;;; +0;32;112;;; +0;48;112;;; +0;72;128;;; +0;96;112;;; +0;112;112;;; +0;128;0;;; +0;128;112;;; +0;144;16;;; +0;144;32;;; +0;144;48;;; +0;144;64;;; +0;144;80;;; +0;144;96;;; +3;64;112;;; +4;80;112;;; +2;32;14;;; +2;48;14;;; +2;64;14;;; +2;80;14;;; +2;96;14;;; +2;112;14;;; +174;168;0;houseMusic +153;72;120;;;h2;overworld.map;h2;1;; +299;72;112;;;;;; +285;-24;24;;;; +9;16;32;;; +9;16;64;;; +9;16;80;;; +9;16;96;;; +9;32;32;;; +9;96;32;;; +9;96;48;;; +9;112;32;;; +9;112;48;;; +9;128;32;;; +287;-24;0;50 +357;64;40;npc04;;; +232;112;80;;;;;; +232;112;96;;;;;; +232;128;80;;;;;; +232;128;96;;;;;; +205;32;8;npc_house_chest;;;1 +205;32;32;ulrira_telephone;;; +205;48;8;npc_house_chest;;;1 +205;64;8;npc_house_chest;;;1 +205;80;8;npc_house_chest;;;1 +205;96;8;npc_house_chest;;;1 +205;112;8;npc_house_chest;;;1 diff --git a/bin/Data/Maps/house2.map.data b/bin/Data/Maps/house2.map.data new file mode 100644 index 0000000..c90cdd4 --- /dev/null +++ b/bin/Data/Maps/house2.map.data @@ -0,0 +1,10 @@ +10 +8 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/house3m.map b/bin/Data/Maps/house3m.map new file mode 100644 index 0000000..7a7b4c3 --- /dev/null +++ b/bin/Data/Maps/house3m.map @@ -0,0 +1,615 @@ +3 +0 +0 +house.png +10 +8 +3 +13,36,36,36,36,36,100,36,36,11, +37,61,51,51,51,51,81,51,51,34, +37,29,51,51,97,90,89,51,51,34, +37,51,51,51,51,97,97,51,51,34, +37,51,51,51,51,51,51,51,51,34, +37,51,51,51,51,51,51,51,51,34, +37,97,91,97,51,51,51,51,51,34, +12,35,35,35,39,38,35,35,35,14, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +59 +384;32;32;bowWow2 +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;0;64;;; +0;0;80;;; +0;0;96;;; +0;16;0;;; +0;16;112;;; +0;32;0;;; +0;32;112;;; +0;48;0;;; +0;48;112;;; +0;64;0;;; +0;72;128;;; +0;80;0;;; +0;96;0;;; +0;96;112;;; +0;112;0;;; +0;112;112;;; +0;128;0;;; +0;128;112;;; +0;144;16;;; +0;144;32;;; +0;144;48;;; +0;144;64;;; +0;144;80;;; +0;144;96;;; +3;64;112;;; +4;80;112;;; +2;96;13;;; +174;168;24;houseMusic +174;168;48;bowWowHouse +153;72;120;;;h3m;overworld.map;h3m;1;; +299;72;112;;;;;; +285;-24;0;;;; +9;16;16;;; +9;16;32;;; +9;16;96;;; +9;32;96;;; +9;48;96;;; +9;64;32;;; +9;80;32;;; +9;80;48;;; +9;96;32;;; +9;96;48;;; +287;168;0;9 +358;64;48;;npc09;npc09;; +232;112;16;;;;;; +232;112;32;;;;;; +232;112;48;;;;;; +232;112;64;;;;;; +232;128;16;;;;;; +232;128;32;;;;;; +232;128;48;;;;;; +232;128;64;;;;;; +232;128;80;;;;;; +232;128;96;;;;;; +205;96;6;npc_house_chest;;;1 diff --git a/bin/Data/Maps/house3m.map.data b/bin/Data/Maps/house3m.map.data new file mode 100644 index 0000000..c90cdd4 --- /dev/null +++ b/bin/Data/Maps/house3m.map.data @@ -0,0 +1,10 @@ +10 +8 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/house3n.map b/bin/Data/Maps/house3n.map new file mode 100644 index 0000000..6f80a02 --- /dev/null +++ b/bin/Data/Maps/house3n.map @@ -0,0 +1,570 @@ +3 +0 +0 +house.png +6 +5 +3 +13,36,36,36,36,11, +37,93,93,93,93,34, +37,93,75,93,93,34, +37,93,93,93,93,34, +12,35,28,27,35,14, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +23 +384;32;16;bowWow3 +382;-32;64; +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;16;0;;; +0;16;64;;; +0;32;0;;; +0;40;80;;; +0;48;0;;; +0;64;0;;; +0;64;64;;; +0;80;16;;; +0;80;32;;; +0;80;48;;; +3;32;64;;; +4;48;64;;; +174;144;0;houseMusic +153;40;72;;;h3n;overworld.map;h3n;1;; +299;40;64;;;;;; +22;40;64;;;; +285;-32;0;;;; +287;112;0;9 diff --git a/bin/Data/Maps/house3n.map.data b/bin/Data/Maps/house3n.map.data new file mode 100644 index 0000000..a21f33e --- /dev/null +++ b/bin/Data/Maps/house3n.map.data @@ -0,0 +1,7 @@ +6 +5 +;;;;;; +;2;2;2;2;; +;2;;2;2;; +;2;2;2;shell:shell_3:2;; +;;;;;; diff --git a/bin/Data/Maps/house4.map b/bin/Data/Maps/house4.map new file mode 100644 index 0000000..22195ee --- /dev/null +++ b/bin/Data/Maps/house4.map @@ -0,0 +1,729 @@ +3 +0 +0 +house.png +20 +8 +3 +19,47,47,47,47,47,47,47,47,47,47,47,47,100,47,100,100,100,100,21, +45,19,47,47,47,47,47,21,0,0,0,51,51,81,51,81,81,81,81,46, +45,45,51,51,51,51,51,46,0,0,0,51,51,61,51,61,61,61,61,46, +45,45,51,51,51,51,51,46,0,0,0,51,51,29,51,29,29,29,29,46, +45,20,48,70,48,48,48,22,0,0,0,51,90,89,51,91,91,91,91,46, +45,0,0,0,0,0,0,0,0,0,0,51,97,51,51,97,97,97,97,46, +45,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,46, +20,48,48,48,39,38,48,48,48,48,48,48,48,48,39,38,48,48,48,22, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +173 +382;-24;48; +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;0;64;;; +0;0;80;;; +0;0;96;;; +0;16;0;;; +0;16;112;;; +0;32;0;;; +0;32;112;;; +0;48;0;;; +0;48;112;;; +0;64;0;;; +0;72;128;;; +0;80;0;;; +0;96;0;;; +0;96;112;;; +0;112;0;;; +0;112;112;;; +0;128;0;;; +0;128;112;;; +0;144;0;;; +0;144;112;;; +0;160;0;;; +0;160;112;;; +0;176;0;;; +0;176;112;;; +0;192;0;;; +0;192;112;;; +0;208;112;;; +0;224;0;;; +0;232;128;;; +0;256;112;;; +0;272;112;;; +0;288;112;;; +0;304;16;;; +0;304;32;;; +0;304;48;;; +0;304;64;;; +0;304;80;;; +0;304;96;;; +3;64;112;;; +3;224;112;;; +4;80;112;;; +4;240;112;;; +2;208;13;;; +2;240;13;;; +2;256;13;;; +2;272;13;;; +2;288;13;;; +174;0;-24;houseMusic +153;72;120;;;h4-1;overworld.map;h4-1;1;; +153;232;120;;;h4-2;overworld.map;h4-2;1;; +299;72;112;;;;;; +299;232;112;;;;;; +285;-24;0;;;; +162;32;72;;-18;;8;;;;; +162;64;72;;-18;48;8;;;;; +162;120;32;-18;;8;32;;;;; +311;48;16;;;;; +9;192;64;;; +9;192;80;;; +9;208;32;;; +9;208;48;;; +9;208;64;;; +9;240;32;;; +9;240;48;;; +9;240;64;;; +9;240;80;;; +9;256;32;;; +9;256;48;;; +9;256;64;;; +9;256;80;;; +9;272;32;;; +9;272;48;;; +9;272;64;;; +9;272;80;;; +9;288;32;;; +9;288;48;;; +9;288;64;;; +9;288;80;;; +25;16;16;;;; +25;16;32;;;; +25;16;48;;;; +25;16;64;;;; +25;32;16;;;; +25;32;64;;;; +25;48;16;;;; +25;64;16;;;; +25;64;64;;;; +25;80;16;;;; +25;80;64;;;; +25;96;16;;;; +25;96;64;;;; +25;112;16;;;; +25;112;32;;;; +25;112;48;;;; +25;112;64;;;; +287;-24;-24;9 +164;224;32;npc_lost_boy_state;;personNew;.npc_lost_boy.npc08..; +164;224;32;npc_lost_boy_state;2;personNew;.npc_lost_boy.npc08.wave.; +357;192;48;npc07;0.0.16.10;;stand +232;16;96;;;;;; +232;32;32;;;;;; +232;32;96;;;;;; +232;48;32;;ruby;;;; +232;64;32;;;;;; +232;80;32;;;;;; +205;208;4;npc_house_chest;;;1 +205;240;4;npc_house_chest;;;1 +205;256;4;npc_house_chest;;;1 +205;272;4;npc_house_chest;;;1 +205;288;4;npc_house_chest;;;1 +160;48;64; +246;16;80; +246;16;96; +246;32;80; +246;32;96; +246;48;64; +246;48;80; +246;48;96; +246;64;80; +246;64;96; +246;80;80; +246;80;96; +246;96;80; +246;96;96; +246;112;80; +246;112;96; +246;128;16; +246;128;32; +246;128;48; +246;128;64; +246;128;80; +246;128;96; +246;144;16; +246;144;32; +246;144;48; +246;144;64; +246;144;80; +246;144;96; +246;160;16; +246;160;32; +246;160;48; +246;160;64; +246;160;80; +246;160;96; +246;176;16; +246;176;32; +246;176;48; +246;176;64; +246;176;80; +246;176;96; +246;192;16; +246;192;32; +246;192;48; +246;192;96; +246;208;16; +246;208;80; +246;208;96; +246;224;16; +246;224;64; +246;224;80; +246;224;96; +246;240;16; +246;240;96; +246;256;16; +246;256;96; +246;272;16; +246;272;96; +246;288;16; +246;288;96; diff --git a/bin/Data/Maps/house4.map.data b/bin/Data/Maps/house4.map.data new file mode 100644 index 0000000..ed25ef3 --- /dev/null +++ b/bin/Data/Maps/house4.map.data @@ -0,0 +1,10 @@ +20 +8 +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/house6.map b/bin/Data/Maps/house6.map new file mode 100644 index 0000000..20383ca --- /dev/null +++ b/bin/Data/Maps/house6.map @@ -0,0 +1,632 @@ +3 +0 +0 +house.png +10 +8 +3 +19,47,47,47,47,100,100,47,47,21, +45,,61,,56,81,81,51,51,46, +45,,29,,56,51,51,51,51,46, +45,,,,56,51,51,51,51,46, +45,58,51,58,54,51,51,51,51,46, +45,49,49,49,51,51,49,49,49,46, +45,49,49,49,51,51,49,49,49,46, +20,48,48,48,39,38,48,48,48,22, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +76 +366;120;56 +63;112;92;;;;;; +63;128;76;;;;;; +63;128;92;;;;;; +382;-32;96; +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;0;64;;; +0;0;80;;; +0;0;96;;; +0;16;0;;; +0;16;112;;; +0;32;0;;; +0;32;112;;; +0;48;0;;; +0;48;112;;; +0;64;0;;; +0;96;112;;; +0;112;0;;; +0;112;112;;; +0;128;0;;; +0;128;112;;; +0;144;16;;; +0;144;32;;; +0;144;48;;; +0;144;64;;; +0;144;80;;; +0;144;96;;; +14;64;62;;; +3;64;112;;; +4;80;112;;; +2;80;16;;; +2;96;16;;; +153;72;120;;;h6;overworld.map;h6;1;; +299;72;112;;;;;; +285;-32;0;;;; +11;16;62;;; +11;48;62;;; +9;16;80;;; +9;16;96;;; +9;32;16;;; +9;32;32;;; +9;32;80;;; +9;32;96;;; +9;48;80;;; +9;48;96;;; +9;96;80;;; +9;96;96;;; +9;112;80;;; +9;112;96;;; +9;128;80;;; +9;128;96;;; +12;64;16;;; +12;64;32;;; +12;64;48;;; +287;-32;64;9 +232;112;16;;;;;; +232;128;16;;;;;; +232;128;32;;;;;; +205;80;8;npc_house_chest;;;1 +205;96;8;npc_house_chest;;;1 +157;16;16; +157;16;32; +157;16;48; +157;32;48; +157;48;16; +157;48;32; +157;48;48; +108;16;16;;;;;; +108;16;32;;;;;; +108;16;48;;;;;; +108;32;48;;;;;; +108;48;16;;;;;; +108;48;32;;;;;; +108;48;48;;;;;; diff --git a/bin/Data/Maps/house6.map.data b/bin/Data/Maps/house6.map.data new file mode 100644 index 0000000..c90cdd4 --- /dev/null +++ b/bin/Data/Maps/house6.map.data @@ -0,0 +1,10 @@ +10 +8 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/house7.map b/bin/Data/Maps/house7.map new file mode 100644 index 0000000..9999614 --- /dev/null +++ b/bin/Data/Maps/house7.map @@ -0,0 +1,631 @@ +3 +0 +0 +house.png +10 +8 +3 +63,58,100,62,19,47,47,47,47,21, +56,61,81,57,45,51,51,72,51,46, +56,29,51,60,45,51,51,91,97,46, +19,47,70,47,74,51,51,97,51,46, +45,51,51,51,51,51,51,51,51,46, +45,51,51,51,51,51,51,91,51,46, +45,51,51,51,51,51,51,51,51,46, +20,48,48,48,39,38,48,48,48,22, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +75 +382;-32;112; +0;-16;0;;; +0;-16;16;;; +0;-16;32;;; +0;-16;48;;; +0;0;-16;;; +0;0;64;;; +0;0;80;;; +0;0;96;;; +0;16;-16;;; +0;16;112;;; +0;32;0;;; +0;32;112;;; +0;48;-16;;; +0;48;112;;; +0;80;0;;; +0;96;0;;; +0;96;112;;; +0;112;0;;; +0;112;112;;; +0;128;0;;; +0;128;112;;; +0;144;16;;; +0;144;32;;; +0;144;48;;; +0;144;64;;; +0;144;80;;; +0;144;96;;; +19;48;0;;; +21;48;32;;; +3;64;112;;; +4;80;112;;; +2;32;16;;; +18;0;0;;; +174;168;48;npc_frog_house +153;72;120;;;h7;overworld.map;h7;1;; +153;112;16;;;ce3;cave3.map;ce3;;1; +22;72;112;;;; +391;32;96 +391;48;64 +391;96;80 +391;128;64 +285;168;0;;;; +297;72;112;160;;;;200; +11;16;0;;; +9;16;16;;; +9;16;32;;; +9;112;32;;; +9;112;48;;; +9;112;80;;; +9;128;32;;; +12;0;16;;; +12;0;32;;; +13;48;16;;; +25;16;48;;;; +25;48;48;;;; +25;64;0;;;; +25;64;16;;;; +25;64;32;;;; +25;64;48;;;; +287;168;24;63 +164;112;16;frogHouseMovedStone;0;moveStoneFrogHouse;4.frogHouseMovedStone.....True; +164;128;16;frogHouseMovedStone;1;moveStoneFrogHouse;; +358;96;16;;npc_frog_boy;npc_frog_boy;; +232;16;64;;;;;; +232;16;80;;;;;; +232;16;96;;;;;; +205;32;8;npc_house_chest;;;1 +160;32;48; +246;32;16; +246;32;32; +246;32;48; +246;48;0; +246;48;16; +246;48;32; diff --git a/bin/Data/Maps/house7.map.data b/bin/Data/Maps/house7.map.data new file mode 100644 index 0000000..c90cdd4 --- /dev/null +++ b/bin/Data/Maps/house7.map.data @@ -0,0 +1,10 @@ +10 +8 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/house8.map b/bin/Data/Maps/house8.map new file mode 100644 index 0000000..9b0af2e --- /dev/null +++ b/bin/Data/Maps/house8.map @@ -0,0 +1,610 @@ +3 +0 +0 +house.png +10 +8 +3 +25,43,43,100,43,43,43,43,43,23, +42,51,51,81,51,51,51,51,51,41, +42,51,51,61,51,51,51,51,51,41, +42,51,51,29,51,51,51,51,51,41, +42,51,51,51,80,79,51,51,51,41, +42,51,51,51,51,51,51,51,51,41, +42,51,51,51,0,0,51,51,51,41, +24,44,44,44,39,38,44,44,44,26, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +54 +382;-32;64; +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;0;64;;; +0;0;80;;; +0;0;96;;; +0;16;0;;; +0;16;112;;; +0;32;0;;; +0;32;112;;; +0;48;112;;; +0;64;0;;; +0;72;128;;; +0;80;0;;; +0;96;0;;; +0;96;112;;; +0;112;0;;; +0;112;112;;; +0;128;0;;; +0;128;112;;; +0;144;16;;; +0;144;32;;; +0;144;48;;; +0;144;64;;; +0;144;80;;; +0;144;96;;; +3;64;112;;; +4;80;112;;; +2;48;14;;; +153;72;120;;;h8;overworld.map;h8;1;; +284;-32;0;;;;175 +22;72;112;;;; +387;96;32; +359;72;50;npc_letter_boy +297;72;112;160;;;;200; +9;48;34;;; +9;48;48;;; +9;64;64;;; +9;80;64;;; +287;-32;32;49 +232;16;16;;;;;; +232;16;32;;;;;; +232;16;48;;;;;; +232;16;64;;;;;; +232;16;80;;;;;; +232;16;96;;;;;; +232;32;16;;;;;; +232;32;32;;;;;; +232;32;48;;;;;; +232;32;64;;;;;; +232;32;80;;;;;; +232;32;96;;;;;; +205;48;6;npc_house_chest;;;1 diff --git a/bin/Data/Maps/house8.map.data b/bin/Data/Maps/house8.map.data new file mode 100644 index 0000000..c90cdd4 --- /dev/null +++ b/bin/Data/Maps/house8.map.data @@ -0,0 +1,10 @@ +10 +8 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/house9.map b/bin/Data/Maps/house9.map new file mode 100644 index 0000000..7a2160d --- /dev/null +++ b/bin/Data/Maps/house9.map @@ -0,0 +1,607 @@ +3 +0 +0 +house.png +10 +8 +3 +13,36,36,36,36,36,36,36,100,11, +37,97,51,51,51,51,51,61,81,34, +37,91,51,51,97,51,51,29,51,34, +37,97,51,51,91,51,51,51,51,34, +37,51,51,51,51,51,51,51,51,34, +37,51,51,51,51,51,51,51,51,34, +37,51,51,51,51,51,51,51,51,34, +12,35,35,35,39,38,35,35,35,14, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +51 +382;-32;32; +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;0;64;;; +0;0;80;;; +0;0;96;;; +0;16;0;;; +0;16;112;;; +0;32;0;;; +0;32;112;;; +0;48;0;;; +0;48;112;;; +0;64;0;;; +0;80;0;;; +0;96;0;;; +0;96;112;;; +0;112;0;;; +0;112;112;;; +0;128;112;;; +0;144;16;;; +0;144;32;;; +0;144;48;;; +0;144;64;;; +0;144;80;;; +0;144;96;;; +3;64;112;;; +4;80;112;;; +2;128;16;;; +153;72;120;;;h9;overworld.map;h9;1;; +22;72;112;;;; +285;-32;0;;;; +302;16;96;;;;; +302;128;96;;;;; +9;16;16;;; +9;16;32;;; +9;16;48;;; +9;64;48;;; +9;112;16;;; +9;112;32;;; +390;32;80 +390;96;48 +287;-64;0;6 +232;80;32;;;;;; +232;80;48;;;;;; +232;80;64;;;;;; +232;96;64;;;;;; +232;112;64;;;;;; +232;128;64;;;;;; +205;128;8;npc_house_chest;;;1 +369;64;27 diff --git a/bin/Data/Maps/house9.map.data b/bin/Data/Maps/house9.map.data new file mode 100644 index 0000000..c90cdd4 --- /dev/null +++ b/bin/Data/Maps/house9.map.data @@ -0,0 +1,10 @@ +10 +8 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/library.map b/bin/Data/Maps/library.map new file mode 100644 index 0000000..5ba5beb --- /dev/null +++ b/bin/Data/Maps/library.map @@ -0,0 +1,615 @@ +3 +0 +0 +house.png +10 +8 +3 +2,98,98,98,98,98,98,98,98,5, +15,76,76,76,76,76,76,76,76,16, +15,91,51,91,51,51,91,51,91,16, +15,51,51,51,51,51,51,51,51,16, +15,51,51,51,51,51,51,51,51,16, +15,91,51,91,51,51,91,51,91,16, +15,51,51,51,51,51,51,51,51,16, +3,17,17,17,39,38,17,17,17,4, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +59 +241;16;27;;book1;2 +241;16;75;;book5; +241;48;27;;book2;3 +241;48;75;;book6;1 +241;72;23;library_book;book9; +241;96;27;;book3; +241;96;75;;book7;2 +241;128;27;;book4;1 +241;128;75;;book8;3 +382;0;176; +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;0;64;;; +0;0;80;;; +0;0;96;;; +0;16;112;;; +0;32;112;;; +0;48;112;;; +0;96;112;;; +0;112;112;;; +0;128;112;;; +0;144;16;;; +0;144;32;;; +0;144;48;;; +0;144;64;;; +0;144;80;;; +0;144;96;;; +3;64;112;;; +4;80;112;;; +2;16;14;;; +2;32;14;;; +2;48;14;;; +2;64;14;;; +2;80;14;;; +2;96;14;;; +2;112;14;;; +2;129;14;;; +174;208;0;houseMusic +153;72;120;;;l1;overworld.map;l1;1;; +299;72;112;;;;;; +285;0;144;;;; +9;16;32;;; +9;16;80;;; +9;48;32;;; +9;48;80;;; +9;96;32;;; +9;96;80;;; +9;128;32;;; +9;128;80;;; +287;176;0;9 +205;16;6;bookcase;;; +205;32;6;bookcase;;; +205;48;6;bookcase;;; +205;64;6;bookcase;;; +205;80;6;bookcase;;; +205;96;6;bookcase;;; +205;112;6;bookcase;;; +205;128;6;bookcase;;; diff --git a/bin/Data/Maps/library.map.data b/bin/Data/Maps/library.map.data new file mode 100644 index 0000000..c90cdd4 --- /dev/null +++ b/bin/Data/Maps/library.map.data @@ -0,0 +1,10 @@ +10 +8 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/overworld.map b/bin/Data/Maps/overworld.map new file mode 100644 index 0000000..18b1acc --- /dev/null +++ b/bin/Data/Maps/overworld.map @@ -0,0 +1,17432 @@ +3 +1 +0 +tileset0.png +161 +129 +3 +,163,163,163,163,163,163,163,163,163,163,,165,163,,,163,163,163,163,163,163,163,163,163,163,,,165,163,163,183,184,184,185,163,183,184,184,185,163,,,163,163,,,,165,163,163,163,163,163,163,,165,163,163,163,163,163,163,163,163,160,161,162,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,,165,163,163,163,163,163,163,183,184,184,386,386,386,184,184,184,184,184,184,184,185,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,,165,163,163,163,163,310,311,311,311,312,163,163,163,163,163,163,163,163,166,165,163,163, +,,165,163,183,184,184,184,185,163,,167,167,168,167,167,168,165,163,163,163,163,163,183,184,185,,167,167,168,165,463,357,357,178,184,179,357,357,186,163,,,,,,,,167,168,165,163,163,163,,,167,168,165,163,163,166,165,163,183,180,181,182,185,166,165,,165,163,183,184,184,184,184,184,185,163,163,,165,163,163,163,163,,165,163,,,167,168,165,163,163,183,184,179,357,357,175,187,175,357,357,357,357,357,357,357,178,184,185,,165,163,163,163,,165,163,,165,183,184,184,185,183,184,184,184,185,163,,,167,165,166,188,165,310,169,170,171,312,166,165,166,165,163,163,166,188,167,167,165,163, +,237,237,237,463,357,357,357,186,237,237,237,237,237,237,237,237,237,237,237,237,237,237,463,357,186,237,237,237,237,237,463,357,357,357,357,357,357,357,186,193,194,,194,194,194,194,194,194,194,194,193,193,193,193,193,193,193,193,193,193,237,237,237,463,200,201,202,186,237,237,237,237,237,463,357,357,357,357,357,186,199,199,199,237,199,237,237,237,199,199,206,206,206,207,207,207,207,206,463,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,186,207,207,207,207,193,206,206,199,199,199,463,357,357,186,203,204,204,204,205,237,237,237,237,237,237,237,237,310,311,195,311,312,237,237,193,193,193,193,193,193,193,193,193,193, +,,,197,203,421,210,422,205,212,,,,,,,197,213,212,,,,197,203,204,205,212,,,,197,463,357,357,214,204,215,357,357,186,212,,,197,213,213,213,213,213,213,213,213,213,213,213,213,213,213,212,,,,,197,463,220,221,222,186,212,,,,197,179,357,357,357,357,357,186,199,199,199,219,199,219,219,219,199,199,226,226,226,219,219,219,219,226,463,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,186,199,219,199,199,199,226,226,,,197,179,357,357,186,229,223,223,223,224,197,213,213,212,,197,213,213,310,311,225,311,312,213,213,213,213,213,216,216,216,213,213,212,, +,,197,463,217,361,210,223,230,186,,,,,197,213,463,401,186,213,213,213,179,227,361,228,186,,,,463,203,204,204,205,361,203,204,204,205,186,,,463,357,357,357,357,357,357,357,357,357,357,357,357,357,357,186,,,,,463,203,421,210,422,205,186,,,,463,357,357,214,421,336,422,205,,,,,,,,,,,,,,,197,213,213,213,203,204,204,204,204,421,210,422,215,357,214,204,204,204,204,204,204,205,213,212,,,,197,213,213,212,463,357,357,214,205,229,223,223,223,224,463,357,357,186,,463,357,357,357,311,225,311,357,357,357,357,357,357,313,187,314,357,357,186,, +,197,463,463,357,357,357,357,357,186,199,199,199,199,463,357,461,210,300,357,357,357,357,357,357,357,186,213,213,213,179,217,223,223,230,357,217,223,223,230,186,,,463,357,357,357,357,357,357,357,357,357,357,357,357,357,357,186,,,,,463,229,223,210,223,224,186,,,,463,357,357,186,223,223,223,230,213,213,212,,197,213,213,213,213,213,213,213,213,213,179,357,357,357,229,223,223,223,223,223,210,223,203,204,205,223,223,223,223,223,223,230,357,186,206,206,206,463,357,357,186,463,357,357,186,224,229,223,223,223,224,463,357,357,186,,463,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,186,, +,463,463,463,357,357,357,357,357,186,213,213,213,213,463,357,357,357,357,357,357,357,357,357,357,357,186,357,357,357,357,357,357,357,357,357,357,357,357,357,186,199,199,463,357,357,357,357,357,357,357,357,357,357,357,357,357,357,186,,,,197,203,204,421,210,422,204,205,212,,,463,357,357,186,357,357,357,357,357,357,186,,463,357,357,357,357,357,357,357,357,357,357,357,357,357,217,223,223,361,301,357,357,357,217,361,230,357,357,357,357,357,357,357,357,186,226,226,226,463,357,357,186,203,204,204,205,224,229,361,223,223,224,203,204,204,205,,203,215,357,357,357,357,357,357,357,357,357,357,357,357,357,357,214,204,205,, +,463,463,203,204,204,204,204,204,205,357,357,357,357,203,204,204,204,204,204,204,204,204,204,204,204,205,357,357,357,214,204,204,421,336,422,204,421,336,422,205,197,213,203,204,204,204,421,336,422,204,204,204,204,421,210,422,204,205,213,212,,463,229,223,223,210,223,223,230,186,,,203,204,204,205,210,215,357,357,357,357,186,197,203,204,204,204,204,204,421,336,422,215,357,357,357,357,357,357,357,357,463,357,357,357,357,357,357,357,357,357,357,357,357,357,357,186,,,,203,204,210,205,229,302,223,224,224,463,357,357,357,186,229,223,223,224,,229,203,204,204,421,336,422,421,336,422,204,204,204,204,204,204,205,223,224,, +,463,463,217,243,223,361,223,243,230,357,357,357,357,217,223,223,223,223,223,223,223,223,223,223,223,230,357,357,357,186,223,223,223,223,223,361,223,223,223,230,463,357,229,223,223,223,223,223,223,223,223,223,223,223,210,223,223,224,357,186,197,203,204,204,421,210,422,204,204,205,212,197,229,223,223,224,210,463,357,357,357,357,186,463,217,223,361,223,361,223,223,223,223,463,357,357,357,357,357,357,357,357,463,357,357,357,357,357,357,357,357,357,357,357,357,357,357,186,213,213,213,229,223,210,224,229,,223,224,224,463,357,357,357,495,318,443,223,224,,229,229,223,361,223,223,223,361,223,223,223,223,361,223,223,223,224,361,224,, +,463,463,357,263,357,357,357,263,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,186,357,357,357,357,357,357,357,357,357,357,463,357,217,223,223,223,223,223,223,223,223,223,223,223,210,223,223,172,357,186,463,229,223,223,223,210,223,223,223,224,186,463,229,223,223,224,210,463,357,357,357,357,186,463,357,357,357,357,357,357,357,357,357,463,357,357,357,357,357,357,357,357,463,357,214,204,204,204,215,357,357,214,204,215,357,357,357,186,,,,229,223,210,224,229,,223,224,224,203,204,215,357,357,357,186,223,224,,229,229,301,357,272,223,301,357,357,357,357,357,357,357,272,223,224,357,186,, +,463,463,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,186,357,357,357,357,357,357,357,357,357,357,203,215,357,357,357,357,357,357,357,357,357,357,357,357,357,357,214,204,204,205,463,229,223,223,223,210,223,223,223,224,186,463,217,361,223,230,357,203,204,204,204,204,205,463,357,357,357,357,357,357,357,357,357,463,357,357,357,214,204,204,204,204,203,204,205,302,302,302,203,204,204,205,361,203,204,204,204,205,357,,,229,223,210,224,229,,223,224,230,217,361,463,357,357,357,186,223,224,213,217,229,203,210,205,223,203,204,204,204,421,210,422,204,205,223,224,357,186,, +,463,463,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,186,357,357,357,357,357,357,357,357,357,357,217,203,204,421,210,422,204,204,204,204,204,204,204,204,204,204,205,223,361,230,203,204,204,204,421,210,422,204,204,204,205,463,357,357,357,357,357,217,223,223,223,223,463,463,357,357,357,357,357,357,357,357,357,203,204,204,204,205,361,223,223,223,229,223,224,,,,229,223,223,224,223,229,223,223,361,224,357,357,,229,223,210,224,217,,223,230,,,,203,204,204,204,205,223,224,357,357,217,229,210,224,223,229,301,357,357,357,357,272,223,224,361,230,357,186,, +,463,463,357,357,357,357,357,357,357,214,204,204,215,357,357,357,214,204,204,204,204,204,204,204,204,204,204,204,204,205,357,357,357,357,357,357,357,357,357,357,357,217,223,223,210,223,223,223,223,223,223,223,223,223,223,223,230,357,357,357,217,223,223,223,223,210,223,223,223,223,230,463,357,357,357,357,357,357,357,272,223,223,463,461,204,204,204,204,204,204,204,421,210,217,223,223,223,230,,,,,217,223,230,,,,217,223,223,230,357,217,223,223,223,230,357,357,,217,223,210,230,,,,,,,,229,223,223,223,224,361,230,357,357,357,217,210,230,401,217,203,204,204,204,204,205,361,230,357,357,357,186,, +,463,463,357,357,357,357,357,357,357,186,357,357,203,421,336,422,205,223,223,223,223,223,223,223,223,223,223,223,223,230,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,461,204,204,421,210,422,204,204,205,223,223,463,,,,,,,,,,,,,,,,,,,,,,,,,,,,,357,357,357,357,357,357,357,357,,,,,,,,,,,,,,217,223,223,223,230,357,357,357,357,357,357,357,357,357,357,217,223,223,223,223,230,357,357,357,357,357,186,, +,463,461,204,204,204,204,204,204,204,300,357,357,217,223,223,223,230,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,214,204,204,204,204,204,204,204,204,204,204,204,204,215,357,357,357,357,357,357,357,357,357,357,357,357,272,223,223,210,223,223,223,224,223,223,203,204,204,204,204,204,215,,,214,204,204,204,204,204,204,204,204,204,204,204,215,,,,,,,,214,421,336,336,336,422,215,357,357,,214,204,,204,,204,,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,205,, +,203,204,204,204,204,204,215,500,500,500,500,500,357,500,500,214,421,336,422,215,214,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,205,223,223,223,223,223,223,223,223,223,223,223,223,203,204,204,204,204,421,210,422,204,204,204,204,204,205,223,223,210,223,223,223,224,615,615,229,223,223,223,223,223,203,204,204,205,223,223,223,223,223,223,223,223,223,223,223,203,204,204,204,204,204,204,204,205,223,223,223,223,223,203,204,204,204,205,223,,223,,223,,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,224,, +,463,223,223,223,223,223,463,500,500,500,500,500,500,500,500,186,223,223,223,463,186,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,189,190,189,223,224,223,223,223,223,223,223,223,223,223,223,223,223,229,223,223,223,223,223,210,223,223,223,223,223,223,224,223,223,210,223,223,223,230,615,615,217,223,223,223,223,223,229,223,223,224,223,223,223,223,223,223,223,223,223,223,223,229,223,223,223,223,223,223,223,224,223,340,341,342,223,229,223,223,223,224,223,,223,,223,,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,224,443, +,463,223,223,223,223,223,203,204,204,204,204,204,421,210,422,205,223,223,223,463,186,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,189,191,196,191,189,230,359,370,390,411,371,359,359,359,359,359,370,450,217,223,223,223,223,223,210,223,223,223,223,223,223,230,500,372,412,453,615,500,500,500,500,372,373,272,223,223,223,229,223,223,224,223,223,223,223,223,223,223,223,223,223,223,229,343,344,223,343,344,223,223,224,223,360,361,362,223,229,223,223,223,224,223,,223,,223,,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,361,223,223,223,223,223,223,223,223,223,223,223,223,230,186, +,463,372,452,412,452,353,217,223,361,223,223,361,223,210,223,230,500,500,352,463,186,450,371,474,298,325,298,298,298,325,325,298,298,299,299,299,299,325,299,299,245,245,245,245,245,246,500,500,359,615,615,615,615,500,155,204,215,359,370,371,500,352,413,392,373,500,500,615,372,412,413,353,500,500,615,372,413,353,500,309,443,353,500,500,186,,,,217,223,223,230,,,,,,,,,,,,217,223,223,361,223,223,223,223,230,357,357,357,357,400,217,223,223,223,230,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,186, +,203,215,372,413,452,452,412,373,500,500,372,413,373,500,500,500,352,412,452,463,186,431,267,477,298,325,298,298,298,298,299,298,299,299,325,299,299,299,299,325,325,245,245,245,245,478,268,615,615,615,615,615,615,500,500,500,463,359,359,359,352,453,214,204,421,460,422,204,204,204,204,204,421,460,422,204,215,393,615,463,186,452,412,412,186,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,357,357,357,,,,,,,,,309,318,443,,309,318,443,,,309,318,443,,309,318,318,318,318,443,,,309,318,318,318,318,318,318,318,318,443,,,,186, +,217,463,353,500,372,413,373,500,500,309,443,500,500,500,352,412,452,413,500,463,186,371,474,298,298,325,298,298,298,325,325,325,325,299,299,299,299,299,325,325,325,245,245,245,245,245,246,615,615,350,410,390,390,351,359,359,203,421,460,422,204,204,205,223,223,223,223,223,223,223,223,223,223,223,223,223,463,452,353,463,186,452,452,452,495,318,318,318,318,318,318,318,443,,309,318,318,318,318,318,318,443,,,,,,,,,,,,,,,,,,,,,,309,318,463,401,186,318,463,401,186,318,318,463,400,186,318,255,352,412,413,373,442,,,470,372,452,412,452,412,353,500,500,186,,,,186, +,,463,452,353,500,500,500,500,500,463,186,353,500,352,452,452,500,500,500,463,186,359,474,298,298,298,298,325,325,298,299,299,299,325,299,299,299,299,299,325,325,245,245,245,245,245,246,500,350,450,431,155,215,370,410,351,217,223,223,223,223,223,230,452,452,412,373,500,372,413,452,452,500,500,500,500,463,372,453,463,186,432,452,373,500,500,352,452,413,452,452,373,186,318,255,352,412,452,412,452,353,495,318,318,318,318,318,318,318,318,318,318,318,318,96,318,318,318,318,318,318,318,318,255,500,461,210,300,500,461,204,300,412,500,461,210,300,500,412,452,373,615,500,409,,,97,500,372,413,413,413,452,412,353,495,443,322,,186, +,,463,452,452,412,412,353,500,352,463,186,452,412,452,452,500,500,500,500,463,186,359,474,298,298,298,298,298,298,298,299,299,299,299,299,299,325,299,299,325,325,245,245,245,245,245,246,500,370,411,411,410,463,359,370,450,410,351,359,359,372,452,452,452,413,373,214,462,500,500,372,452,452,452,353,500,463,500,432,463,186,452,453,500,214,204,204,204,215,372,373,500,186,352,412,413,413,452,452,413,452,412,353,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,372,413,500,500,500,413,500,500,500,452,452,500,500,500,452,413,373,500,500,500,409,,,97,500,615,615,615,400,372,413,452,353,186,,322,186, +,,463,432,452,452,452,373,500,432,463,186,432,452,452,452,452,452,452,500,463,186,359,474,298,298,325,298,298,325,325,325,299,299,299,325,299,325,299,299,325,325,325,325,245,245,325,246,615,615,615,615,370,463,359,359,370,411,450,410,351,500,432,452,373,500,214,205,353,500,500,500,432,452,452,452,353,463,615,432,463,186,452,452,412,186,223,223,223,203,204,421,210,205,500,309,318,443,432,453,309,318,443,452,412,309,318,443,412,412,309,318,443,309,318,443,309,318,443,309,318,443,309,318,443,500,309,318,443,500,309,318,443,432,452,309,318,443,373,500,500,500,352,353,507,,322,506,500,500,615,615,615,615,615,432,452,186,,,186, +,,463,432,452,452,373,500,352,452,463,186,432,452,452,452,452,452,452,500,463,186,351,474,298,298,325,298,298,325,325,325,299,299,299,325,299,325,299,299,325,325,325,325,209,209,325,246,615,615,615,615,359,463,211,211,211,268,430,450,431,500,372,373,500,500,186,230,452,353,500,352,452,452,413,452,413,463,412,453,463,186,432,452,452,186,223,223,223,229,223,223,210,224,500,461,204,300,500,500,461,204,300,500,500,461,204,300,500,500,461,204,300,461,204,300,461,204,300,463,401,186,463,401,186,412,463,401,186,412,463,401,186,452,373,463,401,186,500,500,500,352,452,373,186,,309,255,500,500,615,615,240,241,242,452,453,186,,,186, +,,463,416,452,373,352,500,452,452,463,186,452,452,413,413,452,452,413,373,463,186,44,474,298,298,325,298,298,298,325,325,299,299,299,325,299,325,299,299,325,325,209,325,209,209,298,246,359,359,615,615,350,463,,,,246,370,450,431,500,214,421,460,422,205,500,452,452,412,452,452,373,615,615,615,463,372,413,203,205,452,413,373,186,223,301,353,217,223,223,210,230,452,500,500,615,615,432,500,500,500,452,452,500,500,500,500,372,500,500,500,500,500,500,500,500,500,461,204,300,461,204,300,500,461,204,300,500,461,204,300,453,500,461,204,300,412,353,500,432,373,500,186,,463,500,500,500,615,615,175,187,175,500,373,186,,,186, +,309,255,432,453,500,500,175,187,175,463,186,372,68,500,500,372,373,500,500,203,205,431,474,298,298,298,325,298,298,298,299,299,299,299,325,299,325,299,299,299,209,209,325,209,331,332,288,615,615,615,615,430,463,,,331,288,359,370,371,500,186,223,223,223,230,452,413,452,452,452,373,615,146,147,148,203,215,615,217,230,373,500,214,205,,463,452,500,500,500,500,500,500,413,373,615,615,432,452,452,452,452,452,452,413,373,500,500,372,413,452,452,413,413,500,500,500,500,500,500,500,500,500,413,500,500,500,452,500,500,500,413,412,500,500,500,452,452,412,453,214,210,300,,463,500,500,500,615,615,500,500,500,373,214,300,,,186, +,463,412,452,373,401,372,500,500,500,203,205,401,401,500,500,615,615,500,500,217,230,391,287,332,208,298,298,325,298,298,299,299,299,325,299,299,325,299,299,299,209,325,209,331,288,615,615,615,615,350,410,450,203,204,204,204,421,460,460,422,204,205,500,500,452,452,373,500,432,452,453,500,615,464,321,464,217,463,353,500,500,500,352,186,224,,463,413,452,452,453,500,372,373,500,500,352,412,452,452,452,452,452,413,373,214,204,204,204,204,204,204,204,421,210,422,215,500,500,452,452,413,452,373,500,372,413,452,413,413,452,373,500,432,452,413,452,413,413,452,373,186,,,,463,500,500,500,615,615,500,500,500,500,186,,,,186, +,463,416,373,500,500,500,401,401,401,217,230,500,352,500,500,615,615,615,500,500,359,450,410,351,474,298,298,298,325,325,325,325,325,299,299,299,299,325,325,325,325,325,209,246,500,615,615,350,410,411,411,431,217,223,223,189,196,189,223,223,223,230,500,500,372,373,401,500,432,413,413,412,353,500,485,500,352,463,413,353,352,412,413,186,230,,461,215,432,413,452,353,500,500,352,412,452,452,452,413,413,413,373,500,352,186,,,,,,,,,,,461,204,215,372,373,214,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,300,322,322,322,461,204,204,204,204,204,204,204,204,210,300,,,,186, +,463,452,500,500,500,401,401,500,500,500,500,500,372,452,452,500,500,452,413,500,359,359,450,44,287,332,208,298,325,298,299,299,299,325,299,299,299,299,299,299,209,209,298,246,500,350,390,411,371,615,615,370,351,615,350,351,359,359,359,359,372,413,452,353,500,500,352,412,373,615,615,372,452,412,412,412,413,203,204,204,204,204,204,205,,,,461,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,300,,,309,318,318,210,318,443,,,,,463,500,500,186,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,186, +,463,467,467,500,500,500,500,500,500,500,500,500,500,372,413,413,413,373,500,500,500,500,500,500,500,500,287,208,325,298,299,298,298,299,299,325,299,298,298,299,209,298,331,288,350,431,615,615,615,615,615,500,370,390,411,411,390,351,615,615,615,615,432,453,401,352,413,373,615,615,615,500,372,413,413,373,500,217,223,223,223,223,223,224,,,,,,,,,,,,,,,,,,,,,,,,,463,615,615,500,372,186,,,,,203,215,214,205,,,,422,215,,,,,214,421,,,422,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,205, +,598,467,467,468,637,637,637,637,466,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,287,332,332,332,332,332,332,332,332,332,332,332,332,332,332,288,615,370,371,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,432,452,412,373,500,615,615,615,615,615,615,615,615,615,615,615,615,615,615,500,272,224,,309,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,255,615,615,500,500,495,318,318,443,,229,463,186,224,,,,223,203,204,204,204,204,205,223,,,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,224, +,64,467,467,468,657,657,658,659,466,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,467,467,467,467,615,615,500,500,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,432,452,373,500,500,615,615,615,615,615,615,615,615,615,615,615,615,615,615,500,186,230,,405,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,406,615,615,615,615,500,500,500,500,500,186,,217,463,186,224,,,,223,229,223,223,223,223,224,223,,,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,224, +,64,467,467,468,198,434,434,434,486,487,487,487,487,487,487,487,472,119,487,487,487,472,119,303,472,467,119,487,487,487,487,487,487,487,487,487,487,472,467,467,467,467,615,615,500,500,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,500,453,500,500,500,500,500,500,500,500,500,500,500,615,615,615,615,615,214,204,205,,,248,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,248,615,615,615,615,500,500,500,500,500,186,,,463,186,230,,,,223,229,223,223,223,223,224,223,,,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,224, +,64,467,467,468,355,434,434,198,434,434,434,434,434,434,434,434,466,468,198,434,434,466,468,253,466,467,468,434,434,434,434,434,434,434,374,415,355,486,487,487,467,467,500,401,401,401,500,352,412,412,418,353,500,615,615,352,412,615,615,615,615,615,500,500,500,500,500,500,500,500,500,500,401,615,500,500,500,615,615,615,186,223,230,,,248,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,248,418,452,418,500,500,500,500,500,352,186,,,463,186,,,,,,217,223,223,223,223,230,,,,,49,49,49,49,49,49,,,,,,,,,,,,,,,,,,186, +,64,467,467,67,617,448,434,446,447,447,447,447,448,434,434,434,486,488,434,434,434,486,488,469,486,487,488,434,434,434,434,198,434,434,434,434,374,375,597,615,615,615,401,401,500,401,401,418,452,452,452,373,500,500,352,413,452,464,321,464,615,615,500,615,615,615,500,500,357,357,357,357,357,357,500,500,500,500,615,615,186,,,,,248,352,412,412,412,412,412,392,392,392,392,392,392,412,412,412,412,412,412,412,353,248,418,418,418,500,500,500,500,500,432,186,,,463,186,,,,,,,,,,,,328,,,,49,49,49,49,49,49,,,,,,,,,,,,,,,328,,,186, +,64,119,487,487,487,488,381,486,487,487,487,472,468,434,434,434,434,381,434,434,374,434,434,434,434,434,434,434,446,447,447,448,434,434,434,434,434,434,198,596,500,500,401,500,500,500,401,432,452,413,373,500,214,204,210,215,500,500,500,500,500,500,615,615,500,500,500,500,357,500,500,500,500,500,615,615,500,357,615,615,186,,405,402,402,426,432,452,452,413,452,373,615,615,615,615,400,500,372,413,452,452,452,452,452,453,425,402,402,406,615,615,500,500,500,432,186,,,463,186,,,,,,,328,,,,,,,,,,49,49,,,,,,,49,49,49,49,49,49,49,49,,,,,328,,186, +,64,468,198,434,434,434,434,434,434,374,192,466,468,434,434,434,434,381,446,447,448,198,434,434,434,434,434,434,466,467,467,468,434,434,434,434,434,434,434,434,356,356,401,401,500,401,401,432,418,615,615,500,186,,,463,500,500,500,615,615,615,500,500,500,500,357,357,500,500,500,500,500,500,500,401,357,357,615,615,186,,248,129,129,134,432,452,373,405,402,402,402,402,402,402,402,402,402,402,406,452,452,452,452,453,133,129,129,248,615,615,500,500,352,452,186,,,463,186,,,,,,,,,,,,,,,,,,,,,,,,,49,49,49,49,49,49,49,49,,,328,,,,186, +,64,468,434,434,434,434,434,434,434,434,374,466,468,434,434,198,434,446,467,467,67,448,434,434,434,434,446,447,244,467,467,67,447,447,447,447,447,448,434,198,372,356,356,401,401,401,352,452,373,615,615,500,495,318,318,255,500,452,453,615,615,500,500,500,500,500,500,615,615,500,500,500,500,500,357,357,500,615,615,615,186,,248,149,149,154,432,453,405,248,457,457,457,457,457,457,457,457,457,457,248,406,452,452,452,453,153,149,149,248,615,615,500,500,432,453,186,,,463,186,,,309,318,318,443,,,309,318,443,49,49,49,49,49,49,,,,,,,,,,,,,,,,,,,328,,,186, +,64,468,434,434,434,434,446,447,447,447,447,244,468,434,434,434,434,466,467,467,467,468,434,434,434,434,466,467,467,467,467,467,467,467,467,467,467,467,467,434,615,432,356,353,500,352,452,453,500,615,615,432,452,500,500,500,452,452,418,615,615,357,357,500,500,500,500,500,500,500,500,500,357,357,615,615,500,357,615,615,186,,248,615,615,352,452,453,248,248,457,457,457,457,457,457,457,457,457,457,248,248,452,452,452,452,412,412,353,248,615,615,500,352,452,453,186,,,463,186,,,203,204,204,205,,,203,204,205,49,49,49,49,49,49,49,49,49,49,49,49,328,49,49,49,49,49,49,,,,,,,,,186, +,64,468,434,434,434,434,466,119,303,472,467,119,488,434,434,434,434,466,467,467,467,468,434,434,434,434,466,467,467,467,467,467,467,467,467,467,467,467,467,467,615,372,356,413,412,452,413,373,500,615,615,372,416,413,373,500,372,413,373,615,615,615,357,357,500,500,500,500,615,500,500,500,500,500,357,357,357,500,615,615,186,,248,615,615,432,452,453,248,425,402,402,402,406,457,457,457,405,402,402,426,248,432,452,452,413,452,452,453,248,615,615,500,432,452,373,186,,,463,186,,,229,223,223,224,,,217,223,230,309,318,318,318,318,443,49,49,49,49,49,49,328,49,49,49,49,49,49,,,,,,,,,186, +,64,468,198,434,434,434,466,468,253,466,119,488,434,434,434,434,434,486,472,467,467,468,434,434,434,434,486,487,472,467,467,119,487,487,487,487,487,487,472,467,615,500,356,356,356,356,356,356,500,615,615,615,615,500,615,615,500,500,500,615,615,500,500,500,352,353,500,500,500,615,615,615,500,357,615,500,357,357,615,615,186,,248,615,615,432,452,453,248,133,130,131,132,425,402,402,402,426,129,129,134,248,432,452,373,401,372,452,453,248,615,615,352,418,373,500,186,,,463,186,,,463,500,500,186,,,,,,463,500,500,500,500,186,,,,,,,,,,,,,,,,49,49,49,49,328,,186, +,64,468,434,434,434,434,486,488,469,466,468,198,434,434,434,434,434,434,466,467,467,468,434,434,198,434,434,434,466,467,467,468,434,498,420,420,499,434,466,467,615,214,204,204,204,215,500,356,500,615,615,615,615,500,500,500,615,615,500,615,615,500,500,500,372,373,500,500,352,353,500,357,500,500,500,357,357,615,615,615,186,,248,615,615,432,452,453,248,153,150,151,152,249,130,131,132,249,149,149,154,248,372,373,500,500,500,372,373,248,615,615,432,453,214,204,300,,,463,186,,,463,500,500,186,,,,,,461,215,500,500,500,186,,,,,,,,,,,328,,,,,49,49,49,49,328,,186, +,64,468,434,434,434,374,434,434,434,466,468,434,434,434,434,434,434,434,466,467,467,468,434,434,434,434,434,434,466,467,467,468,434,423,286,286,64,434,466,467,615,186,,,,463,500,356,500,615,615,500,615,615,500,500,615,615,615,615,500,500,500,500,500,500,401,500,372,452,353,500,500,500,357,357,500,500,615,615,186,,425,406,352,417,452,453,248,99,99,99,99,408,150,151,152,408,99,99,99,248,401,500,500,500,500,500,401,248,615,615,432,453,186,,,,,463,186,,,441,500,500,186,,,,,,,461,421,210,422,300,,,,,,,,,,328,,,,,,,49,49,,,,186, +,64,468,198,434,434,434,374,375,434,466,468,434,434,434,434,434,434,434,466,467,467,468,434,434,434,434,434,434,466,467,467,468,434,234,236,236,456,434,466,467,615,186,,,,463,500,356,500,615,615,615,615,615,615,357,357,500,615,615,500,500,615,401,500,500,357,357,357,372,373,500,615,615,357,500,500,500,615,615,186,,133,248,432,452,452,373,248,99,99,99,99,428,99,99,99,428,99,99,99,248,353,500,500,401,500,500,352,248,615,615,432,453,186,,,,,463,186,,,496,421,210,300,328,,,,,,,,,328,,,,,309,318,318,403,,,,,,,,,,49,49,,,,186, +,64,67,447,448,434,434,434,434,434,466,468,434,434,434,434,434,434,434,466,467,467,468,434,434,434,434,198,434,486,487,487,488,434,434,434,434,434,434,466,467,615,495,443,,,463,500,356,500,615,615,500,615,615,357,500,500,500,500,615,615,615,357,357,500,500,615,615,357,500,500,615,357,357,615,500,500,615,615,615,186,,153,248,432,452,453,500,248,99,99,99,99,99,99,99,99,99,99,99,99,248,453,500,500,500,500,500,432,248,615,615,432,373,186,,,,,463,186,,,,,,328,,,,,,,,,,,,,,,463,500,500,186,,,,328,,,,,49,49,49,49,328,,186, +,64,467,467,468,198,434,434,434,434,466,468,434,434,434,198,434,434,446,244,467,467,468,434,434,434,434,434,434,434,198,374,415,415,434,434,434,434,375,466,467,615,615,495,318,318,255,500,356,500,615,615,615,401,357,357,357,500,615,615,500,357,357,500,615,615,500,500,500,500,500,500,357,615,357,353,500,357,357,615,615,186,,,248,417,452,373,500,248,99,99,99,99,99,99,99,99,99,99,99,99,248,373,401,352,412,353,401,432,248,615,615,393,500,495,318,443,,,463,186,,,,,,,,49,49,49,49,,,,,,,,,,463,500,500,186,,328,,,,,,,49,49,49,49,328,,186, +,64,467,467,467,447,447,447,447,447,244,67,447,448,434,434,434,434,466,467,467,467,468,198,434,434,446,447,447,447,447,447,447,448,434,434,434,375,446,244,467,615,615,615,615,615,500,500,356,500,615,615,615,615,615,615,615,615,352,353,615,615,615,615,615,615,615,615,615,615,615,615,615,615,432,453,615,615,615,615,615,186,,,248,452,453,615,615,425,402,402,402,402,406,99,99,99,405,402,402,402,426,615,615,372,452,452,405,402,426,615,615,373,500,615,615,186,,,463,186,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,461,204,204,300,49,49,49,49,49,49,,,,49,49,,,,186, +,64,467,467,467,119,487,487,487,487,487,487,487,488,434,434,434,434,466,467,467,467,468,434,434,354,466,467,467,467,467,467,119,488,434,434,434,434,466,467,467,615,615,615,615,615,500,500,356,353,615,615,615,615,615,615,615,615,432,453,615,615,615,615,615,615,615,615,615,615,615,615,615,615,327,453,615,615,615,615,615,186,,,248,432,453,615,615,249,129,129,129,129,248,99,99,99,248,129,129,129,249,615,615,500,432,452,248,129,134,615,615,500,254,615,615,186,,,463,186,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,,,,328,328,,,,186, +,64,467,467,467,468,198,434,434,434,434,374,434,434,198,434,434,434,466,467,467,467,468,355,434,455,466,119,303,472,467,119,488,434,434,434,434,434,486,472,467,615,615,615,615,500,500,352,356,356,412,412,353,500,2,3,4,352,452,327,615,615,615,615,615,615,615,615,615,615,615,615,615,615,432,453,615,615,615,615,615,186,,,248,432,373,615,615,408,149,149,149,149,425,402,402,402,426,149,149,149,408,615,615,500,432,453,248,149,154,615,615,500,254,500,500,186,,,463,186,,,,,,,,,,,,,,,,,,,,,49,49,49,49,,,,,,,,,,,328,,328,,186, +,64,467,467,467,468,434,434,434,434,434,434,434,434,434,434,434,434,466,467,467,467,468,435,434,374,466,468,253,466,467,468,198,434,434,434,434,434,434,466,467,615,615,615,615,500,500,432,327,356,452,327,373,500,22,23,24,372,373,615,615,615,615,615,615,615,615,615,500,500,500,500,500,500,500,500,500,500,500,500,615,186,,,248,393,500,615,615,428,352,412,353,500,249,130,131,132,249,500,372,373,428,615,615,352,452,452,248,500,500,500,500,500,254,500,500,495,443,,463,186,,309,318,318,443,,,,,,,,,,49,49,49,49,,,,,,,,328,328,,,,,,,,328,,324,,186, +,64,467,467,467,468,434,198,434,446,447,447,447,447,448,434,434,434,466,467,467,467,468,375,434,434,486,488,469,486,472,468,434,434,434,434,434,434,434,466,467,615,615,615,615,615,500,372,452,356,356,356,356,500,500,356,500,500,500,615,615,615,615,500,357,357,357,500,357,357,500,500,357,357,357,500,357,500,357,500,615,186,,,248,453,500,500,372,412,452,452,373,500,408,150,151,152,408,500,500,500,500,500,500,432,452,373,248,500,500,500,500,500,254,254,500,500,186,,463,186,,463,500,400,186,,,,,,,,,49,49,49,49,49,328,328,328,328,,,,,,,328,328,328,328,,,,,328,,186, +,64,467,467,467,468,434,434,434,466,467,467,467,467,468,434,434,434,486,487,487,487,488,434,434,434,434,434,434,434,466,468,434,434,434,434,434,434,434,466,467,615,68,68,615,615,615,500,372,413,373,500,356,500,500,356,500,500,500,500,615,615,615,500,500,500,615,357,500,500,500,500,500,357,357,615,500,500,357,357,615,186,,,248,452,353,500,500,372,413,373,500,500,428,500,444,500,428,500,352,353,500,352,412,452,453,500,248,210,422,204,215,500,500,254,500,500,186,,463,186,,463,500,500,186,,,49,49,49,49,,,49,49,,,,,,,,,,,,,,,,,,,,,,326,,186, +,64,467,467,119,488,434,434,434,466,467,467,467,467,468,434,434,434,434,434,434,434,434,434,434,434,434,434,434,198,466,468,434,434,434,434,434,434,434,466,467,615,68,452,68,615,615,615,500,500,500,500,356,356,356,356,500,401,500,352,412,500,500,500,357,357,357,500,357,615,500,500,500,357,357,500,357,500,357,500,615,186,,,248,452,452,412,353,500,500,500,352,353,500,500,444,500,500,352,452,452,412,452,452,452,373,500,248,,,,463,500,500,254,615,615,186,,463,186,,461,204,204,330,,,49,49,49,49,,328,328,,,,,,,,328,328,328,,,,,,,,,328,,328,328,,,186, +,64,467,467,468,434,198,434,434,486,487,487,487,487,488,434,198,434,446,447,447,447,448,434,434,434,198,198,434,434,466,468,434,434,434,198,434,434,446,244,467,615,68,68,68,373,615,615,500,500,500,500,500,500,500,500,500,401,352,452,413,500,500,500,500,500,357,615,615,500,500,500,500,615,615,500,500,500,500,500,615,186,,405,426,372,452,452,452,412,412,412,452,413,353,500,444,500,352,452,452,452,452,452,452,373,500,352,425,406,,,463,500,500,254,615,615,186,,463,186,,,,,,,,,,,,,,,328,,,,,,,,,,,,328,328,,,,,,,,,,,186, +,64,467,467,468,355,434,434,434,434,434,434,434,434,434,434,434,434,466,467,467,467,468,198,446,447,447,447,447,447,244,67,447,448,434,434,434,434,466,467,467,615,372,413,373,500,214,421,210,422,204,204,204,204,204,204,204,215,500,453,615,615,615,615,615,500,500,500,357,357,500,500,500,500,500,500,357,357,500,500,615,186,,248,405,402,402,402,402,402,402,402,402,405,406,353,444,352,405,406,402,402,402,402,402,402,402,402,406,248,,,463,615,615,500,615,615,186,,463,186,,,,,,,,,,,,,,,328,,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,186, +,64,467,467,468,192,355,434,434,434,434,434,434,434,434,434,434,434,466,467,467,467,468,434,466,467,467,119,487,487,487,487,487,488,434,434,434,434,486,472,467,615,357,357,357,357,186,223,210,223,223,223,223,223,223,223,223,463,452,373,615,615,615,500,500,615,615,357,500,500,500,500,615,357,357,500,500,500,500,500,615,186,,425,426,129,129,129,129,129,129,129,129,425,426,99,444,99,425,426,129,129,129,129,129,129,129,129,425,426,,,463,615,615,500,615,615,186,,463,186,,,,,,,,,,,,,,,328,,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,186, +,64,467,467,468,374,435,198,434,434,434,434,434,198,434,198,434,434,466,467,467,467,468,434,466,467,467,468,434,434,434,434,434,434,434,381,374,192,434,466,467,615,214,421,210,422,300,357,357,357,357,357,357,357,357,357,357,463,500,500,615,615,615,500,615,357,500,357,357,500,500,500,500,357,357,615,357,357,357,500,615,186,,133,134,149,149,149,149,149,149,149,149,133,134,99,444,99,133,134,149,149,149,149,149,149,149,149,133,134,,,461,204,204,204,204,204,300,,463,186,,,,,,,328,328,328,328,,,,,328,,,,,,,,,,,,,,,,,,,,,328,328,328,186, +,64,467,467,67,448,455,355,198,434,434,434,434,434,434,434,434,434,466,467,467,467,468,434,486,487,487,488,434,446,447,447,448,434,198,434,198,374,434,466,467,467,186,357,357,357,500,327,500,357,357,357,357,357,357,357,357,463,500,353,615,615,615,500,500,500,500,357,615,615,500,500,357,615,615,500,500,615,357,500,615,186,,153,154,,,,,,,,,153,154,99,444,99,153,154,,,,,,,,,153,154,,,,,,,,,,,463,186,,,,,,,,,,,328,328,328,,328,328,,,,,,328,328,328,328,328,328,328,328,328,,,,,,,,328,186, +,64,467,467,467,468,374,435,434,434,434,434,434,434,434,434,434,434,466,467,467,467,468,434,434,434,434,434,434,466,467,467,468,381,434,434,434,381,434,466,467,467,186,357,357,500,327,500,327,500,357,357,357,357,400,357,309,235,500,500,615,615,615,500,500,357,357,357,357,500,500,500,500,357,357,500,357,357,500,500,615,186,,,,,,,,,,,,,404,99,444,99,404,,,,,,,,,,,,,,,309,318,318,318,443,,,463,186,,,,,,,,,,,,,,,,,,328,328,328,328,328,,,,,,,,,,,,,,,,,186, +164,456,467,467,467,468,434,455,355,434,434,434,434,434,434,434,434,434,467,467,467,467,468,398,434,434,434,434,434,466,467,467,468,434,198,434,198,354,434,466,467,467,186,357,357,357,500,327,500,357,357,357,357,357,357,357,463,452,500,373,615,615,615,500,357,357,500,500,357,357,615,500,500,500,500,357,357,615,615,615,615,186,,,,,,,,,,,,,248,99,444,99,248,,,,,,,,,,,,,,,463,500,500,500,186,,,463,186,,,,,,,,,,,,,,,,,,,,,,,,,328,328,328,,,,,,,,,,,,186, +64,467,467,119,487,488,434,455,435,434,434,434,434,434,434,434,434,434,467,467,467,467,468,434,434,434,434,434,434,466,467,467,468,198,434,381,354,434,434,466,467,467,186,357,357,357,357,357,357,357,357,357,357,357,357,357,463,500,373,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,214,462,500,500,500,495,318,318,318,318,318,318,318,318,318,318,318,318,424,99,444,99,424,318,318,318,318,318,318,318,318,318,318,318,318,318,318,255,353,500,352,495,443,,463,495,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,443,,,,309,318,318,443,186, +64,467,467,468,434,434,354,192,434,434,434,434,434,434,434,434,434,434,434,467,467,467,467,447,447,447,447,447,447,244,467,467,67,447,447,447,447,447,447,244,467,467,186,357,357,357,357,357,357,357,357,357,357,357,357,357,463,373,491,615,615,615,615,214,204,204,204,204,204,204,204,204,204,204,204,204,205,500,500,615,615,615,615,400,500,401,401,401,401,401,500,372,413,452,412,353,444,352,412,452,413,373,500,500,500,500,500,500,500,500,500,372,413,413,452,412,452,452,186,,463,214,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,205,,,,203,204,204,205,186, +64,467,467,467,434,354,192,192,434,434,434,434,434,434,434,434,434,434,434,434,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,495,318,318,318,318,318,318,318,318,318,318,318,318,318,255,500,500,615,615,615,615,186,223,223,223,223,223,223,223,223,223,223,223,223,224,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,432,452,453,444,432,452,453,615,615,615,615,615,615,615,615,615,615,615,615,615,615,372,452,452,373,186,,463,186,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,224,,,,229,223,223,224,186, +64,467,467,467,597,455,192,192,434,434,434,500,500,500,500,500,500,500,500,500,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,500,500,615,615,615,615,186,223,223,223,223,223,223,223,223,223,361,223,223,230,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,372,452,373,356,452,413,453,615,615,615,615,615,615,615,615,615,615,615,615,615,615,500,432,452,353,186,,463,186,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,224,,,,229,223,223,224,186, +510,499,434,434,434,374,192,434,434,434,434,500,214,204,204,215,615,615,615,500,467,467,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,500,214,204,204,204,204,205,500,500,500,500,500,500,500,372,437,412,452,413,392,353,500,615,615,615,615,352,412,412,412,418,412,412,412,412,353,500,418,500,356,393,500,393,615,615,500,309,318,318,318,318,318,318,318,318,318,443,352,452,452,68,186,,463,186,363,363,363,363,363,272,223,223,223,223,223,223,361,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,361,224,,,,229,223,223,230,186, +395,64,597,597,434,434,374,434,434,434,434,500,186,266,266,463,175,175,175,615,615,615,500,352,353,615,615,615,615,615,352,353,504,504,504,352,412,418,412,412,412,412,353,500,500,500,500,500,155,215,500,412,417,353,500,500,500,352,186,223,223,223,223,224,500,500,412,353,401,500,500,500,432,452,437,500,500,437,353,500,615,615,352,452,452,413,413,413,452,452,452,418,373,500,372,392,356,373,500,393,615,615,309,255,373,500,500,500,372,452,452,452,68,186,372,68,413,452,186,,463,186,493,493,493,493,493,186,70,272,223,223,223,301,335,335,272,223,223,223,223,223,223,223,223,301,500,500,500,615,500,500,186,,,,463,615,615,214,300, +481,64,597,597,597,597,434,374,434,434,434,500,186,266,266,461,215,500,500,615,615,615,500,372,453,500,500,500,500,500,452,453,503,321,503,432,452,452,452,452,413,413,452,412,353,500,500,615,615,203,204,204,204,204,204,421,210,422,205,223,223,223,361,230,500,401,372,356,356,356,356,356,356,437,500,500,500,500,437,500,615,615,432,418,373,615,615,615,372,452,452,453,500,500,500,401,356,500,500,393,615,615,463,373,500,500,500,500,500,372,452,452,453,495,318,318,443,432,186,,463,186,493,493,493,493,493,442,335,186,,,,463,335,335,186,,,,,,,,,461,204,421,210,422,204,204,300,,,,463,615,615,186,, +,510,499,597,597,597,597,434,434,434,434,500,186,266,266,266,463,372,416,615,615,615,500,500,372,175,187,175,187,176,372,418,500,500,500,432,452,452,452,453,500,500,432,452,452,353,500,615,615,229,223,223,223,223,223,223,210,223,224,500,615,615,500,500,500,356,356,401,500,401,500,500,356,356,437,500,500,437,373,500,615,615,372,453,500,615,615,615,500,372,418,373,500,500,500,500,356,500,352,453,615,615,463,500,500,500,356,500,500,500,432,452,452,353,500,500,186,453,186,,463,186,363,363,363,363,363,409,335,442,,,,463,335,335,495,318,210,318,318,318,318,443,,,,,,,,,,,,,463,500,500,186,, +,395,64,597,434,597,597,434,434,434,434,500,495,318,318,318,255,500,393,615,615,615,155,215,500,417,356,356,356,356,356,356,356,500,352,418,452,452,452,453,500,500,372,452,452,453,615,615,500,217,361,223,223,223,223,223,210,223,230,500,615,615,500,500,500,401,418,392,500,353,500,500,500,356,432,437,437,453,500,500,615,615,500,372,392,353,356,356,356,356,356,356,356,356,356,356,356,401,372,418,615,615,463,500,500,500,356,500,500,500,418,452,413,373,500,500,186,393,186,,463,186,363,363,363,363,363,507,335,409,,,,463,335,335,335,335,335,335,335,500,500,495,318,318,318,318,318,318,318,318,318,443,,,463,500,500,186,, +,481,64,597,597,597,597,434,434,434,434,500,372,452,416,373,500,352,453,615,615,615,352,463,500,500,500,500,372,417,412,353,356,352,373,214,462,432,418,453,500,500,500,432,452,453,615,615,372,500,500,500,500,500,500,500,500,500,500,417,615,615,500,500,452,356,500,401,372,453,615,615,500,356,356,356,437,373,500,615,615,615,615,615,615,393,356,352,418,392,373,500,500,500,500,356,500,500,500,372,615,615,463,353,500,500,356,500,500,352,413,373,500,500,500,500,186,432,186,,463,186,357,363,363,363,357,186,335,507,,,,461,204,421,210,422,204,215,615,615,500,500,500,500,500,500,500,615,500,500,500,186,,,463,413,500,186,, +,,64,597,597,434,192,599,192,434,434,615,615,432,453,500,500,432,453,615,615,615,432,203,204,204,204,204,421,460,422,421,210,422,204,205,352,452,452,453,500,500,352,452,452,373,615,615,500,432,500,500,500,500,417,452,500,500,452,373,615,615,500,500,500,356,373,500,500,393,615,615,500,500,372,356,373,500,615,615,615,615,615,615,615,393,356,393,615,615,615,615,615,615,500,356,615,615,615,615,615,615,463,452,353,500,356,352,412,453,214,204,421,460,460,422,205,453,186,,463,186,204,421,210,422,204,205,335,186,,,,,,,,,,463,335,500,615,500,615,500,500,615,500,615,500,500,500,186,,,463,500,372,186,, +,,618,434,500,500,192,619,192,500,500,615,615,432,373,500,352,452,373,615,615,615,432,217,223,223,223,223,223,223,223,223,210,223,223,230,432,452,452,453,500,500,432,452,373,500,615,615,500,500,500,500,500,500,500,452,452,500,500,500,615,615,432,452,452,356,500,500,352,373,615,615,500,500,500,356,500,500,309,318,318,318,318,318,443,393,356,393,615,615,615,615,615,615,500,356,615,615,615,615,615,615,463,432,453,500,356,372,413,452,186,223,223,223,223,223,230,432,186,,463,186,223,223,210,223,361,230,335,186,,,,,,,,,,463,335,500,615,500,615,500,500,615,500,615,500,500,500,186,,,463,500,500,186,, +,,463,615,615,615,615,500,500,500,500,500,352,373,500,352,452,453,500,615,615,615,393,485,485,485,485,485,485,485,432,453,356,432,413,413,413,417,413,373,500,500,432,453,500,500,500,352,500,500,500,500,500,500,500,500,500,500,500,500,615,615,500,452,373,356,352,412,453,401,615,615,500,500,500,356,500,500,470,352,412,412,418,353,186,393,356,372,392,353,615,615,353,500,500,356,500,500,500,500,615,615,463,452,452,353,356,356,356,372,186,500,500,500,372,452,412,418,186,,463,186,223,301,335,335,335,335,335,186,,,309,318,318,318,318,443,,463,335,500,500,500,500,500,500,615,500,500,500,500,500,186,,,463,500,500,186,, +,,463,615,615,615,500,500,500,615,615,615,393,615,615,372,68,452,353,500,615,615,393,485,485,418,418,418,485,485,432,453,356,373,500,500,500,372,356,356,356,356,356,356,356,500,500,356,356,356,356,356,356,500,500,500,500,500,500,500,500,412,452,500,401,356,372,452,373,500,615,615,500,401,500,356,356,356,97,432,418,452,413,373,186,393,356,356,500,393,615,615,418,500,401,356,500,500,401,500,615,615,461,204,204,215,352,353,356,155,300,500,500,500,214,421,210,422,300,,203,205,,203,421,460,422,204,204,205,,,463,400,363,363,363,186,,463,615,615,615,615,615,615,615,615,500,500,615,615,500,495,318,318,255,500,500,186,, +,,463,615,615,500,373,500,500,615,615,615,393,615,615,500,372,413,452,353,615,615,393,485,418,485,485,485,418,485,432,453,356,500,615,615,615,500,356,352,615,615,372,373,500,500,615,615,352,418,500,500,356,356,500,500,309,318,443,500,500,500,372,452,353,356,401,393,500,615,615,615,615,500,500,500,500,500,506,372,413,373,214,210,205,432,353,401,352,453,615,615,393,500,500,356,500,500,418,500,352,412,413,353,500,461,462,393,356,500,352,412,353,500,186,,,,,,217,230,,217,223,223,223,223,223,230,,,461,204,421,210,422,300,,463,335,500,615,500,500,500,500,500,500,500,500,500,500,615,500,500,500,500,500,186,, +,,463,615,615,500,500,500,500,615,615,615,432,353,500,500,615,615,432,453,615,615,393,485,418,485,615,485,418,485,432,453,356,500,100,101,102,500,356,453,615,615,500,500,500,615,615,615,500,452,500,500,500,356,356,356,463,401,186,500,500,500,401,372,373,356,352,373,500,615,615,615,615,500,401,615,615,615,203,210,422,204,205,210,230,372,373,356,418,453,615,615,393,500,401,356,500,500,401,352,413,373,500,372,412,392,412,373,356,352,452,418,453,214,300,,,,,,,,,,,,,,,,,,,,,,,,,463,335,500,500,500,500,500,615,615,500,500,615,615,615,615,500,500,500,155,215,186,, +,,463,615,615,453,500,500,352,615,615,615,432,68,353,500,615,615,432,373,615,615,393,485,418,485,485,485,418,485,372,373,356,500,464,321,464,500,356,453,615,615,615,615,615,615,615,500,500,452,452,353,500,500,500,356,461,210,300,356,356,356,356,356,356,356,393,401,352,353,615,615,500,615,500,615,615,500,217,210,223,223,230,356,356,356,356,356,432,453,615,615,393,500,500,356,356,356,356,356,356,356,356,356,356,356,356,356,356,432,452,452,373,186,,,309,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,255,615,615,615,615,615,500,500,500,500,500,500,500,500,500,500,500,500,500,463,186,, +,,463,615,615,432,353,356,418,615,615,615,372,413,373,500,352,412,373,500,615,615,393,485,485,418,418,418,485,485,356,356,356,356,356,356,356,356,356,453,615,615,615,615,615,615,352,452,452,452,500,500,412,452,500,356,356,356,356,356,500,500,500,500,392,392,413,392,413,373,615,615,615,500,615,615,500,500,500,500,615,615,418,413,373,356,372,392,413,373,615,615,418,392,412,412,412,353,356,418,413,413,392,413,392,413,392,413,392,413,413,373,500,186,,,463,352,412,418,373,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,463,186,, +,,463,615,615,432,452,356,500,615,615,615,615,615,615,352,452,453,615,615,615,615,393,485,485,485,485,485,485,485,352,412,412,412,412,412,412,412,412,453,615,615,615,615,615,615,432,500,500,500,500,500,500,500,500,412,500,412,500,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,356,615,615,615,615,615,615,615,615,432,452,418,373,356,615,615,615,615,615,615,615,615,615,615,615,615,615,615,186,,,463,418,452,453,309,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,443,500,309,318,318,255,186,, +,,463,615,615,432,453,356,500,615,615,615,615,615,615,500,500,500,615,615,615,615,432,392,392,392,392,392,392,392,452,500,500,500,500,500,500,500,500,500,615,615,615,615,615,615,372,500,500,500,500,500,352,500,500,500,500,500,500,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,356,615,615,615,615,615,615,615,615,432,418,373,500,356,615,615,615,615,615,615,615,615,615,615,615,615,615,615,186,,,463,500,452,418,463,214,215,493,493,493,493,493,493,493,214,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,205,357,203,204,215,357,186,, +,,463,615,615,372,373,356,356,356,356,356,356,615,615,615,500,452,412,412,412,412,453,500,500,500,500,500,500,500,432,500,500,500,500,500,500,500,500,500,615,615,500,500,500,500,500,500,500,500,500,352,500,500,500,500,500,500,500,309,318,318,318,318,443,490,490,490,490,490,490,490,490,490,270,352,615,615,352,373,615,615,352,412,412,356,353,615,615,500,500,500,352,392,413,373,500,500,356,500,615,615,500,352,353,615,615,615,615,352,412,353,500,186,,,463,500,452,452,463,186,463,493,493,493,493,493,493,493,186,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,230,357,217,223,463,357,186,, +,,463,155,215,500,500,500,214,462,352,353,356,140,141,142,615,372,418,452,452,452,453,500,500,500,500,500,615,615,500,500,500,500,500,500,500,500,500,500,615,615,500,615,615,615,500,500,500,500,500,500,500,500,309,318,318,318,318,255,352,412,412,353,186,,,,,,,,,,376,372,412,412,453,356,356,356,356,356,356,356,453,615,615,500,500,352,453,615,615,615,615,615,356,500,615,615,352,373,500,615,615,615,615,372,452,452,353,186,,,461,215,418,453,463,186,463,346,348,347,338,346,348,347,186,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,363,363,357,463,357,186,, +,,463,353,203,421,460,422,205,500,432,453,356,177,320,174,321,615,500,452,452,452,417,500,500,615,615,615,615,615,500,500,500,500,500,500,500,500,500,500,615,615,353,615,615,615,500,500,500,500,500,500,500,500,470,500,500,500,500,372,452,452,452,453,186,,252,333,138,,,,,,376,500,372,413,373,356,352,412,453,309,318,318,318,318,443,500,500,372,418,615,500,500,352,353,356,356,356,356,356,356,356,356,356,356,356,356,372,452,453,495,443,,,463,372,453,463,186,463,366,368,367,382,366,368,367,186,357,357,357,357,357,357,357,357,357,357,357,357,357,363,357,357,357,363,357,357,357,357,357,363,357,357,463,357,186,, +,,463,453,217,223,223,223,230,412,418,453,356,429,473,135,500,500,500,500,452,452,453,500,500,175,187,175,500,500,432,500,500,500,500,500,500,500,500,500,615,615,68,353,500,500,352,500,500,155,204,215,500,500,97,500,500,500,500,500,432,452,452,453,186,,376,500,497,,,,,,376,500,615,615,356,356,432,452,373,463,500,500,352,353,495,443,615,615,615,615,500,352,615,418,615,352,412,412,353,615,615,615,615,615,615,615,500,432,452,353,186,,,463,400,432,463,186,463,357,357,357,363,357,357,357,186,357,357,357,357,357,357,357,357,357,357,357,357,363,363,363,357,363,363,363,357,357,357,357,363,357,357,463,357,186,, +,,463,432,353,500,440,500,372,413,413,413,392,418,500,500,500,500,500,452,452,452,453,500,500,500,356,500,500,500,432,500,500,500,500,500,500,500,500,500,615,615,500,452,412,68,500,500,500,615,615,463,500,500,506,500,500,500,500,352,452,452,452,453,186,,376,500,497,,,,,,376,500,615,615,356,352,309,318,318,255,352,412,452,452,353,186,500,500,500,500,500,418,392,373,615,372,452,452,453,615,615,615,615,615,615,352,412,413,413,373,442,,,470,352,373,463,186,463,357,357,357,363,357,357,357,186,357,357,357,357,357,357,357,357,357,357,357,357,357,363,400,357,357,363,357,357,357,357,357,363,357,357,463,357,495,443, +,,463,432,418,500,500,500,356,356,356,356,356,372,413,413,413,413,413,418,413,413,373,500,500,500,356,500,500,500,432,500,500,500,500,500,500,500,500,500,615,615,500,500,500,500,500,500,500,615,615,463,500,500,463,500,500,500,352,413,413,413,413,373,186,,158,490,480,,,,,,376,500,615,615,356,393,463,615,615,352,452,452,413,413,452,186,500,500,615,500,615,393,615,500,615,500,372,413,413,392,392,392,392,392,392,413,373,500,615,500,409,,,97,393,615,463,186,463,357,357,363,363,363,357,357,186,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,363,363,363,357,463,357,357,186, +,,463,432,452,412,412,353,356,352,615,615,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,352,412,412,452,500,500,500,500,500,500,500,500,500,615,615,500,500,500,500,500,500,500,615,615,463,500,500,203,204,204,204,204,204,204,421,210,422,205,,,,,,,,,,376,500,615,615,356,432,463,615,615,432,309,318,318,443,393,186,500,500,500,500,352,452,353,500,615,500,615,615,615,615,615,615,615,615,615,615,615,615,615,615,507,,,506,452,353,463,186,203,204,204,421,210,422,204,204,205,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,363,357,357,203,215,357,186, +,,463,418,413,413,452,453,356,393,615,615,352,412,412,412,412,412,418,412,412,412,412,392,392,392,392,413,416,413,452,500,500,500,500,500,500,500,500,500,615,615,500,500,500,500,500,500,500,615,615,463,500,500,217,387,484,484,484,387,223,223,210,223,230,,,,,,,,,,376,500,615,615,356,393,463,615,615,432,463,500,500,186,453,186,353,500,500,500,372,418,413,353,615,500,615,615,615,615,615,615,615,615,615,615,615,615,615,615,186,,,463,432,418,463,186,217,223,223,223,210,223,223,223,230,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,363,357,357,217,463,357,186, +,,463,452,500,500,432,453,356,393,615,615,372,452,418,452,452,413,413,452,452,452,453,485,485,485,485,485,485,485,432,452,452,452,373,500,500,500,372,214,204,215,500,500,500,500,500,500,500,615,615,463,500,500,615,482,483,364,483,482,,252,333,333,138,,252,138,,252,333,333,138,,376,500,615,615,356,393,463,615,615,432,203,204,204,205,432,186,452,353,615,500,615,393,615,393,615,352,418,412,353,500,500,500,500,500,500,500,500,500,500,500,186,,,463,452,453,463,186,357,357,363,363,363,357,363,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,363,357,357,357,357,357,357,357,363,357,357,357,463,357,186, +,,463,464,321,464,372,373,356,393,615,615,504,503,503,503,503,503,504,432,452,416,453,485,139,139,139,139,139,485,432,452,452,453,500,615,615,615,500,186,266,463,500,500,500,500,500,401,500,615,615,463,500,500,615,497,,,,252,333,290,500,500,497,,158,480,,158,490,490,480,,158,270,500,615,615,393,463,615,615,393,217,223,361,230,453,186,500,453,500,500,500,372,392,373,615,432,452,68,452,353,214,204,204,421,210,422,204,204,204,204,300,,,463,500,373,463,186,357,363,357,357,357,357,363,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,363,363,363,357,357,357,357,357,357,357,357,357,357,463,357,186, +,,463,353,500,500,500,356,356,418,615,615,503,500,83,440,85,500,503,432,418,452,453,485,139,139,139,139,139,485,432,452,452,453,500,115,116,117,500,186,266,463,500,500,500,500,401,401,401,615,615,463,500,500,615,289,333,333,333,290,500,500,269,490,480,,,,,,,,,,,376,500,615,615,432,463,615,615,432,417,373,500,372,373,186,500,373,615,500,500,500,615,615,615,432,452,452,452,373,186,,,,,,,,,,,,309,255,500,500,463,186,357,363,357,357,357,363,363,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,363,363,363,357,357,357,357,357,357,357,357,357,357,463,357,186, +,,463,452,412,353,356,356,500,500,615,615,352,500,103,104,105,500,452,452,452,452,453,485,139,139,139,139,139,485,432,452,416,453,500,175,187,175,500,186,266,463,500,500,615,615,500,401,401,615,615,463,500,500,615,615,500,615,500,615,500,500,497,,,,,252,138,,,,,,,376,500,615,615,393,463,615,615,372,373,500,214,204,204,205,500,500,500,500,500,615,352,392,412,452,413,413,373,214,300,,309,318,318,318,318,318,318,318,318,318,255,500,500,500,463,186,357,363,357,357,363,363,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,363,357,357,357,357,357,363,357,363,357,363,357,463,357,186, +,,463,432,452,453,356,352,353,500,615,615,372,500,175,187,175,500,452,452,452,452,453,485,139,139,139,139,139,485,432,452,452,433,500,500,500,500,500,186,266,463,615,615,615,615,500,500,401,615,615,463,500,500,500,615,615,615,615,615,500,500,497,,252,138,,158,480,,,,,,214,462,500,615,615,393,463,615,615,615,500,352,186,223,361,230,615,615,615,615,500,615,393,214,204,204,204,204,204,300,,,463,500,500,500,500,500,500,500,500,500,500,500,500,500,463,186,357,363,357,363,363,363,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,363,363,357,363,357,357,463,357,186, +,,463,372,413,453,356,432,373,615,615,615,615,372,373,500,372,413,413,418,413,413,416,485,485,485,485,485,485,485,372,413,413,413,353,500,500,615,615,186,266,463,615,615,615,500,500,500,500,615,615,463,500,500,500,500,353,500,500,615,352,353,497,,158,480,,,,,,,,,186,500,500,615,615,432,463,615,615,615,500,432,186,500,500,500,500,500,500,500,500,352,452,186,,,,,,,,,461,210,215,500,500,413,452,452,453,500,500,500,452,500,463,186,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,463,357,186, +,,463,615,615,393,356,393,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,495,318,255,615,615,615,500,500,500,500,615,615,203,204,204,204,204,421,210,422,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,205,500,500,615,615,432,463,615,615,615,500,372,186,500,615,393,615,615,500,615,500,418,453,186,,,,,,,,,,,463,500,615,615,432,452,452,412,452,418,452,500,463,495,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,255,357,186, +,,463,615,615,372,356,373,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,500,500,500,500,615,615,217,223,223,223,223,223,210,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,230,500,500,500,615,432,463,357,615,615,615,615,186,500,615,393,615,615,500,615,500,372,373,186,,,,,,,,,,,463,500,615,615,500,452,452,413,452,418,500,500,203,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,215,615,214,204,204,204,204,204,204,215,615,214,204,204,204,421,361,422,215,615,186, +,,463,353,500,500,356,356,352,412,392,392,392,392,392,412,418,392,392,412,412,412,412,412,412,412,413,418,412,412,412,392,392,412,412,412,353,615,615,615,615,615,615,615,615,500,500,500,500,500,500,500,500,500,500,615,615,500,500,500,500,500,500,500,500,500,615,500,500,500,615,500,500,500,500,500,500,500,615,393,463,357,615,357,214,204,205,500,413,413,412,353,500,500,214,204,204,300,322,,,,,,,,,,463,453,615,615,418,500,373,500,372,500,500,500,217,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,361,463,214,300,,,,,,,461,215,186,505,505,505,505,505,505,461,215,186, +,309,255,155,215,353,500,356,418,214,204,204,204,204,462,432,453,500,500,432,413,413,452,418,452,373,500,372,413,413,373,500,500,372,418,413,452,353,500,500,615,615,500,500,500,500,252,333,333,333,333,333,138,500,500,615,615,615,500,500,500,500,500,309,318,318,443,500,500,500,500,500,500,500,500,500,500,500,615,453,463,615,500,615,186,223,230,615,615,500,372,453,500,352,186,,,,,,,,,,,,,,463,393,615,615,500,373,500,352,353,500,615,615,500,500,86,87,87,88,372,452,413,68,413,373,92,93,94,92,93,94,500,500,463,186,,,,,,,,,461,300,505,505,505,505,505,505,505,463,186, +,463,352,353,203,204,421,494,422,205,352,412,452,413,392,413,413,412,412,453,615,615,372,413,373,500,615,615,615,615,615,615,615,615,393,500,432,418,353,500,615,615,500,500,500,252,290,401,500,500,500,500,289,333,333,138,615,615,500,615,615,615,500,203,204,204,205,500,500,500,615,500,500,500,500,500,500,500,615,432,463,214,204,204,205,500,500,353,500,214,204,421,210,422,300,,,,,,,,,,,,,,463,373,615,615,393,500,352,452,452,353,615,615,615,500,106,107,107,108,500,500,500,500,500,500,112,113,114,112,113,114,500,500,463,186,,,,,,,,,505,505,505,505,505,505,505,505,505,463,186, +,463,432,452,217,223,223,223,223,230,432,452,453,500,500,500,401,372,452,453,615,615,615,615,401,500,615,615,615,615,615,615,615,615,432,412,452,413,452,353,615,615,500,401,500,376,500,269,490,490,500,500,490,270,250,289,333,333,138,500,615,615,500,217,361,223,230,615,615,615,615,500,500,500,500,500,500,500,615,393,463,186,223,361,230,500,452,373,500,186,,,,,,,,,,,,,,,,,,,463,500,615,615,500,353,372,452,418,373,500,615,615,500,175,187,175,175,500,175,187,175,500,500,175,187,175,175,187,175,500,353,463,186,,,,,,,,,309,443,505,505,505,505,505,505,505,463,186, +,463,452,452,452,413,418,356,432,412,413,413,452,412,412,353,500,214,462,393,615,615,615,615,401,401,401,352,412,412,392,392,412,412,452,418,453,500,432,373,615,615,500,615,252,290,500,497,500,,500,500,,158,270,500,500,500,497,500,615,615,500,615,500,500,500,500,500,500,500,500,500,500,500,500,500,500,615,453,463,186,500,500,500,500,453,500,500,186,,,,,,,,,,,,,,,,,,,463,500,615,615,500,500,500,432,373,500,352,418,453,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,500,432,463,186,,,,,,,,,463,186,505,505,505,505,505,505,505,463,186, +,463,372,413,373,356,356,356,372,214,204,462,432,418,452,452,353,186,352,418,615,615,352,353,500,500,352,452,452,373,615,615,372,413,413,452,452,412,373,500,615,615,401,500,376,500,500,497,,,,,,,376,500,269,490,480,500,615,615,500,615,500,500,500,500,500,500,500,500,500,500,500,500,500,500,615,453,463,186,500,500,500,452,453,500,214,205,,,,322,,,59,,,,,,,,,,,,463,500,615,615,500,500,500,373,500,352,418,615,615,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,485,500,452,463,186,,,,,,,,,463,186,505,505,505,505,505,505,505,463,186, +,203,204,204,421,494,422,204,204,205,373,352,452,452,452,452,452,186,372,453,615,615,432,453,500,500,432,452,453,615,615,615,615,615,615,309,318,318,318,443,615,615,500,500,376,500,500,289,333,333,333,138,,,376,250,497,500,500,500,615,615,500,615,500,500,500,500,500,500,500,500,500,500,500,500,500,500,615,432,463,186,500,500,452,452,373,500,186,224,,,,,,,,,,,,,,,,,,,463,500,615,615,500,500,453,500,352,452,453,615,615,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,485,500,393,463,495,318,318,443,505,309,318,318,318,255,186,505,505,505,505,505,309,318,255,186, +,229,223,223,223,223,223,223,223,230,500,432,418,452,452,452,453,186,500,393,615,615,432,453,500,352,452,452,453,615,615,615,615,615,615,203,204,204,204,205,615,615,500,500,376,500,250,500,269,490,270,497,,,376,500,497,500,500,500,615,615,500,615,500,500,500,500,500,500,500,500,500,500,500,500,500,500,615,432,463,186,500,452,452,373,500,500,186,230,,,,,,,,,,,,,,,,,,,463,500,615,615,372,500,453,500,372,452,453,615,615,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,485,500,432,463,155,204,204,300,505,203,204,204,204,204,205,505,505,505,505,505,461,204,462,186, +,463,452,452,453,356,372,452,452,373,352,452,452,413,413,418,373,186,353,372,615,615,432,418,412,452,452,452,452,418,615,615,500,500,465,217,483,251,483,230,615,615,500,252,290,500,500,500,497,,376,497,,252,290,615,497,500,500,500,615,615,500,615,500,500,500,500,500,500,500,500,500,500,500,500,500,500,615,453,463,186,500,452,453,500,500,352,186,,,,,,322,59,59,59,59,,,,,,,,,,461,210,204,204,215,500,452,353,500,418,453,615,615,500,500,500,452,452,452,452,452,500,500,500,500,500,500,500,500,500,500,393,463,505,505,505,505,505,217,223,223,223,223,230,505,505,505,505,505,505,505,505,186, +,463,372,413,373,356,356,372,373,500,372,413,373,214,421,460,422,205,418,353,615,615,432,452,452,452,418,452,452,373,615,615,500,500,465,465,465,465,465,465,615,615,500,158,490,270,500,500,497,,376,289,333,290,269,490,480,500,500,500,615,615,500,615,500,500,500,500,500,500,500,500,500,500,500,500,500,500,615,372,463,186,500,452,373,500,500,432,186,,,,,59,,51,52,53,,322,,,,309,318,318,443,,,,,,463,452,452,373,352,500,500,615,615,500,500,452,418,452,452,452,452,452,500,500,500,500,500,109,110,111,500,432,463,505,505,214,462,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,186, +,203,204,204,204,421,494,422,421,210,422,204,204,205,223,223,223,230,452,373,615,615,432,452,413,413,452,452,453,615,615,615,500,500,465,465,465,465,465,465,615,615,500,500,615,158,490,270,289,333,290,500,250,500,497,500,500,500,500,500,615,615,500,615,615,615,615,500,500,500,500,500,500,500,500,500,500,500,615,500,463,186,500,453,500,500,352,452,186,,,,,59,,71,72,73,,59,,,,463,500,500,495,318,443,,,,463,432,453,500,500,615,615,615,615,500,500,452,452,452,452,452,452,418,500,500,500,500,440,175,187,175,500,453,203,215,357,186,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,186, +,229,223,223,223,223,223,223,223,210,223,223,223,230,352,412,452,413,373,500,615,615,432,453,615,615,432,452,373,615,615,615,500,500,465,465,465,465,465,465,615,615,615,615,500,615,615,158,490,490,490,490,490,490,480,500,500,500,500,500,615,615,500,353,464,321,464,615,500,615,615,500,500,500,500,500,500,615,500,352,463,186,500,453,214,421,210,422,205,,,,322,59,,,,,,59,,,,463,500,500,500,500,186,,,,463,418,453,500,500,615,615,615,615,500,500,452,452,452,452,418,452,452,500,500,500,485,485,485,485,500,432,68,217,463,357,186,505,505,505,505,505,505,505,505,505,505,505,505,155,204,215,505,186, +,463,452,373,500,500,500,500,500,500,352,412,452,413,418,452,453,500,500,500,615,615,372,418,615,615,432,453,500,500,615,615,500,500,500,465,465,465,465,465,615,615,615,500,500,401,401,401,401,500,615,615,500,500,500,500,500,500,500,615,615,615,615,500,353,500,500,372,392,353,615,615,615,615,500,615,615,352,392,373,203,205,452,453,186,223,210,223,230,,,,,,59,,,,322,59,,,,461,215,500,500,500,186,,,,463,500,452,353,500,500,500,615,615,500,500,500,452,452,418,413,413,500,500,452,453,485,500,500,500,500,373,615,615,463,357,495,318,443,505,505,505,505,309,443,505,505,505,505,505,505,463,357,186, +,463,373,500,155,215,500,500,352,412,452,452,373,500,500,372,373,500,500,500,615,615,500,372,412,412,413,452,353,500,500,465,465,465,465,465,465,465,465,500,615,615,500,500,500,401,401,401,401,500,500,500,500,500,500,500,500,500,500,615,615,615,615,500,500,500,500,615,615,372,392,413,353,500,500,500,352,373,615,615,217,230,372,452,186,,,,,,,,322,322,322,59,322,59,59,,,,,,463,500,500,352,186,,,,463,500,452,418,412,452,453,214,204,204,204,215,500,500,500,500,500,500,500,500,500,485,500,500,413,373,500,615,615,463,357,357,357,186,505,505,505,505,463,186,505,505,505,505,505,358,463,357,186, +,463,500,500,500,203,421,460,422,204,204,204,204,204,204,421,460,422,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,215,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,372,186,,,,,,,,,,,,,,,,,,,,463,352,412,416,186,,,,463,500,452,452,452,452,452,186,,,,463,453,615,615,615,615,615,615,615,615,485,615,615,500,615,615,615,615,463,357,357,357,186,505,309,318,318,255,495,318,318,318,318,318,318,255,357,186, +,463,357,357,357,217,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,463,615,615,615,615,615,615,214,462,615,615,615,615,615,615,615,615,615,615,615,615,615,615,500,186,,,,,,,,,,,,,,,,,,,,463,417,413,373,186,,,,463,452,452,452,452,452,418,186,,,,463,453,615,615,615,615,615,615,615,615,418,615,615,500,615,615,615,615,463,357,357,357,186,505,461,204,204,204,204,204,204,204,204,204,204,215,357,186, +,463,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,505,505,505,505,505,505,505,505,505,505,505,505,505,203,204,204,204,204,204,204,205,500,500,500,500,500,500,500,500,500,400,615,615,352,412,353,500,186,,,,,,,,,,,309,318,318,318,318,318,318,318,443,461,204,204,204,300,,,,463,372,418,452,452,452,373,186,,,,463,393,214,204,204,204,204,204,204,215,373,615,615,500,352,418,309,318,255,357,357,357,186,505,505,505,505,505,505,505,505,505,505,505,505,463,357,186, +,463,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,464,321,464,357,357,357,357,357,357,357,357,357,357,505,505,505,505,505,505,505,505,505,505,505,505,505,217,223,223,223,223,223,223,230,500,500,500,500,500,500,500,500,500,615,615,352,68,452,452,353,495,318,318,318,443,,,,,,322,463,500,400,500,500,352,412,417,186,,322,49,,,,,,463,500,432,452,452,453,500,186,,,,463,432,186,,,,,,,463,500,615,615,352,452,309,255,357,357,357,357,357,186,505,505,505,505,505,505,505,505,505,505,505,505,463,357,186, +,463,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,352,412,412,353,615,615,400,500,500,500,615,615,615,615,615,615,500,615,615,615,372,452,452,452,413,392,413,353,615,186,,,,,,,461,215,500,352,412,452,452,453,495,443,322,49,322,,309,318,318,255,352,413,418,452,452,353,186,,,309,255,453,186,309,318,443,,,,461,210,215,500,432,373,463,357,357,357,214,204,204,205,505,505,505,505,505,505,505,505,505,505,505,505,463,357,186, +,463,357,357,357,357,357,357,357,357,357,357,357,357,214,204,462,357,357,155,204,204,204,204,204,204,204,204,215,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,432,452,452,453,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,500,500,432,413,373,615,615,615,432,353,186,,,,,322,,,463,352,413,418,452,417,373,500,495,443,49,322,309,255,500,352,412,373,500,372,452,418,373,186,,,463,418,453,186,463,401,186,,,,,,463,352,453,309,255,357,357,357,186,223,223,230,505,505,505,505,505,505,505,505,505,505,505,505,463,357,186, +,463,357,357,357,357,357,357,357,357,357,357,357,357,186,505,505,505,505,505,505,505,505,505,505,505,505,505,463,357,357,357,357,357,357,357,357,357,357,357,357,357,357,214,462,505,505,505,505,505,505,505,505,505,505,505,505,155,215,372,413,413,413,353,500,615,615,615,615,500,500,500,372,353,615,615,68,353,401,352,452,357,500,615,615,615,372,452,495,318,318,318,318,318,443,,461,204,215,372,413,373,500,615,615,495,318,318,255,352,412,452,373,615,615,500,372,373,500,186,,,463,452,452,186,461,210,300,,,,,,463,432,452,463,357,357,357,357,186,505,505,505,505,505,358,505,505,505,505,505,505,505,505,505,463,357,186, +,463,357,357,357,357,357,357,357,357,357,357,357,357,186,505,505,505,505,505,505,505,505,505,505,505,505,505,463,357,357,357,357,357,357,357,357,357,357,357,357,357,357,186,505,505,505,505,505,505,309,443,505,505,505,505,505,505,461,204,215,214,204,215,353,500,500,500,500,500,615,615,500,372,392,392,413,413,412,452,452,357,357,357,500,615,500,372,413,452,412,500,500,500,186,,,,461,204,204,215,500,615,615,500,500,372,417,452,413,418,500,615,615,500,500,500,500,186,,,463,432,418,186,,,,,,,,,463,452,418,463,357,357,357,357,186,505,358,505,505,505,505,505,505,505,505,505,505,505,505,505,463,357,186, +,463,357,357,214,204,421,210,422,204,204,204,204,204,205,505,505,505,505,309,318,318,443,505,505,505,505,505,203,215,357,357,214,421,460,460,460,422,204,204,204,204,204,205,505,505,505,505,505,505,463,495,318,318,318,443,505,505,505,505,463,186,223,203,215,412,353,500,500,500,615,615,615,615,615,615,615,615,432,68,452,357,357,357,357,357,357,500,500,372,413,452,500,500,186,,,,322,322,322,463,500,500,615,615,500,500,372,453,615,615,615,615,418,353,500,500,214,300,,,463,432,452,495,318,318,318,318,318,318,318,318,255,418,452,463,357,357,357,357,186,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,463,357,186, +,463,357,357,186,223,223,210,223,223,223,223,223,223,230,505,505,505,505,463,357,357,186,505,505,505,505,505,229,203,204,204,205,223,223,223,223,223,223,223,223,223,223,224,505,505,505,505,505,505,463,357,214,204,204,300,505,505,505,505,463,186,,217,463,452,452,353,500,500,615,615,615,615,615,615,615,615,418,413,373,500,352,353,500,352,392,412,412,353,500,372,413,452,186,,,,322,322,322,463,352,353,615,615,500,500,500,393,615,615,615,615,372,452,353,500,186,,,,463,452,453,615,615,615,615,615,615,615,615,615,615,432,452,463,357,357,357,357,186,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,463,357,186, +,463,357,357,186,505,505,505,505,505,505,505,505,505,505,505,505,505,505,203,204,204,205,505,505,505,505,505,217,229,223,223,224,223,223,223,223,223,223,223,223,223,361,230,505,505,505,505,505,505,463,357,186,505,505,505,505,505,505,505,463,186,,,463,500,500,418,412,353,615,615,615,615,615,615,615,615,373,615,615,214,204,421,210,422,215,372,413,418,353,500,500,372,495,318,318,318,318,318,443,463,372,418,214,204,210,215,352,418,615,615,500,500,500,372,373,500,186,,,,463,418,453,615,615,615,615,615,615,615,615,615,615,418,453,203,421,460,422,204,205,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,463,357,186, +,463,357,357,186,505,505,505,505,505,505,505,505,505,505,505,505,505,505,217,223,223,230,505,505,505,505,505,505,217,223,223,230,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,463,214,205,505,505,505,505,505,505,505,463,186,,,463,500,500,452,500,500,412,353,615,615,615,615,615,615,500,615,615,186,,,,,461,204,215,372,452,412,353,500,401,401,500,500,500,500,186,463,500,372,442,,,470,432,373,615,615,500,500,500,500,500,500,186,,322,309,255,452,453,500,615,615,418,500,352,353,500,500,352,452,452,217,223,223,223,223,230,505,345,505,505,345,505,505,505,505,505,505,505,309,318,318,255,357,186, +,203,215,357,186,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,508,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,463,186,230,505,505,505,505,505,505,505,463,186,,,463,175,187,175,500,452,452,453,500,500,401,401,401,500,500,214,204,300,,309,318,318,443,,463,500,372,452,453,401,401,401,500,500,500,500,186,463,500,500,409,,,97,393,500,500,500,500,500,500,500,500,352,186,,322,463,432,452,418,500,500,615,615,500,432,418,353,500,432,452,452,418,373,500,352,505,505,505,365,505,505,365,505,505,505,505,505,505,505,463,500,615,357,357,186, +,217,463,357,186,505,505,505,505,505,505,505,505,505,505,508,505,505,505,505,309,318,443,505,505,508,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,463,186,505,505,505,505,505,505,505,505,463,186,,,203,215,500,500,500,372,418,452,353,615,615,615,615,615,615,186,,322,,463,500,500,186,,463,353,500,372,373,401,401,500,500,500,400,500,186,461,215,353,409,,,97,418,500,500,500,500,500,352,353,214,204,300,322,322,463,418,452,373,500,500,615,615,352,452,452,452,412,418,452,413,373,500,352,418,505,505,505,505,505,505,505,505,505,505,505,505,505,505,463,500,357,214,204,205, +,,203,204,205,,,,,,,,,,,,,,,,463,357,186,,,,,,,,,,,,,,,,,,,,,,,,,,,,463,186,,,,,,,,,203,205,,,217,203,204,215,353,500,372,452,373,615,615,615,615,615,615,186,,322,,461,210,204,300,,463,413,412,353,500,401,401,500,500,500,500,500,186,,463,418,507,,,506,372,353,500,500,500,352,453,214,300,,322,,,461,215,418,500,500,500,352,412,418,452,452,452,452,452,373,214,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,203,204,204,205,223,230, +,,217,223,230,,,,,,,,,,,,,,,,203,204,205,,,,,,,,,,,,,,,,,,,,,,,,,,,,461,300,,,,,,,,,229,224,,,,217,223,203,204,204,204,204,204,204,204,204,204,204,204,205,,322,,,,322,,,203,215,418,413,353,401,401,401,500,500,500,214,300,,461,204,300,,322,461,204,204,204,204,204,204,204,300,,,,,,,461,215,500,352,412,418,452,413,452,413,452,418,373,214,300,,,,,,,,,,,,,,,,,,,217,223,223,230,,, +,,,,,,,,,,,,,,,,,,,,217,223,230,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,217,230,,,,,,217,223,223,223,223,223,223,223,223,223,223,223,230,,,322,322,322,,,,217,203,204,204,204,204,204,204,204,204,204,205,,,,,322,322,,,,,,,,,,,,,,,,,,461,204,204,204,204,204,204,204,204,204,204,204,300,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,217,223,223,223,223,223,223,223,223,223,230,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,206,,,,,,,,,,,,,,,,,,,,,,,,,,,,199,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,199,,,,,,,,,,,,,,,,,,,226,,,,,,,,,,,,,,,,,199,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,199,199,199,199,199,199,199,199,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,199,,,,,199,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,206,,,,206,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,199,,,199,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,226,,,,226,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,216,216,216,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,256,256,256,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,216,216,216,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,603,604,604,604,605,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,103,104,104,104,105,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,256,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,501,501,501,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,256,256,256,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,159,159,159,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,51,52,53,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,256,256,256,,,,,,,,,,,,,,,,,,,,,,,,,,,,,71,72,73,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,502,502,502,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,591,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,334,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,334,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,334,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,590,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,502,502,502,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +524 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +waterfallSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +16512 +211;384;320 +211;384;336 +211;384;400 +211;384;416 +211;400;288 +211;400;304 +211;400;320 +211;400;416 +211;416;448 +211;432;288 +211;432;448 +211;448;464 +211;512;288 +211;512;304 +211;512;480 +211;528;288 +211;528;480 +211;608;480 +211;624;480 +211;672;480 +211;688;464 +211;736;400 +211;896;400 +60;1968;1088;;;;;; +60;2000;1088;;;;;; +60;2176;1184;;;;;; +59;2000;1472;;;;;; +59;2144;1328;;;;;; +59;2160;1440;;;;;; +59;2208;1328;;;;;; +59;2288;1328;;;;;; +59;2288;1360;;;;;; +59;2320;1472;;;;;; +59;2352;1424;;;;;; +59;2384;1328;;;;;; +59;2384;1360;;;;;; +59;2432;1328;;;;;; +59;2432;1360;;;;;; +59;2464;1456;;;;;; +59;2496;1328;;;;;; +59;2496;1360;;;;;; +59;2496;1488;;;;;; +403;80;1472;villageAttacked +402;80;1472;!villageAttacked +386;224;1408 +386;240;1216 +386;384;1360 +386;448;1440 +386;528;1184 +383;244;1348;pole +238;1840;912 +213;80;1312;item:j..heart.;;;;;; +213;96;1312;item:j..heart.;;;;;; +213;96;1888;;;;;;; +213;112;1184;;;;;;; +213;112;1312;item:j..heart.;;;;;; +213;128;1888;;;;;;; +213;144;1328;;;;;;; +213;144;1472;;;;;;; +213;144;1488;;;;;;; +213;144;1888;;;;;;; +213;192;1888;;;;;;; +213;208;336;;;;;;; +213;208;1600;;;;;;; +213;208;1760;;;;;;; +213;208;1888;;;;;;; +213;224;1600;;;;;;; +213;224;1760;;;;;;; +213;240;304;;;;;;; +213;240;1600;;;;;;; +213;256;304;;;;;;; +213;256;1808;;;;;;; +213;272;1568;;;;;;; +213;272;1744;;;;;;; +213;272;1808;;;;;;; +213;288;336;;;;;;; +213;288;1568;;;;;;; +213;288;1744;;;;;;; +213;288;1808;;;;;;; +213;304;1744;;;;;;; +213;352;1056;;;;;;; +213;352;1072;;;;;;; +213;352;1088;;;;;;; +213;368;1088;;;;;;; +213;384;1104;;;;;;; +213;384;1120;;;;;;; +213;400;1120;;;;;;; +213;416;1120;;;;;;; +213;432;1120;;;;;;; +213;528;1200;;;;;;; +213;528;1216;;;;;;; +213;528;1232;;;;;;; +213;528;1312;;;;;;; +213;528;1328;;;;;;; +213;528;1344;;;;;;; +213;528;1360;;;;;;; +213;528;1376;;;;;;; +213;528;1832;;;;;;; +213;528;1848;;;;;;; +213;528;1864;;;;;;; +213;544;1184;;;;;;; +213;544;1312;;;;;;; +213;544;1328;;;;;;; +213;544;1344;;;;;;; +213;544;1360;;;;;;; +213;544;1376;;;;;;; +213;544;1440;;;;;;; +213;544;1456;;;;;;; +213;544;1472;;;;;;; +213;544;1488;;;;;;; +213;560;1184;;;;;;; +213;560;1312;;;;;;; +213;560;1328;;;;;;; +213;560;1344;;;;;;; +213;560;1360;;;;;;; +213;560;1376;;;;;;; +213;560;1424;;;;;;; +213;560;1504;;;;;;; +213;560;1584;;;;;;; +213;576;1184;;;;;;; +213;576;1312;;;;;;; +213;576;1328;item:j.shell_1.shell..true;;;;;; +213;576;1344;;;;;;; +213;576;1360;;;;;;; +213;576;1376;;;;;;; +213;576;1424;;;;;;; +213;576;1504;;;;;;; +213;592;1200;;;;;;; +213;592;1216;;;;;;; +213;592;1232;;;;;;; +213;592;1312;;;;;;; +213;592;1328;;;;;;; +213;592;1344;;;;;;; +213;592;1360;;;;;;; +213;592;1376;;;;;;; +213;592;1424;;;;;;; +213;592;1616;;;;;;; +213;608;1312;;;;;;; +213;608;1328;;;;;;; +213;608;1344;;;;;;; +213;608;1360;;;;;;; +213;608;1376;;;;;;; +213;608;1440;;;;;;; +213;608;1456;;;;;;; +213;608;1472;;;;;;; +213;608;1488;;;;;;; +213;624;1584;;;;;;; +213;688;1056;;;;;;; +213;688;1216;;;;;;; +213;688;1840;;;;;;; +213;688;1856;;;;;;; +213;704;1056;;;;;;; +213;704;1200;;;;;;; +213;704;1216;;;;;;; +213;704;1728;visiblehole;;;;;; +213;720;1056;;;;;;; +213;720;1168;;;;;;; +213;720;1184;;;;;;; +213;720;1200;;;;;;; +213;736;1072;;;;;;; +213;736;1088;;;;;;; +213;736;1696;visiblehole;;;;;; +213;752;944;;;;;;; +213;784;1760;visiblehole;;;;;; +213;848;1184;;;;;;; +213;944;1168;;;;;;; +213;1024;1632;;;;;;; +213;1024;1648;visiblehole;;;;;; +213;1024;1664;visiblehole;;;;;; +213;1024;1680;visiblehole;;;;;; +213;1024;1696;visiblehole;;;;;; +213;1040;1616;visiblehole;;;;;; +213;1040;1632;;;;;;; +213;1040;1648;visiblehole;;;;;; +213;1040;1664;visiblehole;;;;;; +213;1040;1680;;;;;;; +213;1040;1696;visiblehole;;;;;; +213;1056;1040;;;;;;; +213;1056;1616;visiblehole;;;;;; +213;1056;1632;;;;;;; +213;1056;1648;visiblehole;;;;;; +213;1056;1664;visiblehole;;;;;; +213;1056;1680;;;;;;; +213;1056;1696;visiblehole;;;;;; +213;1056;1760;visiblehole;;;;;; +213;1072;1040;;;;;;; +213;1072;1344;item:j.shell_19.shell..true;;;;;; +213;1072;1616;visiblehole;;;;;; +213;1072;1632;;;;;;; +213;1072;1680;;;;;;; +213;1072;1696;;;;;;; +213;1072;1712;;;;;;; +213;1088;1040;;;;;;; +213;1088;1200;;;;;;; +213;1088;1568;;;;;;; +213;1088;1616;visiblehole;;;;;; +213;1088;1632;;;;;;; +213;1088;1648;visiblehole;;;;;; +213;1088;1664;visiblehole;;;;;; +213;1088;1680;;;;;;; +213;1088;1696;visiblehole;;;;;; +213;1088;1712;;;;;;; +213;1104;1616;visiblehole;;;;;; +213;1104;1632;;;;;;; +213;1104;1648;visiblehole;;;;;; +213;1104;1664;visiblehole;;;;;; +213;1104;1680;;;;;;; +213;1104;1696;visiblehole;;;;;; +213;1104;1712;;;;;;; +213;1120;1616;visiblehole;;;;;; +213;1120;1648;visiblehole;;;;;; +213;1120;1664;visiblehole;;;;;; +213;1120;1696;visiblehole;;;;;; +213;1136;1552;visiblehole;;;;;; +213;1136;1584;visiblehole;;;;;; +213;1136;1600;visiblehole;;;;;; +213;1136;1616;visiblehole;;;;;; +213;1136;1648;visiblehole;;;;;; +213;1136;1664;visiblehole;;;;;; +213;1136;1696;visiblehole;;;;;; +213;1136;1728;visiblehole;;;;;; +213;1152;1552;;;;;;; +213;1152;1568;;;;;;; +213;1152;1584;;;;;;; +213;1152;1600;visiblehole;;;;;; +213;1152;1616;visiblehole;;;;;; +213;1152;1632;;;;;;; +213;1152;1680;;;;;;; +213;1152;1696;visiblehole;;;;;; +213;1152;1712;;;;;;; +213;1152;1728;;;;;;; +213;1168;1552;visiblehole;;;;;; +213;1168;1568;visiblehole;;;;;; +213;1168;1584;;;;;;; +213;1168;1600;visiblehole;;;;;; +213;1168;1616;;;;;;; +213;1168;1632;visiblehole;;;;;; +213;1168;1648;visiblehole;;;;;; +213;1168;1664;visiblehole;;;;;; +213;1168;1680;;;;;;; +213;1168;1696;;;;;;; +213;1168;1712;visiblehole;;;;;; +213;1168;1728;;;;;;; +213;1184;1552;visiblehole;;;;;; +213;1184;1568;visiblehole;;;;;; +213;1184;1584;;;;;;; +213;1184;1600;visiblehole;;;;;; +213;1184;1616;;;;;;; +213;1184;1632;visiblehole;;;;;; +213;1184;1648;visiblehole;;;;;; +213;1184;1664;visiblehole;;;;;; +213;1184;1680;visiblehole;;;;;; +213;1184;1696;;;;;;; +213;1184;1712;visiblehole;;;;;; +213;1184;1728;;;;;;; +213;1200;336;;;;;;; +213;1200;1520;visiblehole;;;;;; +213;1200;1536;visiblehole;;;;;; +213;1200;1552;;;;;;; +213;1200;1568;;;;;;; +213;1200;1584;;;;;;; +213;1200;1600;visiblehole;;;;;; +213;1200;1616;;;;;;; +213;1200;1632;;;;;;; +213;1200;1680;;;;;;; +213;1200;1696;;;;;;; +213;1200;1712;visiblehole;;;;;; +213;1200;1728;;;;;;; +213;1216;336;;;;;;; +213;1216;352;;;;;;; +213;1216;1520;visiblehole;;;;;; +213;1216;1536;visiblehole;;;;;; +213;1216;1552;;;;;;; +213;1216;1568;visiblehole;;;;;; +213;1216;1584;;;;;;; +213;1216;1600;visiblehole;;;;;; +213;1216;1616;visiblehole;;;;;; +213;1216;1632;visiblehole;;;;;; +213;1216;1648;visiblehole;;;;;; +213;1216;1664;visiblehole;;;;;; +213;1216;1680;visiblehole;;;;;; +213;1216;1696;visiblehole;;;;;; +213;1216;1712;;;;;;; +213;1216;1728;;;;;;; +213;1232;1536;visiblehole;;;;;; +213;1232;1552;;;;;;; +213;1232;1568;;;;;;; +213;1232;1584;;;;;;; +213;1232;1600;;;;;;; +213;1232;1616;;;;;;; +213;1232;1632;;;;;;; +213;1232;1680;;;;;;; +213;1232;1696;;;;;;; +213;1232;1712;;;;;;; +213;1248;1040;;;;;;; +213;1264;1056;;;;;;; +213;1264;1072;;;;;;; +213;1360;1984;item:j.shell_18.shell;;;;;; +213;1472;1088;;;;;;; +213;1472;1120;;;;;;; +213;1488;800;;;;;;; +213;1488;816;;;;;;; +213;1488;832;;;;;;; +213;1488;1040;;;;;;; +213;1488;1056;;;;;;; +213;1488;1072;;;;;;; +213;1488;1168;;;;;;; +213;1488;1200;;;;;;; +213;1488;1232;;;;;;; +213;1488;1888;item:j.shell_13.shell..true;;;;;; +213;1504;1088;;;;;;; +213;1504;1120;;;;;;; +213;1520;832;;;;;;; +213;1520;848;;;;;;; +213;1520;864;;;;;;; +213;1520;1040;;;;;;; +213;1520;1984;;;;;;; +213;1520;2000;;;;;;; +213;1536;1120;;;;;;; +213;1536;1184;;;;;;; +213;1536;1216;;;;;;; +213;1536;1952;;;;;;; +213;1536;1968;;;;;;; +213;1536;1984;;;;;;; +213;1536;2000;;;;;;; +213;1536;2016;;;;;;; +213;1552;832;;;;;;; +213;1552;848;;;;;;; +213;1552;864;;;;;;; +213;1552;1168;;;;;;; +213;1552;1200;;;;;;; +213;1552;1952;;;;;;; +213;1552;1968;;;;;;; +213;1552;1984;;;;;;; +213;1552;2000;;;;;;; +213;1552;2016;;;;;;; +213;1568;1040;;;;;;; +213;1568;1056;;;;;;; +213;1568;1120;;;;;;; +213;1568;1952;;;;;;; +213;1568;1968;;;;;;; +213;1568;2000;;;;;;; +213;1568;2016;;;;;;; +213;1584;800;;;;;;; +213;1584;816;;;;;;; +213;1584;832;;;;;;; +213;1584;1168;;;;;;; +213;1584;1200;;;;;;; +213;1584;1952;;;;;;; +213;1584;1968;;;;;;; +213;1584;1984;;;;;;; +213;1584;2000;;;;;;; +213;1792;1120;;;;;;; +213;1808;848;;;;;;; +213;1808;864;;;;;;; +213;1808;1120;;;;;;; +213;1824;864;;;;;;; +213;1824;1088;;;;;;; +213;1824;1104;;;;;;; +213;1824;1120;;;;;;; +213;1824;1568;;;;;;; +213;1824;1616;;;;;;; +213;1840;1088;item:j.shell_7.shell..true;;;;;; +213;1840;1104;;;;;;; +213;1840;1120;;;;;;; +213;1840;1504;;;;;;; +213;1872;832;;;;;;; +213;1872;1568;;;;;;; +213;1872;1616;;;;;;; +213;1904;1456;;;;;;; +213;1904;1488;;;;;;; +213;1984;2000;;;;;;; +213;1984;2016;;;;;;; +213;2000;1952;;;;;;; +213;2000;1984;;;;;;; +213;2000;2000;;;;;;; +213;2016;1968;;;;;;; +213;2016;1984;;;;;;; +213;2016;2000;;;;;;; +213;2128;1696;;;;;;; +213;2128;1712;;;;;;; +213;2144;1696;;;;;;; +213;2288;1248;;;;;;; +213;2304;1120;;;;;;; +213;2320;1120;;;;;;; +213;2320;1168;;;;;;; +213;2336;1248;;;;;;; +213;2352;1200;;;;;;; +213;2368;1200;;;;;;; +213;2432;1168;;;;;;; +213;2432;1184;;;;;;; +213;2432;1200;;;;;;; +213;2544;1952;;;;;;; +213;2544;1968;;;;;;; +214;64;592;;;;;;; +214;64;672;;;;;;; +214;64;688;;;;;;; +214;64;704;;;;;;; +214;80;592;;;;;;; +214;96;592;;;;;;; +214;208;688;;;;;;; +214;208;704;;;;;;; +214;224;560;;;;;;; +214;224;672;;;;;;; +214;224;720;;;;;;; +214;240;576;;;;;;; +214;240;672;;;;;;; +214;240;720;;;;;;; +214;256;560;;;;;;; +214;256;688;;;;;;; +214;256;704;;;;;;; +214;272;816;;;;;;; +214;368;976;;;;;;; +214;384;976;;;;;;; +214;400;976;;;;;;; +214;416;976;;;;;;; +214;432;976;;;;;;; +214;448;960;;;;;;; +214;448;976;;;;;;; +214;528;816;;;;;;; +214;528;832;;;;;;; +214;544;800;;;;;;; +214;544;848;;;;;;; +214;560;800;;;;;;; +214;560;848;;;;;;; +214;560;944;;;;;;; +214;576;816;;;;;;; +214;576;832;;;;;;; +393;48;1360 +393;64;1296 +393;96;1424 +393;112;1312 +393;128;1424 +393;208;1200 +393;224;1312 +393;272;1184 +393;304;1360 +393;352;1168 +393;368;1072 +393;384;1184 +393;384;1440 +393;416;1104 +393;432;1056 +393;448;1168 +393;528;1056 +393;528;1328 +393;544;1296 +393;544;1456 +393;592;1104 +393;592;1216 +393;592;1440 +393;608;1360 +393;608;1472 +393;672;1088 +393;704;1056 +393;1808;1568 +393;1840;1616 +393;1888;1584 +393;1968;1568 +393;1984;1600 +393;2064;1616 +393;2064;1712 +393;2128;1632 +393;2144;1712 +393;2160;1616 +393;2208;1728 +393;2224;1680 +0;16;272;;; +0;16;288;;; +0;16;304;;; +0;16;416;;; +0;16;432;;; +0;16;448;;; +0;16;464;;; +0;16;480;;; +0;16;1568;;; +0;16;1584;;; +0;16;1600;;; +0;16;1616;;; +0;16;1632;;; +0;16;1648;;; +0;16;1664;;; +0;16;1680;;; +0;16;1696;;; +0;16;1712;;; +0;16;1728;;; +0;16;1744;;; +0;16;1760;;; +0;16;1776;;; +0;16;1792;;; +0;16;1808;;; +0;16;1824;;; +0;16;1840;;; +0;16;1856;;; +0;16;1872;;; +0;16;1888;;; +0;16;1904;;; +0;16;1920;;; +0;16;1936;;; +0;16;1952;;; +0;16;1968;;; +0;16;1984;;; +0;16;2000;;; +0;16;2016;;; +0;16;2032;;; +0;32;144;;; +0;32;160;;; +0;32;176;;; +0;32;192;;; +0;32;208;;; +0;32;272;;; +0;32;304;;; +0;32;320;;; +0;32;336;;; +0;32;352;;; +0;32;368;;; +0;32;384;;; +0;32;400;;; +0;32;416;;; +0;32;592;;; +0;32;608;;; +0;32;624;;; +0;32;640;;; +0;32;656;;; +0;32;672;;; +0;32;688;;; +0;32;704;;; +0;32;1328;;; +0;32;1344;;; +0;32;1360;;; +0;32;1376;;; +0;32;1392;;; +0;32;1408;;; +0;32;1424;;; +0;32;1440;;; +0;32;1456;;; +0;32;1472;;; +0;32;1488;;; +0;32;1504;;; +0;32;1520;;; +0;32;1536;;; +0;32;1552;;; +0;32;1568;;; +0;32;1648;;; +0;32;1664;;; +0;32;1712;;; +0;32;1728;;; +0;32;1968;;; +0;32;1984;;; +0;32;2000;;; +0;32;2016;;; +0;32;2032;;; +0;48;80;;; +0;48;96;;; +0;48;112;;; +0;48;128;;; +0;48;160;;; +0;48;224;;; +0;48;272;;; +0;48;576;;; +0;48;720;;; +0;48;992;;; +0;48;1312;;; +0;48;1424;;; +0;48;1440;;; +0;48;1568;;; +0;48;1648;;; +0;48;1664;;; +0;48;1712;;; +0;48;1728;;; +0;48;2000;;; +0;48;2016;;; +0;48;2032;;; +0;64;32;;; +0;64;64;;; +0;64;112;;; +0;64;128;;; +0;64;144;;; +0;64;224;;; +0;64;272;;; +0;64;512;;; +0;64;528;;; +0;64;544;;; +0;64;576;;; +0;64;720;;; +0;64;736;;; +0;64;864;;; +0;64;880;;; +0;64;896;;; +0;64;912;;; +0;64;976;;; +0;64;1312;;; +0;64;1328;;; +0;64;1344;;; +0;64;1424;;; +0;64;1568;;; +0;64;1584;;; +0;64;1600;;; +0;64;1648;;; +0;64;1664;;; +0;64;1712;;; +0;64;1728;;; +0;64;1760;;; +0;64;1904;;; +0;64;1920;;; +0;64;1936;;; +0;64;1952;;; +0;64;1968;;; +0;64;1984;;; +0;64;2000;;; +0;64;2016;;; +0;64;2032;;; +0;80;16;;; +0;80;48;;; +0;80;112;;; +0;80;128;;; +0;80;224;;; +0;80;272;;; +0;80;560;;; +0;80;576;;; +0;80;752;;; +0;80;768;;; +0;80;784;;; +0;80;800;;; +0;80;816;;; +0;80;832;;; +0;80;848;;; +0;80;928;;; +0;80;944;;; +0;80;960;;; +0;80;976;;; +0;80;1328;;; +0;80;1344;;; +0;80;1424;;; +0;80;1440;;; +0;80;1584;;; +0;80;1600;;; +0;80;1712;;; +0;80;1728;;; +0;80;1760;;; +0;80;1776;;; +0;80;1792;;; +0;80;1904;;; +0;80;1920;;; +0;80;2016;;; +0;80;2032;;; +0;96;16;;; +0;96;112;;; +0;96;224;;; +0;96;272;;; +0;96;560;;; +0;96;576;;; +0;96;752;;; +0;96;768;;; +0;96;1360;;; +0;96;1584;;; +0;96;1600;;; +0;96;1648;;; +0;96;1664;;; +0;96;1776;;; +0;96;1792;;; +0;96;1904;;; +0;96;1920;;; +0;96;2016;;; +0;96;2032;;; +0;112;16;;; +0;112;48;;; +0;112;64;;; +0;112;112;;; +0;112;128;;; +0;112;224;;; +0;112;288;;; +0;112;400;;; +0;112;416;;; +0;112;624;;; +0;112;640;;; +0;112;656;;; +0;112;672;;; +0;112;752;;; +0;112;768;;; +0;112;1328;;; +0;112;1344;;; +0;112;1648;;; +0;112;1664;;; +0;112;1712;;; +0;112;1728;;; +0;112;2016;;; +0;112;2032;;; +0;128;32;;; +0;128;64;;; +0;128;112;;; +0;128;128;;; +0;128;144;;; +0;128;224;;; +0;128;288;;; +0;128;400;;; +0;128;560;;; +0;128;576;;; +0;128;624;;; +0;128;640;;; +0;128;656;;; +0;128;672;;; +0;128;752;;; +0;128;768;;; +0;128;1312;;; +0;128;1328;;; +0;128;1344;;; +0;128;1584;;; +0;128;1600;;; +0;128;1648;;; +0;128;1664;;; +0;128;1712;;; +0;128;1728;;; +0;128;1776;;; +0;128;1792;;; +0;128;1904;;; +0;128;1920;;; +0;128;2016;;; +0;128;2032;;; +0;144;64;;; +0;144;96;;; +0;144;112;;; +0;144;128;;; +0;144;160;;; +0;144;224;;; +0;144;400;;; +0;144;416;;; +0;144;512;;; +0;144;528;;; +0;144;560;;; +0;144;576;;; +0;144;624;;; +0;144;640;;; +0;144;656;;; +0;144;752;;; +0;144;768;;; +0;144;816;;; +0;144;832;;; +0;144;848;;; +0;144;864;;; +0;144;1312;;; +0;144;1568;;; +0;144;1584;;; +0;144;1600;;; +0;144;1632;;; +0;144;1648;;; +0;144;1664;;; +0;144;1776;;; +0;144;1792;;; +0;144;1904;;; +0;144;1920;;; +0;144;2016;;; +0;144;2032;;; +0;160;64;;; +0;160;96;;; +0;160;128;;; +0;160;192;;; +0;160;208;;; +0;160;288;;; +0;160;320;;; +0;160;336;;; +0;160;352;;; +0;160;368;;; +0;160;384;;; +0;160;400;;; +0;160;416;;; +0;160;432;;; +0;160;448;;; +0;160;528;;; +0;160;560;;; +0;160;576;;; +0;160;624;;; +0;160;640;;; +0;160;656;;; +0;160;672;;; +0;160;688;;; +0;160;704;;; +0;160;720;;; +0;160;736;;; +0;160;752;;; +0;160;768;;; +0;160;816;;; +0;160;864;;; +0;160;1568;;; +0;160;1632;;; +0;160;1712;;; +0;160;1728;;; +0;160;1776;;; +0;160;1792;;; +0;160;1904;;; +0;160;1920;;; +0;160;2016;;; +0;160;2032;;; +0;176;64;;; +0;176;96;;; +0;176;128;;; +0;176;192;;; +0;176;208;;; +0;176;224;;; +0;176;288;;; +0;176;320;;; +0;176;336;;; +0;176;352;;; +0;176;368;;; +0;176;384;;; +0;176;400;;; +0;176;416;;; +0;176;432;;; +0;176;448;;; +0;176;528;;; +0;176;560;;; +0;176;576;;; +0;176;624;;; +0;176;640;;; +0;176;656;;; +0;176;672;;; +0;176;688;;; +0;176;704;;; +0;176;720;;; +0;176;736;;; +0;176;752;;; +0;176;768;;; +0;176;816;;; +0;176;864;;; +0;176;1568;;; +0;176;1632;;; +0;176;1712;;; +0;176;1728;;; +0;176;1776;;; +0;176;1792;;; +0;176;1904;;; +0;176;1920;;; +0;176;2016;;; +0;176;2032;;; +0;192;64;;; +0;192;96;;; +0;192;128;;; +0;192;192;;; +0;192;208;;; +0;192;272;;; +0;192;528;;; +0;192;560;;; +0;192;576;;; +0;192;592;;; +0;192;608;;; +0;192;624;;; +0;192;640;;; +0;192;656;;; +0;192;752;;; +0;192;768;;; +0;192;816;;; +0;192;864;;; +0;192;1104;;; +0;192;1440;;; +0;192;1456;;; +0;192;1568;;; +0;192;1712;;; +0;192;1728;;; +0;192;1776;;; +0;192;1792;;; +0;192;1904;;; +0;192;1920;;; +0;192;2016;;; +0;192;2032;;; +0;208;64;;; +0;208;96;;; +0;208;128;;; +0;208;192;;; +0;208;208;;; +0;208;224;;; +0;208;272;;; +0;208;288;;; +0;208;528;;; +0;208;560;;; +0;208;576;;; +0;208;592;;; +0;208;608;;; +0;208;624;;; +0;208;640;;; +0;208;752;;; +0;208;768;;; +0;208;816;;; +0;208;864;;; +0;208;1104;;; +0;208;1300;;; +0;208;1312;;; +0;208;1328;;; +0;208;1440;;; +0;208;1568;;; +0;208;1696;;; +0;208;1712;;; +0;208;1728;;; +0;208;1776;;; +0;208;1792;;; +0;208;1904;;; +0;208;1920;;; +0;208;2016;;; +0;208;2032;;; +0;224;64;;; +0;224;96;;; +0;224;112;;; +0;224;128;;; +0;224;208;;; +0;224;224;;; +0;224;528;;; +0;224;816;;; +0;224;832;;; +0;224;848;;; +0;224;864;;; +0;224;1104;;; +0;224;1300;;; +0;224;1312;;; +0;224;1440;;; +0;224;1456;;; +0;224;1472;;; +0;224;1488;;; +0;224;1568;;; +0;224;1696;;; +0;224;1712;;; +0;224;1776;;; +0;224;1792;;; +0;224;1856;;; +0;224;1872;;; +0;224;1888;;; +0;224;1904;;; +0;224;1920;;; +0;224;2016;;; +0;224;2032;;; +0;240;64;;; +0;240;112;;; +0;240;128;;; +0;240;272;;; +0;240;288;;; +0;240;528;;; +0;240;1104;;; +0;240;1300;;; +0;240;1312;;; +0;240;1328;;; +0;240;1440;;; +0;240;1456;;; +0;240;1472;;; +0;240;1776;;; +0;240;1792;;; +0;240;1856;;; +0;240;2016;;; +0;240;2032;;; +0;256;64;;; +0;256;80;;; +0;256;112;;; +0;256;128;;; +0;256;144;;; +0;256;154;;; +0;256;208;;; +0;256;224;;; +0;256;240;;; +0;256;256;;; +0;256;272;;; +0;256;288;;; +0;256;448;;; +0;256;528;;; +0;256;1072;;; +0;256;1088;;; +0;256;1104;;; +0;256;1312;;; +0;256;1440;;; +0;256;1456;;; +0;256;1472;;; +0;256;1488;;; +0;256;1696;;; +0;256;1712;;; +0;256;1856;;; +0;256;2016;;; +0;256;2032;;; +0;272;48;;; +0;272;112;;; +0;272;128;;; +0;272;192;;; +0;272;208;;; +0;272;224;;; +0;272;240;;; +0;272;256;;; +0;272;272;;; +0;272;544;;; +0;272;560;;; +0;272;1056;;; +0;272;1440;;; +0;272;1616;;; +0;272;1632;;; +0;272;1648;;; +0;272;1664;;; +0;272;1680;;; +0;272;1696;;; +0;272;1712;;; +0;272;1776;;; +0;272;1792;;; +0;272;2016;;; +0;272;2032;;; +0;288;64;;; +0;288;80;;; +0;288;112;;; +0;288;128;;; +0;288;144;;; +0;288;154;;; +0;288;192;;; +0;288;208;;; +0;288;448;;; +0;288;544;;; +0;288;560;;; +0;288;608;;; +0;288;624;;; +0;288;640;;; +0;288;656;;; +0;288;736;;; +0;288;752;;; +0;288;768;;; +0;288;784;;; +0;288;800;;; +0;288;816;;; +0;288;832;;; +0;288;864;;; +0;288;880;;; +0;288;896;;; +0;288;912;;; +0;288;928;;; +0;288;1056;;; +0;288;1440;;; +0;288;1456;;; +0;288;1616;;; +0;288;1776;;; +0;288;1792;;; +0;288;2016;;; +0;288;2032;;; +0;304;64;;; +0;304;112;;; +0;304;128;;; +0;304;192;;; +0;304;208;;; +0;304;240;;; +0;304;256;;; +0;304;272;;; +0;304;528;;; +0;304;592;;; +0;304;640;;; +0;304;656;;; +0;304;672;;; +0;304;688;;; +0;304;704;;; +0;304;720;;; +0;304;736;;; +0;304;752;;; +0;304;832;;; +0;304;864;;; +0;304;1776;;; +0;304;1792;;; +0;304;1856;;; +0;304;1904;;; +0;304;1920;;; +0;304;1936;;; +0;304;1952;;; +0;304;2016;;; +0;304;2032;;; +0;320;64;;; +0;320;112;;; +0;320;128;;; +0;320;192;;; +0;320;208;;; +0;320;240;;; +0;320;272;;; +0;320;288;;; +0;320;304;;; +0;320;320;;; +0;320;336;;; +0;320;352;;; +0;320;368;;; +0;320;384;;; +0;320;400;;; +0;320;416;;; +0;320;432;;; +0;320;528;;; +0;320;592;;; +0;320;832;;; +0;320;864;;; +0;320;1776;;; +0;320;1792;;; +0;320;1856;;; +0;320;1904;;; +0;320;1920;;; +0;320;1936;;; +0;320;1952;;; +0;320;1984;;; +0;320;2000;;; +0;320;2016;;; +0;320;2032;;; +0;336;64;;; +0;336;112;;; +0;336;128;;; +0;336;192;;; +0;336;208;;; +0;336;240;;; +0;336;272;;; +0;336;288;;; +0;336;304;;; +0;336;320;;; +0;336;336;;; +0;336;352;;; +0;336;368;;; +0;336;384;;; +0;336;400;;; +0;336;416;;; +0;336;432;;; +0;336;528;;; +0;336;592;;; +0;336;608;;; +0;336;816;;; +0;336;832;;; +0;336;864;;; +0;336;1776;;; +0;336;1792;;; +0;336;1856;;; +0;336;1904;;; +0;336;1920;;; +0;336;1936;;; +0;336;1952;;; +0;336;1984;;; +0;336;2000;;; +0;336;2016;;; +0;336;2032;;; +0;352;64;;; +0;352;112;;; +0;352;128;;; +0;352;192;;; +0;352;208;;; +0;352;240;;; +0;352;272;;; +0;352;544;;; +0;352;560;;; +0;352;608;;; +0;352;624;;; +0;352;640;;; +0;352;656;;; +0;352;672;;; +0;352;688;;; +0;352;704;;; +0;352;720;;; +0;352;736;;; +0;352;752;;; +0;352;768;;; +0;352;784;;; +0;352;800;;; +0;352;816;;; +0;352;832;;; +0;352;864;;; +0;352;880;;; +0;352;896;;; +0;352;912;;; +0;352;928;;; +0;352;944;;; +0;352;960;;; +0;352;976;;; +0;352;1104;;; +0;352;1776;;; +0;352;1792;;; +0;352;1856;;; +0;352;1904;;; +0;352;1920;;; +0;352;1936;;; +0;352;1952;;; +0;352;1984;;; +0;352;2000;;; +0;352;2016;;; +0;352;2032;;; +0;368;64;;; +0;368;112;;; +0;368;128;;; +0;368;192;;; +0;368;208;;; +0;368;240;;; +0;368;272;;; +0;368;560;;; +0;368;992;;; +0;368;1104;;; +0;368;1120;;; +0;368;1136;;; +0;368;1152;;; +0;368;1776;;; +0;368;1792;;; +0;368;1856;;; +0;368;2016;;; +0;368;2032;;; +0;384;48;;; +0;384;112;;; +0;384;128;;; +0;384;192;;; +0;384;208;;; +0;384;240;;; +0;384;272;;; +0;384;544;;; +0;384;880;;; +0;384;896;;; +0;384;912;;; +0;384;928;;; +0;384;992;;; +0;384;1136;;; +0;384;1152;;; +0;384;1776;;; +0;384;1792;;; +0;384;1856;;; +0;384;2016;;; +0;384;2032;;; +0;400;64;;; +0;400;112;;; +0;400;128;;; +0;400;192;;; +0;400;208;;; +0;400;240;;; +0;400;272;;; +0;400;560;;; +0;400;880;;; +0;400;928;;; +0;400;992;;; +0;400;1056;;; +0;400;1072;;; +0;400;1088;;; +0;400;1136;;; +0;400;1152;;; +0;400;1328;;; +0;400;1344;;; +0;400;1472;;; +0;400;1776;;; +0;400;1792;;; +0;400;1856;;; +0;400;2016;;; +0;400;2032;;; +0;416;64;;; +0;416;80;;; +0;416;96;;; +0;416;112;;; +0;416;128;;; +0;416;192;;; +0;416;208;;; +0;416;240;;; +0;416;272;;; +0;416;288;;; +0;416;304;;; +0;416;320;;; +0;416;368;;; +0;416;384;;; +0;416;400;;; +0;416;560;;; +0;416;752;;; +0;416;768;;; +0;416;784;;; +0;416;800;;; +0;416;816;;; +0;416;880;;; +0;416;928;;; +0;416;992;;; +0;416;1056;;; +0;416;1072;;; +0;416;1136;;; +0;416;1152;;; +0;416;1328;;; +0;416;1776;;; +0;416;1792;;; +0;416;1856;;; +0;416;2016;;; +0;416;2032;;; +0;432;80;;; +0;432;192;;; +0;432;208;;; +0;432;240;;; +0;432;272;;; +0;432;416;;; +0;432;544;;; +0;432;560;;; +0;432;608;;; +0;432;624;;; +0;432;640;;; +0;432;656;;; +0;432;752;;; +0;432;816;;; +0;432;880;;; +0;432;912;;; +0;432;928;;; +0;432;992;;; +0;432;1056;;; +0;432;1072;;; +0;432;1088;;; +0;432;1136;;; +0;432;1152;;; +0;432;1328;;; +0;432;1344;;; +0;432;1472;;; +0;432;1776;;; +0;432;1792;;; +0;432;1856;;; +0;432;2016;;; +0;432;2032;;; +0;448;80;;; +0;448;192;;; +0;448;208;;; +0;448;240;;; +0;448;272;;; +0;448;336;;; +0;448;432;;; +0;448;528;;; +0;448;608;;; +0;448;656;;; +0;448;752;;; +0;448;800;;; +0;448;880;;; +0;448;896;;; +0;448;992;;; +0;448;1056;;; +0;448;1072;;; +0;448;1136;;; +0;448;1152;;; +0;448;1776;;; +0;448;1792;;; +0;448;1856;;; +0;448;1872;;; +0;448;1888;;; +0;448;1904;;; +0;448;1920;;; +0;448;1936;;; +0;448;2016;;; +0;448;2032;;; +0;464;80;;; +0;464;192;;; +0;464;208;;; +0;464;240;;; +0;464;272;;; +0;464;336;;; +0;464;368;;; +0;464;384;;; +0;464;448;;; +0;464;464;;; +0;464;480;;; +0;464;528;;; +0;464;576;;; +0;464;592;;; +0;464;672;;; +0;464;688;;; +0;464;704;;; +0;464;720;;; +0;464;752;;; +0;464;816;;; +0;464;880;;; +0;464;896;;; +0;464;928;;; +0;464;944;;; +0;464;960;;; +0;464;976;;; +0;464;1056;;; +0;464;1072;;; +0;464;1088;;; +0;464;1776;;; +0;464;1792;;; +0;464;1904;;; +0;464;1920;;; +0;464;1936;;; +0;464;1952;;; +0;464;2016;;; +0;464;2032;;; +0;480;80;;; +0;480;112;;; +0;480;128;;; +0;480;144;;; +0;480;160;;; +0;480;176;;; +0;480;192;;; +0;480;208;;; +0;480;240;;; +0;480;272;;; +0;480;288;;; +0;480;320;;; +0;480;368;;; +0;480;400;;; +0;480;448;;; +0;480;528;;; +0;480;576;;; +0;480;720;;; +0;480;752;;; +0;480;816;;; +0;480;832;;; +0;480;848;;; +0;480;864;;; +0;480;880;;; +0;480;896;;; +0;480;928;;; +0;480;1136;;; +0;480;1152;;; +0;480;1776;;; +0;480;1792;;; +0;480;1920;;; +0;480;1936;;; +0;480;1952;;; +0;480;2016;;; +0;480;2032;;; +0;496;80;;; +0;496;112;;; +0;496;128;;; +0;496;240;;; +0;496;272;;; +0;496;288;;; +0;496;320;;; +0;496;368;;; +0;496;384;;; +0;496;400;;; +0;496;448;;; +0;496;528;;; +0;496;576;;; +0;496;720;;; +0;496;752;;; +0;496;800;;; +0;496;816;;; +0;496;832;;; +0;496;848;;; +0;496;864;;; +0;496;880;;; +0;496;896;;; +0;496;928;;; +0;496;1136;;; +0;496;1152;;; +0;496;1776;;; +0;496;1792;;; +0;496;1920;;; +0;496;1936;;; +0;496;1952;;; +0;496;2016;;; +0;496;2032;;; +0;512;80;;; +0;512;112;;; +0;512;128;;; +0;512;240;;; +0;512;272;;; +0;512;320;;; +0;512;448;;; +0;512;528;;; +0;512;576;;; +0;512;592;;; +0;512;672;;; +0;512;688;;; +0;512;704;;; +0;512;720;;; +0;512;752;;; +0;512;784;;; +0;512;880;;; +0;512;896;;; +0;512;928;;; +0;512;944;;; +0;512;960;;; +0;512;976;;; +0;512;1056;;; +0;512;1072;;; +0;512;1776;;; +0;512;1792;;; +0;512;1904;;; +0;512;1920;;; +0;512;1936;;; +0;512;1952;;; +0;512;2016;;; +0;512;2032;;; +0;528;80;;; +0;528;112;;; +0;528;128;;; +0;528;240;;; +0;528;272;;; +0;528;320;;; +0;528;448;;; +0;528;528;;; +0;528;608;;; +0;528;656;;; +0;528;752;;; +0;528;768;;; +0;528;880;;; +0;528;896;;; +0;528;992;;; +0;528;1056;;; +0;528;1136;;; +0;528;1152;;; +0;528;1776;;; +0;528;1792;;; +0;528;1904;;; +0;528;1920;;; +0;528;1936;;; +0;528;2016;;; +0;528;2032;;; +0;544;64;;; +0;544;80;;; +0;544;240;;; +0;544;272;;; +0;544;336;;; +0;544;432;;; +0;544;464;;; +0;544;528;;; +0;544;608;;; +0;544;656;;; +0;544;672;;; +0;544;688;;; +0;544;704;;; +0;544;992;;; +0;544;1056;;; +0;544;1072;;; +0;544;1136;;; +0;544;1152;;; +0;544;1204;;; +0;544;1216;;; +0;544;1232;;; +0;544;1776;;; +0;544;1792;;; +0;544;1808;;; +0;544;1824;;; +0;544;1920;;; +0;544;2016;;; +0;544;2032;;; +0;560;48;;; +0;560;112;;; +0;560;128;;; +0;560;240;;; +0;560;272;;; +0;560;304;;; +0;560;368;;; +0;560;384;;; +0;560;400;;; +0;560;416;;; +0;560;528;;; +0;560;608;;; +0;560;656;;; +0;560;672;;; +0;560;704;;; +0;560;992;;; +0;560;1120;;; +0;560;1136;;; +0;560;1152;;; +0;560;1204;;; +0;560;1216;;; +0;560;1444;;; +0;560;1456;;; +0;560;1472;;; +0;560;1648;;; +0;560;1664;;; +0;560;1680;;; +0;560;1776;;; +0;560;1792;;; +0;560;1808;;; +0;560;1920;;; +0;560;2016;;; +0;560;2032;;; +0;576;64;;; +0;576;80;;; +0;576;112;;; +0;576;240;;; +0;576;272;;; +0;576;480;;; +0;576;528;;; +0;576;608;;; +0;576;656;;; +0;576;672;;; +0;576;704;;; +0;576;992;;; +0;576;1120;;; +0;576;1204;;; +0;576;1216;;; +0;576;1232;;; +0;576;1444;;; +0;576;1456;;; +0;576;1648;;; +0;576;1664;;; +0;576;1680;;; +0;576;1776;;; +0;576;1792;;; +0;576;1808;;; +0;576;1824;;; +0;576;1920;;; +0;576;2016;;; +0;576;2032;;; +0;592;80;;; +0;592;112;;; +0;592;128;;; +0;592;240;;; +0;592;272;;; +0;592;352;;; +0;592;368;;; +0;592;384;;; +0;592;400;;; +0;592;416;;; +0;592;432;;; +0;592;528;;; +0;592;608;;; +0;592;656;;; +0;592;672;;; +0;592;688;;; +0;592;704;;; +0;592;992;;; +0;592;1444;;; +0;592;1456;;; +0;592;1472;;; +0;592;1648;;; +0;592;1664;;; +0;592;1776;;; +0;592;1792;;; +0;592;1904;;; +0;592;1920;;; +0;592;1936;;; +0;592;2016;;; +0;592;2032;;; +0;608;80;;; +0;608;240;;; +0;608;272;;; +0;608;288;;; +0;608;448;;; +0;608;544;;; +0;608;608;;; +0;608;656;;; +0;608;752;;; +0;608;768;;; +0;608;784;;; +0;608;864;;; +0;608;880;;; +0;608;896;;; +0;608;992;;; +0;608;1648;;; +0;608;1664;;; +0;608;1680;;; +0;608;1776;;; +0;608;1792;;; +0;608;1904;;; +0;608;1920;;; +0;608;1936;;; +0;608;2016;;; +0;608;2032;;; +0;624;80;;; +0;624;112;;; +0;624;128;;; +0;624;240;;; +0;624;272;;; +0;624;320;;; +0;624;448;;; +0;624;560;;; +0;624;656;;; +0;624;672;;; +0;624;688;;; +0;624;704;;; +0;624;720;;; +0;624;736;;; +0;624;752;;; +0;624;768;;; +0;624;784;;; +0;624;800;;; +0;624;816;;; +0;624;832;;; +0;624;848;;; +0;624;864;;; +0;624;880;;; +0;624;896;;; +0;624;912;;; +0;624;928;;; +0;624;944;;; +0;624;960;;; +0;624;976;;; +0;624;992;;; +0;624;1424;;; +0;624;1440;;; +0;624;1456;;; +0;624;1472;;; +0;624;1488;;; +0;624;1504;;; +0;624;1520;;; +0;624;1648;;; +0;624;1664;;; +0;624;1680;;; +0;624;1776;;; +0;624;1792;;; +0;624;1904;;; +0;624;1920;;; +0;624;1936;;; +0;624;2016;;; +0;624;2032;;; +0;640;80;;; +0;640;112;;; +0;640;128;;; +0;640;240;;; +0;640;272;;; +0;640;304;;; +0;640;336;;; +0;640;352;;; +0;640;368;;; +0;640;384;;; +0;640;400;;; +0;640;448;;; +0;640;560;;; +0;640;1424;;; +0;640;1520;;; +0;640;1776;;; +0;640;1792;;; +0;640;1904;;; +0;640;1920;;; +0;640;1936;;; +0;640;2016;;; +0;640;2032;;; +0;656;80;;; +0;656;112;;; +0;656;128;;; +0;656;144;;; +0;656;160;;; +0;656;176;;; +0;656;240;;; +0;656;272;;; +0;656;304;;; +0;656;320;;; +0;656;336;;; +0;656;352;;; +0;656;400;;; +0;656;448;;; +0;656;560;;; +0;656;1424;;; +0;656;1440;;; +0;656;1456;;; +0;656;1472;;; +0;656;1488;;; +0;656;1504;;; +0;656;1520;;; +0;656;1776;;; +0;656;1792;;; +0;656;1904;;; +0;656;1920;;; +0;656;1936;;; +0;656;2016;;; +0;656;2032;;; +0;672;80;;; +0;672;112;;; +0;672;160;;; +0;672;176;;; +0;672;192;;; +0;672;240;;; +0;672;272;;; +0;672;368;;; +0;672;432;;; +0;672;448;;; +0;672;560;;; +0;672;672;;; +0;672;688;;; +0;672;704;;; +0;672;720;;; +0;672;912;;; +0;672;928;;; +0;672;944;;; +0;672;960;;; +0;672;976;;; +0;672;992;;; +0;672;1008;;; +0;672;1776;;; +0;672;1792;;; +0;672;1904;;; +0;672;1920;;; +0;672;2016;;; +0;672;2032;;; +0;688;64;;; +0;688;80;;; +0;688;112;;; +0;688;128;;; +0;688;144;;; +0;688;176;;; +0;688;192;;; +0;688;240;;; +0;688;272;;; +0;688;368;;; +0;688;384;;; +0;688;400;;; +0;688;416;;; +0;688;496;;; +0;688;544;;; +0;688;672;;; +0;688;720;;; +0;688;736;;; +0;688;912;;; +0;688;1008;;; +0;688;1328;;; +0;688;1776;;; +0;688;1792;;; +0;688;1872;;; +0;688;1888;;; +0;688;1904;;; +0;688;1920;;; +0;688;1936;;; +0;688;2016;;; +0;688;2032;;; +0;704;48;;; +0;704;112;;; +0;704;144;;; +0;704;176;;; +0;704;192;;; +0;704;240;;; +0;704;256;;; +0;704;480;;; +0;704;496;;; +0;704;512;;; +0;704;528;;; +0;704;672;;; +0;704;736;;; +0;704;1008;;; +0;704;1776;;; +0;704;1792;;; +0;704;1872;;; +0;704;2016;;; +0;704;2032;;; +0;720;48;;; +0;720;112;;; +0;720;144;;; +0;720;240;;; +0;720;272;;; +0;720;672;;; +0;720;736;;; +0;720;912;;; +0;720;1008;;; +0;720;1328;;; +0;720;1776;;; +0;720;1792;;; +0;720;2016;;; +0;720;2032;;; +0;736;48;;; +0;736;112;;; +0;736;144;;; +0;736;176;;; +0;736;192;;; +0;736;240;;; +0;736;272;;; +0;736;368;;; +0;736;384;;; +0;736;672;;; +0;736;688;;; +0;736;704;;; +0;736;720;;; +0;736;736;;; +0;736;880;;; +0;736;896;;; +0;736;912;;; +0;736;1008;;; +0;736;1472;;; +0;736;1776;;; +0;736;1792;;; +0;736;2016;;; +0;736;2032;;; +0;752;48;;; +0;752;112;;; +0;752;144;;; +0;752;176;;; +0;752;192;;; +0;752;224;;; +0;752;240;;; +0;752;256;;; +0;752;272;;; +0;752;880;;; +0;752;896;;; +0;752;1008;;; +0;752;1776;;; +0;752;1792;;; +0;752;2016;;; +0;752;2032;;; +0;768;48;;; +0;768;176;;; +0;768;192;;; +0;768;224;;; +0;768;256;;; +0;768;1008;;; +0;768;1776;;; +0;768;1792;;; +0;768;2016;;; +0;768;2032;;; +0;784;48;;; +0;784;112;;; +0;784;144;;; +0;784;176;;; +0;784;192;;; +0;784;224;;; +0;784;256;;; +0;784;880;;; +0;784;896;;; +0;784;1008;;; +0;784;1056;;; +0;784;1104;;; +0;784;1344;;; +0;784;1776;;; +0;784;1792;;; +0;784;2016;;; +0;784;2032;;; +0;800;48;;; +0;800;112;;; +0;800;144;;; +0;800;176;;; +0;800;192;;; +0;800;224;;; +0;800;256;;; +0;800;880;;; +0;800;896;;; +0;800;1008;;; +0;800;1072;;; +0;800;1088;;; +0;800;1344;;; +0;800;1776;;; +0;800;1792;;; +0;800;1888;;; +0;800;1904;;; +0;800;1920;;; +0;800;1936;;; +0;800;1952;;; +0;800;1968;;; +0;800;1984;;; +0;800;2000;;; +0;800;2016;;; +0;800;2032;;; +0;816;48;;; +0;816;112;;; +0;816;144;;; +0;816;176;;; +0;816;192;;; +0;816;224;;; +0;816;256;;; +0;816;880;;; +0;816;896;;; +0;816;1008;;; +0;816;1072;;; +0;816;1104;;; +0;816;1344;;; +0;816;1360;;; +0;816;1376;;; +0;816;1392;;; +0;816;1408;;; +0;816;1424;;; +0;816;1440;;; +0;816;1456;;; +0;816;1472;;; +0;816;1488;;; +0;816;1504;;; +0;816;1520;;; +0;816;1536;;; +0;816;1776;;; +0;816;1792;;; +0;816;1888;;; +0;816;1904;;; +0;816;1920;;; +0;816;1936;;; +0;816;1952;;; +0;816;1968;;; +0;816;1984;;; +0;816;2000;;; +0;816;2016;;; +0;816;2032;;; +0;832;48;;; +0;832;112;;; +0;832;144;;; +0;832;176;;; +0;832;192;;; +0;832;224;;; +0;832;256;;; +0;832;336;;; +0;832;880;;; +0;832;896;;; +0;832;1008;;; +0;832;1072;;; +0;832;1104;;; +0;832;1520;;; +0;832;1536;;; +0;832;1776;;; +0;832;1792;;; +0;832;1904;;; +0;832;1920;;; +0;832;1936;;; +0;832;1952;;; +0;832;1968;;; +0;832;2016;;; +0;832;2032;;; +0;848;48;;; +0;848;112;;; +0;848;144;;; +0;848;176;;; +0;848;192;;; +0;848;224;;; +0;848;256;;; +0;848;336;;; +0;848;352;;; +0;848;368;;; +0;848;384;;; +0;848;400;;; +0;848;416;;; +0;848;432;;; +0;848;448;;; +0;848;576;;; +0;848;592;;; +0;848;608;;; +0;848;880;;; +0;848;896;;; +0;848;1008;;; +0;848;1072;;; +0;848;1104;;; +0;848;1520;;; +0;848;1536;;; +0;848;1776;;; +0;848;1792;;; +0;848;1904;;; +0;848;1920;;; +0;848;2016;;; +0;848;2032;;; +0;864;48;;; +0;864;112;;; +0;864;128;;; +0;864;144;;; +0;864;176;;; +0;864;192;;; +0;864;224;;; +0;864;256;;; +0;864;432;;; +0;864;448;;; +0;864;464;;; +0;864;576;;; +0;864;608;;; +0;864;784;;; +0;864;800;;; +0;864;880;;; +0;864;896;;; +0;864;1008;;; +0;864;1072;;; +0;864;1104;;; +0;864;1312;;; +0;864;1328;;; +0;864;1360;;; +0;864;1376;;; +0;864;1392;;; +0;864;1408;;; +0;864;1520;;; +0;864;1536;;; +0;864;1776;;; +0;864;1792;;; +0;864;1904;;; +0;864;1920;;; +0;864;2016;;; +0;864;2032;;; +0;880;48;;; +0;880;176;;; +0;880;192;;; +0;880;224;;; +0;880;256;;; +0;880;288;;; +0;880;432;;; +0;880;448;;; +0;880;608;;; +0;880;784;;; +0;880;880;;; +0;880;896;;; +0;880;1008;;; +0;880;1072;;; +0;880;1088;;; +0;880;1104;;; +0;880;1312;;; +0;880;1392;;; +0;880;1408;;; +0;880;1424;;; +0;880;1520;;; +0;880;1536;;; +0;880;1776;;; +0;880;1792;;; +0;880;1904;;; +0;880;1920;;; +0;880;2016;;; +0;880;2032;;; +0;896;48;;; +0;896;112;;; +0;896;128;;; +0;896;144;;; +0;896;176;;; +0;896;192;;; +0;896;224;;; +0;896;256;;; +0;896;288;;; +0;896;432;;; +0;896;448;;; +0;896;576;;; +0;896;592;;; +0;896;608;;; +0;896;784;;; +0;896;800;;; +0;896;880;;; +0;896;896;;; +0;896;944;;; +0;896;960;;; +0;896;976;;; +0;896;992;;; +0;896;1008;;; +0;896;1200;;; +0;896;1216;;; +0;896;1232;;; +0;896;1312;;; +0;896;1392;;; +0;896;1408;;; +0;896;1424;;; +0;896;1520;;; +0;896;1536;;; +0;896;1776;;; +0;896;1792;;; +0;896;2016;;; +0;896;2032;;; +0;912;48;;; +0;912;112;;; +0;912;144;;; +0;912;160;;; +0;912;176;;; +0;912;192;;; +0;912;224;;; +0;912;256;;; +0;912;288;;; +0;912;304;;; +0;912;320;;; +0;912;336;;; +0;912;432;;; +0;912;880;;; +0;912;896;;; +0;912;912;;; +0;912;928;;; +0;912;944;;; +0;912;1072;;; +0;912;1088;;; +0;912;1104;;; +0;912;1200;;; +0;912;1312;;; +0;912;1392;;; +0;912;1408;;; +0;912;1776;;; +0;912;1792;;; +0;912;1872;;; +0;912;2016;;; +0;912;2032;;; +0;928;64;;; +0;928;80;;; +0;928;96;;; +0;928;144;;; +0;928;160;;; +0;928;176;;; +0;928;224;;; +0;928;256;;; +0;928;320;;; +0;928;336;;; +0;928;544;;; +0;928;560;;; +0;928;1040;;; +0;928;1056;;; +0;928;1072;;; +0;928;1088;;; +0;928;1104;;; +0;928;1200;;; +0;928;1216;;; +0;928;1232;;; +0;928;1312;;; +0;928;1392;;; +0;928;1408;;; +0;928;1424;;; +0;928;1520;;; +0;928;1536;;; +0;928;1776;;; +0;928;1792;;; +0;928;1872;;; +0;928;1888;;; +0;928;2016;;; +0;928;2032;;; +0;944;160;;; +0;944;224;;; +0;944;256;;; +0;944;544;;; +0;944;1040;;; +0;944;1072;;; +0;944;1296;;; +0;944;1312;;; +0;944;1392;;; +0;944;1408;;; +0;944;1424;;; +0;944;1520;;; +0;944;1536;;; +0;944;1776;;; +0;944;1792;;; +0;944;1888;;; +0;944;2016;;; +0;944;2032;;; +0;960;160;;; +0;960;176;;; +0;960;224;;; +0;960;240;;; +0;960;256;;; +0;960;272;;; +0;960;320;;; +0;960;336;;; +0;960;432;;; +0;960;448;;; +0;960;544;;; +0;960;560;;; +0;960;1040;;; +0;960;1296;;; +0;960;1392;;; +0;960;1408;;; +0;960;1520;;; +0;960;1536;;; +0;960;1776;;; +0;960;1792;;; +0;960;1808;;; +0;960;1824;;; +0;960;1888;;; +0;960;1904;;; +0;960;1920;;; +0;960;1936;;; +0;960;1952;;; +0;960;1968;;; +0;960;1984;;; +0;960;2000;;; +0;960;2016;;; +0;960;2032;;; +0;976;192;;; +0;976;240;;; +0;976;272;;; +0;976;320;;; +0;976;336;;; +0;976;432;;; +0;976;448;;; +0;976;1040;;; +0;976;1296;;; +0;976;1392;;; +0;976;1408;;; +0;976;1520;;; +0;976;1536;;; +0;976;1824;;; +0;976;1888;;; +0;976;1904;;; +0;976;1920;;; +0;976;1936;;; +0;976;1952;;; +0;976;1968;;; +0;976;1984;;; +0;976;2000;;; +0;976;2016;;; +0;976;2032;;; +0;992;192;;; +0;992;240;;; +0;992;272;;; +0;992;320;;; +0;992;336;;; +0;992;400;;; +0;992;416;;; +0;992;432;;; +0;992;448;;; +0;992;1040;;; +0;992;1056;;; +0;992;1296;;; +0;992;1520;;; +0;992;1536;;; +0;992;1824;;; +0;992;1888;;; +0;1008;192;;; +0;1008;240;;; +0;1008;272;;; +0;1008;304;;; +0;1008;320;;; +0;1008;336;;; +0;1008;400;;; +0;1008;416;;; +0;1008;992;;; +0;1008;1008;;; +0;1008;1024;;; +0;1008;1040;;; +0;1008;1056;;; +0;1008;1072;;; +0;1008;1296;;; +0;1008;1392;;; +0;1008;1408;;; +0;1008;1520;;; +0;1008;1536;;; +0;1008;1568;;; +0;1008;1584;;; +0;1008;1600;;; +0;1008;1824;;; +0;1008;1888;;; +0;1024;192;;; +0;1024;240;;; +0;1024;272;;; +0;1024;304;;; +0;1024;320;;; +0;1024;992;;; +0;1024;1008;;; +0;1024;1024;;; +0;1024;1296;;; +0;1024;1312;;; +0;1024;1328;;; +0;1024;1344;;; +0;1024;1360;;; +0;1024;1376;;; +0;1024;1392;;; +0;1024;1408;;; +0;1024;1520;;; +0;1024;1536;;; +0;1024;1568;;; +0;1024;1584;;; +0;1024;1712;;; +0;1024;1728;;; +0;1024;1824;;; +0;1024;1904;;; +0;1024;1920;;; +0;1024;1936;;; +0;1024;1952;;; +0;1024;1968;;; +0;1040;48;;; +0;1040;64;;; +0;1040;80;;; +0;1040;96;;; +0;1040;112;;; +0;1040;128;;; +0;1040;144;;; +0;1040;160;;; +0;1040;176;;; +0;1040;192;;; +0;1040;240;;; +0;1040;256;;; +0;1040;272;;; +0;1040;304;;; +0;1040;320;;; +0;1040;400;;; +0;1040;416;;; +0;1040;992;;; +0;1040;1008;;; +0;1040;1024;;; +0;1040;1520;;; +0;1040;1536;;; +0;1040;1568;;; +0;1040;1584;;; +0;1040;1600;;; +0;1040;1712;;; +0;1040;1824;;; +0;1040;1952;;; +0;1040;1968;;; +0;1040;1984;;; +0;1056;32;;; +0;1056;368;;; +0;1056;384;;; +0;1056;400;;; +0;1056;416;;; +0;1056;992;;; +0;1056;1008;;; +0;1056;1024;;; +0;1056;1520;;; +0;1056;1536;;; +0;1056;1568;;; +0;1056;1584;;; +0;1056;1600;;; +0;1056;1712;;; +0;1056;1728;;; +0;1056;1824;;; +0;1056;1952;;; +0;1056;2000;;; +0;1072;48;;; +0;1072;64;;; +0;1072;80;;; +0;1072;96;;; +0;1072;112;;; +0;1072;128;;; +0;1072;144;;; +0;1072;160;;; +0;1072;176;;; +0;1072;192;;; +0;1072;240;;; +0;1072;256;;; +0;1072;272;;; +0;1072;304;;; +0;1072;320;;; +0;1072;352;;; +0;1072;368;;; +0;1072;384;;; +0;1072;992;;; +0;1072;1008;;; +0;1072;1024;;; +0;1072;1520;;; +0;1072;1536;;; +0;1072;1808;;; +0;1072;1824;;; +0;1072;1952;;; +0;1072;1968;;; +0;1072;2000;;; +0;1088;192;;; +0;1088;240;;; +0;1088;272;;; +0;1088;304;;; +0;1088;320;;; +0;1088;352;;; +0;1088;992;;; +0;1088;1008;;; +0;1088;1024;;; +0;1088;1520;;; +0;1088;1536;;; +0;1088;1552;;; +0;1088;1792;;; +0;1088;2016;;; +0;1104;192;;; +0;1104;240;;; +0;1104;272;;; +0;1104;304;;; +0;1104;320;;; +0;1104;992;;; +0;1104;1008;;; +0;1104;1024;;; +0;1104;1520;;; +0;1104;1536;;; +0;1104;2016;;; +0;1120;192;;; +0;1120;240;;; +0;1120;272;;; +0;1120;304;;; +0;1120;320;;; +0;1120;992;;; +0;1120;1008;;; +0;1120;1024;;; +0;1120;1520;;; +0;1120;1536;;; +0;1120;2016;;; +0;1136;192;;; +0;1136;240;;; +0;1136;272;;; +0;1136;304;;; +0;1136;320;;; +0;1136;992;;; +0;1136;1008;;; +0;1136;1024;;; +0;1136;1520;;; +0;1136;1536;;; +0;1136;2016;;; +0;1152;208;;; +0;1152;240;;; +0;1152;272;;; +0;1152;304;;; +0;1152;320;;; +0;1152;992;;; +0;1152;1008;;; +0;1152;1024;;; +0;1152;1520;;; +0;1152;1536;;; +0;1152;2016;;; +0;1168;64;;; +0;1168;80;;; +0;1168;96;;; +0;1168;112;;; +0;1168;128;;; +0;1168;144;;; +0;1168;160;;; +0;1168;208;;; +0;1168;224;;; +0;1168;240;;; +0;1168;256;;; +0;1168;272;;; +0;1168;304;;; +0;1168;320;;; +0;1168;430;;; +0;1168;1008;;; +0;1168;1520;;; +0;1168;1536;;; +0;1168;2016;;; +0;1184;32;;; +0;1184;48;;; +0;1184;112;;; +0;1184;128;;; +0;1184;144;;; +0;1184;208;;; +0;1184;256;;; +0;1184;404;;; +0;1184;416;;; +0;1184;432;;; +0;1184;1024;;; +0;1184;1488;;; +0;1184;1504;;; +0;1184;1520;;; +0;1184;1536;;; +0;1184;1984;;; +0;1184;2016;;; +0;1200;16;;; +0;1200;112;;; +0;1200;128;;; +0;1200;144;;; +0;1200;160;;; +0;1200;208;;; +0;1200;224;;; +0;1200;240;;; +0;1200;256;;; +0;1200;304;;; +0;1200;320;;; +0;1200;404;;; +0;1200;416;;; +0;1200;1024;;; +0;1200;1488;;; +0;1200;1984;;; +0;1200;2016;;; +0;1216;16;;; +0;1216;64;;; +0;1216;80;;; +0;1216;96;;; +0;1216;112;;; +0;1216;128;;; +0;1216;144;;; +0;1216;160;;; +0;1216;304;;; +0;1216;320;;; +0;1216;404;;; +0;1216;416;;; +0;1216;432;;; +0;1216;976;;; +0;1216;1024;;; +0;1216;1984;;; +0;1216;2016;;; +0;1232;16;;; +0;1232;64;;; +0;1232;80;;; +0;1232;208;;; +0;1232;224;;; +0;1232;240;;; +0;1232;256;;; +0;1232;304;;; +0;1232;320;;; +0;1232;336;;; +0;1232;352;;; +0;1232;368;;; +0;1232;384;;; +0;1232;400;;; +0;1232;416;;; +0;1232;432;;; +0;1232;2016;;; +0;1248;16;;; +0;1248;112;;; +0;1248;128;;; +0;1248;144;;; +0;1248;160;;; +0;1248;176;;; +0;1248;208;;; +0;1248;256;;; +0;1248;416;;; +0;1248;432;;; +0;1248;448;;; +0;1248;464;;; +0;1248;480;;; +0;1248;1152;;; +0;1248;1168;;; +0;1248;1200;;; +0;1248;1216;;; +0;1248;1232;;; +0;1248;2016;;; +0;1264;16;;; +0;1264;64;;; +0;1264;80;;; +0;1264;160;;; +0;1264;176;;; +0;1264;208;;; +0;1264;256;;; +0;1264;464;;; +0;1264;1152;;; +0;1264;1968;;; +0;1264;1984;;; +0;1264;2000;;; +0;1280;16;;; +0;1280;32;;; +0;1280;64;;; +0;1280;80;;; +0;1280;160;;; +0;1280;176;;; +0;1280;192;;; +0;1280;208;;; +0;1280;224;;; +0;1280;240;;; +0;1280;256;;; +0;1280;288;;; +0;1280;304;;; +0;1280;320;;; +0;1280;336;;; +0;1280;352;;; +0;1280;368;;; +0;1280;384;;; +0;1280;400;;; +0;1280;416;;; +0;1280;464;;; +0;1280;1152;;; +0;1280;1216;;; +0;1280;1232;;; +0;1280;1360;;; +0;1280;1376;;; +0;1280;1392;;; +0;1280;1408;;; +0;1280;1424;;; +0;1280;1440;;; +0;1280;1456;;; +0;1280;1472;;; +0;1280;1488;;; +0;1280;1504;;; +0;1280;1520;;; +0;1280;1536;;; +0;1280;1552;;; +0;1280;1568;;; +0;1280;1584;;; +0;1280;1600;;; +0;1280;1616;;; +0;1280;1632;;; +0;1280;1648;;; +0;1280;1664;;; +0;1280;1680;;; +0;1280;1696;;; +0;1280;1712;;; +0;1280;1728;;; +0;1280;1744;;; +0;1280;1760;;; +0;1280;1968;;; +0;1296;16;;; +0;1296;64;;; +0;1296;80;;; +0;1296;160;;; +0;1296;224;;; +0;1296;288;;; +0;1296;304;;; +0;1296;320;;; +0;1296;336;;; +0;1296;352;;; +0;1296;368;;; +0;1296;384;;; +0;1296;400;;; +0;1296;416;;; +0;1296;464;;; +0;1296;544;;; +0;1296;560;;; +0;1296;576;;; +0;1296;592;;; +0;1296;608;;; +0;1296;624;;; +0;1296;640;;; +0;1296;656;;; +0;1296;672;;; +0;1296;688;;; +0;1296;704;;; +0;1296;720;;; +0;1296;736;;; +0;1296;752;;; +0;1296;768;;; +0;1296;784;;; +0;1296;800;;; +0;1296;816;;; +0;1296;832;;; +0;1296;848;;; +0;1296;864;;; +0;1296;880;;; +0;1296;896;;; +0;1296;912;;; +0;1296;928;;; +0;1296;944;;; +0;1296;960;;; +0;1296;1152;;; +0;1296;1216;;; +0;1296;1232;;; +0;1296;1360;;; +0;1296;1584;;; +0;1296;1600;;; +0;1296;1616;;; +0;1296;1632;;; +0;1296;1648;;; +0;1296;1664;;; +0;1296;1680;;; +0;1296;1696;;; +0;1296;1712;;; +0;1296;1728;;; +0;1296;1744;;; +0;1296;1760;;; +0;1296;1936;;; +0;1296;1952;;; +0;1296;1968;;; +0;1296;1984;;; +0;1296;2000;;; +0;1296;2016;;; +0;1312;16;;; +0;1312;64;;; +0;1312;80;;; +0;1312;160;;; +0;1312;224;;; +0;1312;464;;; +0;1312;544;;; +0;1312;976;;; +0;1312;1152;;; +0;1312;1200;;; +0;1312;1216;;; +0;1312;1232;;; +0;1312;1360;;; +0;1312;1584;;; +0;1312;1600;;; +0;1312;1936;;; +0;1312;2032;;; +0;1328;16;;; +0;1328;64;;; +0;1328;96;;; +0;1328;112;;; +0;1328;128;;; +0;1328;144;;; +0;1328;160;;; +0;1328;176;;; +0;1328;192;;; +0;1328;208;;; +0;1328;224;;; +0;1328;240;;; +0;1328;256;;; +0;1328;464;;; +0;1328;528;;; +0;1328;544;;; +0;1328;576;;; +0;1328;592;;; +0;1328;608;;; +0;1328;624;;; +0;1328;640;;; +0;1328;656;;; +0;1328;672;;; +0;1328;688;;; +0;1328;704;;; +0;1328;720;;; +0;1328;864;;; +0;1328;880;;; +0;1328;896;;; +0;1328;912;;; +0;1328;928;;; +0;1328;976;;; +0;1328;1152;;; +0;1328;1328;;; +0;1328;1344;;; +0;1328;1360;;; +0;1328;1584;;; +0;1328;1872;;; +0;1328;1936;;; +0;1328;1968;;; +0;1328;1984;;; +0;1328;2000;;; +0;1328;2032;;; +0;1344;16;;; +0;1344;64;;; +0;1344;112;;; +0;1344;128;;; +0;1344;144;;; +0;1344;160;;; +0;1344;176;;; +0;1344;192;;; +0;1344;224;;; +0;1344;256;;; +0;1344;416;;; +0;1344;432;;; +0;1344;448;;; +0;1344;464;;; +0;1344;480;;; +0;1344;496;;; +0;1344;512;;; +0;1344;576;;; +0;1344;688;;; +0;1344;704;;; +0;1344;720;;; +0;1344;736;;; +0;1344;752;;; +0;1344;768;;; +0;1344;784;;; +0;1344;800;;; +0;1344;816;;; +0;1344;832;;; +0;1344;848;;; +0;1344;864;;; +0;1344;928;;; +0;1344;976;;; +0;1344;1152;;; +0;1344;1168;;; +0;1344;1184;;; +0;1344;1200;;; +0;1344;1216;;; +0;1344;1328;;; +0;1344;1392;;; +0;1344;1408;;; +0;1344;1424;;; +0;1344;1440;;; +0;1344;1552;;; +0;1344;1568;;; +0;1344;1584;;; +0;1344;1600;;; +0;1344;1728;;; +0;1344;1744;;; +0;1344;1760;;; +0;1344;1776;;; +0;1344;1792;;; +0;1344;1808;;; +0;1344;1824;;; +0;1344;1968;;; +0;1344;2032;;; +0;1360;16;;; +0;1360;64;;; +0;1360;96;;; +0;1360;128;;; +0;1360;192;;; +0;1360;224;;; +0;1360;256;;; +0;1360;272;;; +0;1360;288;;; +0;1360;304;;; +0;1360;320;;; +0;1360;352;;; +0;1360;368;;; +0;1360;384;;; +0;1360;400;;; +0;1360;416;;; +0;1360;432;;; +0;1360;448;;; +0;1360;576;;; +0;1360;880;;; +0;1360;912;;; +0;1360;976;;; +0;1360;1088;;; +0;1360;1328;;; +0;1360;1344;;; +0;1360;1392;;; +0;1360;1424;;; +0;1360;1440;;; +0;1360;1552;;; +0;1360;1568;;; +0;1360;1728;;; +0;1360;1744;;; +0;1360;1824;;; +0;1360;1872;;; +0;1360;1936;;; +0;1360;1968;;; +0;1360;2000;;; +0;1360;2016;;; +0;1376;16;;; +0;1376;64;;; +0;1376;80;;; +0;1376;112;;; +0;1376;128;;; +0;1376;192;;; +0;1376;224;;; +0;1376;272;;; +0;1376;320;;; +0;1376;352;;; +0;1376;400;;; +0;1376;496;;; +0;1376;512;;; +0;1376;528;;; +0;1376;544;;; +0;1376;560;;; +0;1376;576;;; +0;1376;592;;; +0;1376;608;;; +0;1376;880;;; +0;1376;912;;; +0;1376;976;;; +0;1376;1328;;; +0;1376;1392;;; +0;1376;1424;;; +0;1376;1472;;; +0;1376;1488;;; +0;1376;1504;;; +0;1376;1520;;; +0;1376;1536;;; +0;1376;1552;;; +0;1376;1568;;; +0;1376;1824;;; +0;1376;1936;;; +0;1376;1952;;; +0;1376;1968;;; +0;1376;1984;;; +0;1376;2000;;; +0;1392;16;;; +0;1392;64;;; +0;1392;80;;; +0;1392;112;;; +0;1392;192;;; +0;1392;224;;; +0;1392;272;;; +0;1392;320;;; +0;1392;352;;; +0;1392;400;;; +0;1392;416;;; +0;1392;432;;; +0;1392;448;;; +0;1392;496;;; +0;1392;544;;; +0;1392;880;;; +0;1392;912;;; +0;1392;976;;; +0;1392;1088;;; +0;1392;1328;;; +0;1392;1392;;; +0;1392;1408;;; +0;1392;1424;;; +0;1392;1440;;; +0;1392;1472;;; +0;1392;1488;;; +0;1392;1728;;; +0;1392;1744;;; +0;1392;1824;;; +0;1392;1952;;; +0;1408;16;;; +0;1408;64;;; +0;1408;80;;; +0;1408;112;;; +0;1408;128;;; +0;1408;192;;; +0;1408;224;;; +0;1408;272;;; +0;1408;320;;; +0;1408;352;;; +0;1408;384;;; +0;1408;448;;; +0;1408;464;;; +0;1408;496;;; +0;1408;544;;; +0;1408;880;;; +0;1408;912;;; +0;1408;976;;; +0;1408;1328;;; +0;1408;1344;;; +0;1408;1472;;; +0;1408;1632;;; +0;1408;1648;;; +0;1408;1664;;; +0;1408;1680;;; +0;1408;1696;;; +0;1408;1712;;; +0;1408;1728;;; +0;1408;1744;;; +0;1408;1824;;; +0;1408;1840;;; +0;1408;1856;;; +0;1408;1872;;; +0;1408;1952;;; +0;1408;1968;;; +0;1408;1984;;; +0;1408;2000;;; +0;1408;2016;;; +0;1408;2032;;; +0;1424;16;;; +0;1424;64;;; +0;1424;80;;; +0;1424;112;;; +0;1424;192;;; +0;1424;224;;; +0;1424;288;;; +0;1424;320;;; +0;1424;352;;; +0;1424;400;;; +0;1424;464;;; +0;1424;496;;; +0;1424;544;;; +0;1424;608;;; +0;1424;624;;; +0;1424;640;;; +0;1424;656;;; +0;1424;672;;; +0;1424;688;;; +0;1424;704;;; +0;1424;720;;; +0;1424;736;;; +0;1424;752;;; +0;1424;784;;; +0;1424;800;;; +0;1424;880;;; +0;1424;912;;; +0;1424;976;;; +0;1424;1344;;; +0;1424;1360;;; +0;1424;1376;;; +0;1424;1392;;; +0;1424;1408;;; +0;1424;1424;;; +0;1424;1440;;; +0;1424;1456;;; +0;1424;1472;;; +0;1424;1488;;; +0;1424;1584;;; +0;1424;1600;;; +0;1424;1616;;; +0;1424;1632;;; +0;1424;1648;;; +0;1424;1664;;; +0;1424;1872;;; +0;1424;2016;;; +0;1424;2032;;; +0;1440;16;;; +0;1440;64;;; +0;1440;80;;; +0;1440;112;;; +0;1440;128;;; +0;1440;192;;; +0;1440;240;;; +0;1440;288;;; +0;1440;320;;; +0;1440;368;;; +0;1440;400;;; +0;1440;464;;; +0;1440;496;;; +0;1440;544;;; +0;1440;592;;; +0;1440;672;;; +0;1440;752;;; +0;1440;784;;; +0;1440;880;;; +0;1440;912;;; +0;1440;976;;; +0;1440;1584;;; +0;1440;1872;;; +0;1440;2032;;; +0;1456;16;;; +0;1456;64;;; +0;1456;80;;; +0;1456;112;;; +0;1456;128;;; +0;1456;192;;; +0;1456;240;;; +0;1456;288;;; +0;1456;320;;; +0;1456;368;;; +0;1456;384;;; +0;1456;400;;; +0;1456;464;;; +0;1456;496;;; +0;1456;544;;; +0;1456;592;;; +0;1456;672;;; +0;1456;752;;; +0;1456;784;;; +0;1456;880;;; +0;1456;912;;; +0;1456;976;;; +0;1456;1584;;; +0;1456;1872;;; +0;1456;2032;;; +0;1472;16;;; +0;1472;64;;; +0;1472;80;;; +0;1472;192;;; +0;1472;224;;; +0;1472;288;;; +0;1472;320;;; +0;1472;464;;; +0;1472;496;;; +0;1472;544;;; +0;1472;592;;; +0;1472;656;;; +0;1472;752;;; +0;1472;784;;; +0;1472;880;;; +0;1472;912;;; +0;1472;976;;; +0;1472;1728;;; +0;1472;1760;;; +0;1472;1872;;; +0;1472;2032;;; +0;1488;16;;; +0;1488;64;;; +0;1488;80;;; +0;1488;112;;; +0;1488;128;;; +0;1488;224;;; +0;1488;272;;; +0;1488;320;;; +0;1488;336;;; +0;1488;352;;; +0;1488;368;;; +0;1488;384;;; +0;1488;400;;; +0;1488;464;;; +0;1488;496;;; +0;1488;544;;; +0;1488;592;;; +0;1488;672;;; +0;1488;752;;; +0;1488;784;;; +0;1488;880;;; +0;1488;928;;; +0;1488;976;;; +0;1488;1584;;; +0;1488;1632;;; +0;1488;1696;;; +0;1488;1712;;; +0;1488;1728;;; +0;1488;1760;;; +0;1488;1856;;; +0;1488;1872;;; +0;1488;2032;;; +0;1504;16;;; +0;1504;64;;; +0;1504;80;;; +0;1504;112;;; +0;1504;128;;; +0;1504;144;;; +0;1504;160;;; +0;1504;176;;; +0;1504;192;;; +0;1504;224;;; +0;1504;272;;; +0;1504;336;;; +0;1504;464;;; +0;1504;496;;; +0;1504;544;;; +0;1504;592;;; +0;1504;688;;; +0;1504;704;;; +0;1504;752;;; +0;1504;768;;; +0;1504;784;;; +0;1504;800;;; +0;1504;816;;; +0;1504;832;;; +0;1504;880;;; +0;1504;896;;; +0;1504;912;;; +0;1504;928;;; +0;1504;944;;; +0;1504;960;;; +0;1504;976;;; +0;1504;1552;;; +0;1504;1568;;; +0;1504;1584;;; +0;1504;1680;;; +0;1504;1744;;; +0;1504;1760;;; +0;1504;1824;;; +0;1504;1872;;; +0;1504;1888;;; +0;1504;1904;;; +0;1504;1920;;; +0;1504;1936;;; +0;1504;2032;;; +0;1520;16;;; +0;1520;64;;; +0;1520;80;;; +0;1520;176;;; +0;1520;192;;; +0;1520;224;;; +0;1520;272;;; +0;1520;320;;; +0;1520;336;;; +0;1520;368;;; +0;1520;384;;; +0;1520;464;;; +0;1520;496;;; +0;1520;544;;; +0;1520;592;;; +0;1520;688;;; +0;1520;784;;; +0;1520;816;;; +0;1520;1552;;; +0;1520;1680;;; +0;1520;1696;;; +0;1520;1712;;; +0;1520;1760;;; +0;1520;1808;;; +0;1520;1824;;; +0;1520;1840;;; +0;1520;1936;;; +0;1520;2032;;; +0;1536;16;;; +0;1536;64;;; +0;1536;176;;; +0;1536;192;;; +0;1536;224;;; +0;1536;272;;; +0;1536;320;;; +0;1536;368;;; +0;1536;384;;; +0;1536;464;;; +0;1536;496;;; +0;1536;544;;; +0;1536;592;;; +0;1536;672;;; +0;1536;784;;; +0;1536;800;;; +0;1536;1552;;; +0;1536;1632;;; +0;1536;1680;;; +0;1536;1696;;; +0;1536;1760;;; +0;1536;1808;;; +0;1536;1840;;; +0;1536;1856;;; +0;1536;1872;;; +0;1536;1936;;; +0;1536;2032;;; +0;1552;16;;; +0;1552;64;;; +0;1552;176;;; +0;1552;192;;; +0;1552;224;;; +0;1552;272;;; +0;1552;320;;; +0;1552;368;;; +0;1552;384;;; +0;1552;464;;; +0;1552;496;;; +0;1552;544;;; +0;1552;592;;; +0;1552;688;;; +0;1552;784;;; +0;1552;816;;; +0;1552;1488;;; +0;1552;1504;;; +0;1552;1520;;; +0;1552;1536;;; +0;1552;1552;;; +0;1552;1680;;; +0;1552;1696;;; +0;1552;1712;;; +0;1552;1760;;; +0;1552;1808;;; +0;1552;1872;;; +0;1552;1936;;; +0;1552;2032;;; +0;1568;16;;; +0;1568;64;;; +0;1568;160;;; +0;1568;176;;; +0;1568;192;;; +0;1568;224;;; +0;1568;272;;; +0;1568;320;;; +0;1568;464;;; +0;1568;496;;; +0;1568;544;;; +0;1568;592;;; +0;1568;688;;; +0;1568;704;;; +0;1568;752;;; +0;1568;768;;; +0;1568;784;;; +0;1568;800;;; +0;1568;816;;; +0;1568;832;;; +0;1568;880;;; +0;1568;896;;; +0;1568;912;;; +0;1568;928;;; +0;1568;944;;; +0;1568;960;;; +0;1568;976;;; +0;1568;1488;;; +0;1568;1552;;; +0;1568;1680;;; +0;1568;1744;;; +0;1568;1760;;; +0;1568;1808;;; +0;1568;1872;;; +0;1568;1888;;; +0;1568;1904;;; +0;1568;1920;;; +0;1568;1936;;; +0;1568;2032;;; +0;1584;16;;; +0;1584;80;;; +0;1584;96;;; +0;1584;160;;; +0;1584;224;;; +0;1584;272;;; +0;1584;320;;; +0;1584;464;;; +0;1584;496;;; +0;1584;544;;; +0;1584;592;;; +0;1584;672;;; +0;1584;752;;; +0;1584;784;;; +0;1584;880;;; +0;1584;928;;; +0;1584;976;;; +0;1584;1488;;; +0;1584;1696;;; +0;1584;1712;;; +0;1584;1728;;; +0;1584;1744;;; +0;1584;1808;;; +0;1584;1888;;; +0;1584;1904;;; +0;1584;1920;;; +0;1584;1936;;; +0;1584;2016;;; +0;1584;2032;;; +0;1600;16;;; +0;1600;64;;; +0;1600;96;;; +0;1600;160;;; +0;1600;176;;; +0;1600;224;;; +0;1600;272;;; +0;1600;320;;; +0;1600;368;;; +0;1600;384;;; +0;1600;464;;; +0;1600;496;;; +0;1600;544;;; +0;1600;592;;; +0;1600;672;;; +0;1600;752;;; +0;1600;784;;; +0;1600;880;;; +0;1600;912;;; +0;1600;976;;; +0;1600;1488;;; +0;1600;1808;;; +0;1600;1888;;; +0;1600;1904;;; +0;1600;1920;;; +0;1600;1936;;; +0;1600;1952;;; +0;1600;1968;;; +0;1600;1984;;; +0;1600;2000;;; +0;1600;2016;;; +0;1616;0;;; +0;1616;16;;; +0;1616;64;;; +0;1616;96;;; +0;1616;160;;; +0;1616;176;;; +0;1616;224;;; +0;1616;272;;; +0;1616;320;;; +0;1616;368;;; +0;1616;384;;; +0;1616;464;;; +0;1616;496;;; +0;1616;544;;; +0;1616;592;;; +0;1616;672;;; +0;1616;752;;; +0;1616;784;;; +0;1616;880;;; +0;1616;912;;; +0;1616;976;;; +0;1616;1488;;; +0;1616;1808;;; +0;1616;1888;;; +0;1616;1904;;; +0;1616;1920;;; +0;1616;1936;;; +0;1616;1952;;; +0;1616;1968;;; +0;1616;1984;;; +0;1632;0;;; +0;1632;64;;; +0;1632;160;;; +0;1632;176;;; +0;1632;224;;; +0;1632;272;;; +0;1632;320;;; +0;1632;336;;; +0;1632;368;;; +0;1632;384;;; +0;1632;464;;; +0;1632;496;;; +0;1632;544;;; +0;1632;608;;; +0;1632;624;;; +0;1632;640;;; +0;1632;656;;; +0;1632;672;;; +0;1632;688;;; +0;1632;704;;; +0;1632;720;;; +0;1632;736;;; +0;1632;752;;; +0;1632;768;;; +0;1632;784;;; +0;1632;800;;; +0;1632;880;;; +0;1632;912;;; +0;1632;976;;; +0;1632;1056;;; +0;1632;1072;;; +0;1632;1088;;; +0;1632;1104;;; +0;1632;1120;;; +0;1632;1136;;; +0;1632;1152;;; +0;1632;1168;;; +0;1632;1184;;; +0;1632;1488;;; +0;1632;1808;;; +0;1632;1984;;; +0;1632;2000;;; +0;1632;2016;;; +0;1648;0;;; +0;1648;64;;; +0;1648;96;;; +0;1648;112;;; +0;1648;128;;; +0;1648;144;;; +0;1648;160;;; +0;1648;176;;; +0;1648;192;;; +0;1648;224;;; +0;1648;272;;; +0;1648;336;;; +0;1648;464;;; +0;1648;496;;; +0;1648;544;;; +0;1648;880;;; +0;1648;912;;; +0;1648;976;;; +0;1648;1040;;; +0;1648;1056;;; +0;1648;1184;;; +0;1648;1472;;; +0;1648;1488;;; +0;1648;1696;;; +0;1648;1712;;; +0;1648;1728;;; +0;1648;1744;;; +0;1648;1808;;; +0;1648;1824;;; +0;1648;1840;;; +0;1648;2016;;; +0;1664;16;;; +0;1664;64;;; +0;1664;80;;; +0;1664;160;;; +0;1664;176;;; +0;1664;192;;; +0;1664;224;;; +0;1664;288;;; +0;1664;336;;; +0;1664;464;;; +0;1664;496;;; +0;1664;544;;; +0;1664;880;;; +0;1664;912;;; +0;1664;976;;; +0;1664;1040;;; +0;1664;1184;;; +0;1664;1440;;; +0;1664;1456;;; +0;1664;1472;;; +0;1664;1696;;; +0;1664;1744;;; +0;1664;1760;;; +0;1664;1776;;; +0;1664;1792;;; +0;1664;1808;;; +0;1664;1840;;; +0;1664;1856;;; +0;1664;1936;;; +0;1664;1952;;; +0;1664;2000;;; +0;1664;2016;;; +0;1664;2032;;; +0;1680;144;;; +0;1680;160;;; +0;1680;176;;; +0;1680;192;;; +0;1680;240;;; +0;1680;288;;; +0;1680;336;;; +0;1680;368;;; +0;1680;384;;; +0;1680;464;;; +0;1680;496;;; +0;1680;544;;; +0;1680;880;;; +0;1680;912;;; +0;1680;976;;; +0;1680;1040;;; +0;1680;1072;;; +0;1680;1184;;; +0;1680;1200;;; +0;1680;1440;;; +0;1680;1696;;; +0;1680;1712;;; +0;1680;1808;;; +0;1680;1824;;; +0;1680;1840;;; +0;1680;1856;;; +0;1680;1872;;; +0;1680;1936;;; +0;1680;2032;;; +0;1696;16;;; +0;1696;64;;; +0;1696;80;;; +0;1696;144;;; +0;1696;192;;; +0;1696;240;;; +0;1696;288;;; +0;1696;336;;; +0;1696;368;;; +0;1696;384;;; +0;1696;432;;; +0;1696;448;;; +0;1696;464;;; +0;1696;496;;; +0;1696;544;;; +0;1696;880;;; +0;1696;912;;; +0;1696;976;;; +0;1696;1040;;; +0;1696;1200;;; +0;1696;1440;;; +0;1696;1472;;; +0;1696;1488;;; +0;1696;1504;;; +0;1696;1696;;; +0;1696;1712;;; +0;1696;2016;;; +0;1712;0;;; +0;1712;64;;; +0;1712;96;;; +0;1712;144;;; +0;1712;192;;; +0;1712;240;;; +0;1712;336;;; +0;1712;368;;; +0;1712;384;;; +0;1712;432;;; +0;1712;496;;; +0;1712;544;;; +0;1712;560;;; +0;1712;576;;; +0;1712;592;;; +0;1712;608;;; +0;1712;880;;; +0;1712;912;;; +0;1712;976;;; +0;1712;1040;;; +0;1712;1072;;; +0;1712;1440;;; +0;1712;1472;;; +0;1712;1712;;; +0;1712;1808;;; +0;1712;1840;;; +0;1712;1856;;; +0;1712;1872;;; +0;1712;1936;;; +0;1712;1952;;; +0;1712;2000;;; +0;1712;2016;;; +0;1728;0;;; +0;1728;80;;; +0;1728;144;;; +0;1728;192;;; +0;1728;240;;; +0;1728;288;;; +0;1728;336;;; +0;1728;432;;; +0;1728;496;;; +0;1728;576;;; +0;1728;608;;; +0;1728;752;;; +0;1728;768;;; +0;1728;784;;; +0;1728;800;;; +0;1728;816;;; +0;1728;832;;; +0;1728;848;;; +0;1728;864;;; +0;1728;928;;; +0;1728;976;;; +0;1728;1040;;; +0;1728;1472;;; +0;1728;1504;;; +0;1728;1520;;; +0;1728;1536;;; +0;1728;1552;;; +0;1728;1568;;; +0;1728;1584;;; +0;1728;1600;;; +0;1728;1616;;; +0;1728;1632;;; +0;1728;1648;;; +0;1728;1664;;; +0;1728;1680;;; +0;1728;1712;;; +0;1728;1728;;; +0;1728;1744;;; +0;1728;1760;;; +0;1728;1776;;; +0;1728;1792;;; +0;1728;1808;;; +0;1728;1856;;; +0;1728;1872;;; +0;1728;2016;;; +0;1744;0;;; +0;1744;64;;; +0;1744;96;;; +0;1744;144;;; +0;1744;160;;; +0;1744;176;;; +0;1744;192;;; +0;1744;240;;; +0;1744;288;;; +0;1744;336;;; +0;1744;432;;; +0;1744;464;;; +0;1744;480;;; +0;1744;496;;; +0;1744;576;;; +0;1744;608;;; +0;1744;752;;; +0;1744;864;;; +0;1744;880;;; +0;1744;896;;; +0;1744;912;;; +0;1744;928;;; +0;1744;976;;; +0;1744;1040;;; +0;1744;1184;;; +0;1744;1440;;; +0;1744;1472;;; +0;1744;1840;;; +0;1744;1856;;; +0;1744;2016;;; +0;1760;0;;; +0;1760;64;;; +0;1760;80;;; +0;1760;160;;; +0;1760;176;;; +0;1760;192;;; +0;1760;240;;; +0;1760;288;;; +0;1760;336;;; +0;1760;368;;; +0;1760;384;;; +0;1760;432;;; +0;1760;464;;; +0;1760;576;;; +0;1760;592;;; +0;1760;608;;; +0;1760;624;;; +0;1760;640;;; +0;1760;656;;; +0;1760;672;;; +0;1760;688;;; +0;1760;704;;; +0;1760;720;;; +0;1760;736;;; +0;1760;752;;; +0;1760;832;;; +0;1760;976;;; +0;1760;1040;;; +0;1760;1136;;; +0;1760;1152;;; +0;1760;1168;;; +0;1760;1184;;; +0;1760;1440;;; +0;1760;1472;;; +0;1760;1680;;; +0;1760;1840;;; +0;1760;2016;;; +0;1776;0;;; +0;1776;64;;; +0;1776;80;;; +0;1776;160;;; +0;1776;176;;; +0;1776;192;;; +0;1776;240;;; +0;1776;288;;; +0;1776;336;;; +0;1776;368;;; +0;1776;384;;; +0;1776;432;;; +0;1776;464;;; +0;1776;832;;; +0;1776;976;;; +0;1776;1040;;; +0;1776;1136;;; +0;1776;1152;;; +0;1776;1440;;; +0;1776;1472;;; +0;1776;1680;;; +0;1776;1840;;; +0;1776;2016;;; +0;1792;0;;; +0;1792;64;;; +0;1792;80;;; +0;1792;144;;; +0;1792;176;;; +0;1792;192;;; +0;1792;224;;; +0;1792;288;;; +0;1792;336;;; +0;1792;368;;; +0;1792;384;;; +0;1792;432;;; +0;1792;832;;; +0;1792;848;;; +0;1792;864;;; +0;1792;880;;; +0;1792;896;;; +0;1792;912;;; +0;1792;976;;; +0;1792;1040;;; +0;1792;1136;;; +0;1792;1152;;; +0;1792;1440;;; +0;1792;1472;;; +0;1792;1680;;; +0;1792;1696;;; +0;1792;1712;;; +0;1792;1728;;; +0;1792;1744;;; +0;1792;1760;;; +0;1792;1776;;; +0;1792;1792;;; +0;1792;1808;;; +0;1792;1824;;; +0;1792;1840;;; +0;1792;2016;;; +0;1808;0;;; +0;1808;64;;; +0;1808;80;;; +0;1808;144;;; +0;1808;176;;; +0;1808;224;;; +0;1808;272;;; +0;1808;336;;; +0;1808;368;;; +0;1808;384;;; +0;1808;432;;; +0;1808;464;;; +0;1808;912;;; +0;1808;944;;; +0;1808;960;;; +0;1808;976;;; +0;1808;1040;;; +0;1808;1056;;; +0;1808;1072;;; +0;1808;1216;;; +0;1808;1232;;; +0;1808;1248;;; +0;1808;1264;;; +0;1808;1280;;; +0;1808;1296;;; +0;1808;1312;;; +0;1808;1328;;; +0;1808;1440;;; +0;1808;1472;;; +0;1808;2016;;; +0;1824;0;;; +0;1824;16;;; +0;1824;64;;; +0;1824;80;;; +0;1824;144;;; +0;1824;176;;; +0;1824;192;;; +0;1824;336;;; +0;1824;368;;; +0;1824;384;;; +0;1824;432;;; +0;1824;464;;; +0;1824;480;;; +0;1824;496;;; +0;1824;512;;; +0;1824;528;;; +0;1824;912;;; +0;1824;944;;; +0;1824;1072;;; +0;1824;1184;;; +0;1824;1200;;; +0;1824;1216;;; +0;1824;1328;;; +0;1824;1344;;; +0;1824;1360;;; +0;1824;1392;;; +0;1824;1408;;; +0;1824;1424;;; +0;1824;1440;;; +0;1824;1472;;; +0;1824;2016;;; +0;1840;16;;; +0;1840;64;;; +0;1840;80;;; +0;1840;160;;; +0;1840;192;;; +0;1840;336;;; +0;1840;368;;; +0;1840;384;;; +0;1840;496;;; +0;1840;512;;; +0;1840;672;;; +0;1840;688;;; +0;1840;704;;; +0;1840;720;;; +0;1840;736;;; +0;1840;1072;;; +0;1840;1136;;; +0;1840;1152;;; +0;1840;1184;;; +0;1840;1472;;; +0;1840;2000;;; +0;1840;2016;;; +0;1856;16;;; +0;1856;32;;; +0;1856;64;;; +0;1856;80;;; +0;1856;160;;; +0;1856;192;;; +0;1856;336;;; +0;1856;368;;; +0;1856;384;;; +0;1856;432;;; +0;1856;496;;; +0;1856;512;;; +0;1856;528;;; +0;1856;672;;; +0;1856;736;;; +0;1856;912;;; +0;1856;944;;; +0;1856;1072;;; +0;1856;1088;;; +0;1856;1104;;; +0;1856;1120;;; +0;1856;1136;;; +0;1856;1152;;; +0;1856;1232;;; +0;1856;1248;;; +0;1856;1264;;; +0;1856;1280;;; +0;1856;1296;;; +0;1856;1312;;; +0;1856;1456;;; +0;1856;1472;;; +0;1856;1984;;; +0;1856;2000;;; +0;1872;32;;; +0;1872;64;;; +0;1872;160;;; +0;1872;192;;; +0;1872;224;;; +0;1872;272;;; +0;1872;336;;; +0;1872;368;;; +0;1872;384;;; +0;1872;432;;; +0;1872;448;;; +0;1872;496;;; +0;1872;512;;; +0;1872;528;;; +0;1872;544;;; +0;1872;560;;; +0;1872;576;;; +0;1872;592;;; +0;1872;608;;; +0;1872;624;;; +0;1872;640;;; +0;1872;656;;; +0;1872;672;;; +0;1872;736;;; +0;1872;752;;; +0;1872;768;;; +0;1872;784;;; +0;1872;800;;; +0;1872;912;;; +0;1872;944;;; +0;1872;960;;; +0;1872;976;;; +0;1872;1184;;; +0;1872;1232;;; +0;1872;1312;;; +0;1872;1328;;; +0;1872;1344;;; +0;1872;1360;;; +0;1872;1392;;; +0;1872;1408;;; +0;1872;1424;;; +0;1872;1440;;; +0;1872;1456;;; +0;1872;1728;;; +0;1872;1984;;; +0;1888;32;;; +0;1888;64;;; +0;1888;112;;; +0;1888;128;;; +0;1888;144;;; +0;1888;160;;; +0;1888;176;;; +0;1888;192;;; +0;1888;224;;; +0;1888;240;;; +0;1888;288;;; +0;1888;336;;; +0;1888;368;;; +0;1888;384;;; +0;1888;448;;; +0;1888;800;;; +0;1888;816;;; +0;1888;832;;; +0;1888;848;;; +0;1888;864;;; +0;1888;880;;; +0;1888;896;;; +0;1888;912;;; +0;1888;976;;; +0;1888;992;;; +0;1888;1008;;; +0;1888;1024;;; +0;1888;1040;;; +0;1888;1056;;; +0;1888;1072;;; +0;1888;1088;;; +0;1888;1104;;; +0;1888;1120;;; +0;1888;1136;;; +0;1888;1152;;; +0;1888;1168;;; +0;1888;1184;;; +0;1888;1232;;; +0;1888;1904;;; +0;1888;1920;;; +0;1888;1936;;; +0;1888;1952;;; +0;1888;1968;;; +0;1888;1984;;; +0;1904;32;;; +0;1904;64;;; +0;1904;112;;; +0;1904;128;;; +0;1904;240;;; +0;1904;288;;; +0;1904;336;;; +0;1904;368;;; +0;1904;384;;; +0;1904;400;;; +0;1904;448;;; +0;1904;464;;; +0;1904;480;;; +0;1904;496;;; +0;1904;512;;; +0;1904;1232;;; +0;1904;1760;;; +0;1904;1776;;; +0;1904;1792;;; +0;1904;1808;;; +0;1904;1824;;; +0;1904;1840;;; +0;1904;1856;;; +0;1904;1872;;; +0;1904;1888;;; +0;1904;1904;;; +0;1920;32;;; +0;1920;64;;; +0;1920;112;;; +0;1920;128;;; +0;1920;240;;; +0;1920;288;;; +0;1920;336;;; +0;1920;368;;; +0;1920;384;;; +0;1920;400;;; +0;1920;480;;; +0;1920;496;;; +0;1920;512;;; +0;1920;528;;; +0;1920;544;;; +0;1920;560;;; +0;1920;576;;; +0;1920;592;;; +0;1920;608;;; +0;1920;624;;; +0;1920;640;;; +0;1920;656;;; +0;1920;672;;; +0;1920;688;;; +0;1920;704;;; +0;1920;720;;; +0;1920;736;;; +0;1920;752;;; +0;1920;768;;; +0;1920;784;;; +0;1920;800;;; +0;1920;816;;; +0;1920;832;;; +0;1920;848;;; +0;1920;864;;; +0;1920;880;;; +0;1920;896;;; +0;1920;912;;; +0;1920;928;;; +0;1920;944;;; +0;1920;960;;; +0;1920;976;;; +0;1920;992;;; +0;1920;1008;;; +0;1920;1024;;; +0;1920;1040;;; +0;1920;1056;;; +0;1920;1072;;; +0;1920;1088;;; +0;1920;1104;;; +0;1920;1120;;; +0;1920;1136;;; +0;1920;1152;;; +0;1920;1168;;; +0;1920;1184;;; +0;1920;1200;;; +0;1920;1232;;; +0;1920;1264;;; +0;1920;1280;;; +0;1920;1296;;; +0;1920;1312;;; +0;1920;1328;;; +0;1920;1344;;; +0;1920;1360;;; +0;1920;1376;;; +0;1920;1392;;; +0;1920;1408;;; +0;1920;1424;;; +0;1920;1440;;; +0;1920;1456;;; +0;1920;1472;;; +0;1920;1488;;; +0;1920;1504;;; +0;1920;1520;;; +0;1920;1536;;; +0;1920;1552;;; +0;1920;1760;;; +0;1936;32;;; +0;1936;64;;; +0;1936;112;;; +0;1936;128;;; +0;1936;240;;; +0;1936;288;;; +0;1936;336;;; +0;1936;368;;; +0;1936;384;;; +0;1936;400;;; +0;1936;480;;; +0;1936;496;;; +0;1936;512;;; +0;1936;528;;; +0;1936;544;;; +0;1936;560;;; +0;1936;576;;; +0;1936;592;;; +0;1936;608;;; +0;1936;624;;; +0;1936;640;;; +0;1936;656;;; +0;1936;672;;; +0;1936;688;;; +0;1936;704;;; +0;1936;720;;; +0;1936;736;;; +0;1936;752;;; +0;1936;768;;; +0;1936;784;;; +0;1936;800;;; +0;1936;816;;; +0;1936;832;;; +0;1936;848;;; +0;1936;864;;; +0;1936;880;;; +0;1936;896;;; +0;1936;912;;; +0;1936;928;;; +0;1936;944;;; +0;1936;960;;; +0;1936;976;;; +0;1936;992;;; +0;1936;1008;;; +0;1936;1024;;; +0;1936;1040;;; +0;1936;1056;;; +0;1936;1072;;; +0;1936;1088;;; +0;1936;1104;;; +0;1936;1120;;; +0;1936;1136;;; +0;1936;1152;;; +0;1936;1168;;; +0;1936;1184;;; +0;1936;1200;;; +0;1936;1232;;; +0;1936;1264;;; +0;1936;1424;;; +0;1936;1440;;; +0;1936;1456;;; +0;1936;1472;;; +0;1936;1488;;; +0;1936;1504;;; +0;1936;1552;;; +0;1936;1760;;; +0;1936;1952;;; +0;1936;1968;;; +0;1936;1984;;; +0;1936;2000;;; +0;1952;16;;; +0;1952;64;;; +0;1952;112;;; +0;1952;128;;; +0;1952;144;;; +0;1952;160;;; +0;1952;176;;; +0;1952;192;;; +0;1952;224;;; +0;1952;240;;; +0;1952;288;;; +0;1952;336;;; +0;1952;368;;; +0;1952;384;;; +0;1952;400;;; +0;1952;448;;; +0;1952;464;;; +0;1952;480;;; +0;1952;496;;; +0;1952;512;;; +0;1952;528;;; +0;1952;640;;; +0;1952;752;;; +0;1952;768;;; +0;1952;976;;; +0;1952;1024;;; +0;1952;1072;;; +0;1952;1136;;; +0;1952;1152;;; +0;1952;1168;;; +0;1952;1232;;; +0;1952;1264;;; +0;1952;1344;;; +0;1952;1360;;; +0;1952;1376;;; +0;1952;1408;;; +0;1952;1520;;; +0;1952;1552;;; +0;1952;1568;;; +0;1952;1584;;; +0;1952;1600;;; +0;1952;1760;;; +0;1952;1840;;; +0;1952;1856;;; +0;1952;1872;;; +0;1952;1888;;; +0;1952;1904;;; +0;1952;1920;;; +0;1952;1936;;; +0;1952;1952;;; +0;1952;2000;;; +0;1952;2016;;; +0;1968;16;;; +0;1968;64;;; +0;1968;112;;; +0;1968;128;;; +0;1968;144;;; +0;1968;160;;; +0;1968;176;;; +0;1968;192;;; +0;1968;224;;; +0;1968;272;;; +0;1968;336;;; +0;1968;368;;; +0;1968;384;;; +0;1968;400;;; +0;1968;448;;; +0;1968;528;;; +0;1968;640;;; +0;1968;752;;; +0;1968;768;;; +0;1968;800;;; +0;1968;816;;; +0;1968;832;;; +0;1968;848;;; +0;1968;976;;; +0;1968;1024;;; +0;1968;1072;;; +0;1968;1136;;; +0;1968;1152;;; +0;1968;1168;;; +0;1968;1184;;; +0;1968;1200;;; +0;1968;1232;;; +0;1968;1264;;; +0;1968;1328;;; +0;1968;1392;;; +0;1968;1408;;; +0;1968;1520;;; +0;1968;1552;;; +0;1968;1568;;; +0;1968;1584;;; +0;1968;1760;;; +0;1968;1776;;; +0;1968;1792;;; +0;1968;1808;;; +0;1968;1824;;; +0;1968;1840;;; +0;1968;2016;;; +0;1968;2032;;; +0;1984;16;;; +0;1984;48;;; +0;1984;64;;; +0;1984;224;;; +0;1984;272;;; +0;1984;320;;; +0;1984;336;;; +0;1984;368;;; +0;1984;384;;; +0;1984;400;;; +0;1984;448;;; +0;1984;528;;; +0;1984;608;;; +0;1984;624;;; +0;1984;640;;; +0;1984;656;;; +0;1984;672;;; +0;1984;688;;; +0;1984;704;;; +0;1984;752;;; +0;1984;768;;; +0;1984;800;;; +0;1984;848;;; +0;1984;976;;; +0;1984;1024;;; +0;1984;1056;;; +0;1984;1184;;; +0;1984;1200;;; +0;1984;1232;;; +0;1984;1264;;; +0;1984;1328;;; +0;1984;1392;;; +0;1984;1408;;; +0;1984;1520;;; +0;1984;1552;;; +0;1984;1568;;; +0;1984;1584;;; +0;1984;1600;;; +0;1984;2032;;; +0;2000;16;;; +0;2000;48;;; +0;2000;64;;; +0;2000;80;;; +0;2000;96;;; +0;2000;112;;; +0;2000;128;;; +0;2000;144;;; +0;2000;160;;; +0;2000;176;;; +0;2000;192;;; +0;2000;224;;; +0;2000;272;;; +0;2000;320;;; +0;2000;448;;; +0;2000;528;;; +0;2000;608;;; +0;2000;640;;; +0;2000;704;;; +0;2000;752;;; +0;2000;768;;; +0;2000;800;;; +0;2000;848;;; +0;2000;976;;; +0;2000;1024;;; +0;2000;1072;;; +0;2000;1136;;; +0;2000;1152;;; +0;2000;1232;;; +0;2000;1264;;; +0;2000;1328;;; +0;2000;1392;;; +0;2000;1408;;; +0;2000;1520;;; +0;2000;1552;;; +0;2000;1568;;; +0;2000;1584;;; +0;2000;1600;;; +0;2000;1808;;; +0;2000;1824;;; +0;2000;1840;;; +0;2000;1856;;; +0;2000;1872;;; +0;2000;1888;;; +0;2000;1904;;; +0;2000;2032;;; +0;2016;16;;; +0;2016;48;;; +0;2016;64;;; +0;2016;80;;; +0;2016;96;;; +0;2016;176;;; +0;2016;224;;; +0;2016;272;;; +0;2016;304;;; +0;2016;320;;; +0;2016;336;;; +0;2016;368;;; +0;2016;384;;; +0;2016;400;;; +0;2016;448;;; +0;2016;480;;; +0;2016;496;;; +0;2016;512;;; +0;2016;528;;; +0;2016;608;;; +0;2016;640;;; +0;2016;752;;; +0;2016;768;;; +0;2016;800;;; +0;2016;816;;; +0;2016;832;;; +0;2016;848;;; +0;2016;976;;; +0;2016;1024;;; +0;2016;1072;;; +0;2016;1136;;; +0;2016;1184;;; +0;2016;1200;;; +0;2016;1232;;; +0;2016;1264;;; +0;2016;1312;;; +0;2016;1520;;; +0;2016;1552;;; +0;2016;1808;;; +0;2016;1840;;; +0;2016;1856;;; +0;2016;1872;;; +0;2016;1904;;; +0;2016;2032;;; +0;2032;16;;; +0;2032;48;;; +0;2032;96;;; +0;2032;176;;; +0;2032;224;;; +0;2032;272;;; +0;2032;304;;; +0;2032;368;;; +0;2032;384;;; +0;2032;400;;; +0;2032;448;;; +0;2032;480;;; +0;2032;544;;; +0;2032;608;;; +0;2032;624;;; +0;2032;640;;; +0;2032;656;;; +0;2032;672;;; +0;2032;688;;; +0;2032;704;;; +0;2032;720;;; +0;2032;752;;; +0;2032;768;;; +0;2032;976;;; +0;2032;1040;;; +0;2032;1056;;; +0;2032;1072;;; +0;2032;1104;;; +0;2032;1120;;; +0;2032;1136;;; +0;2032;1152;;; +0;2032;1184;;; +0;2032;1200;;; +0;2032;1232;;; +0;2032;1264;;; +0;2032;1328;;; +0;2032;1392;;; +0;2032;1408;;; +0;2032;1520;;; +0;2032;1552;;; +0;2032;1584;;; +0;2032;1600;;; +0;2032;1808;;; +0;2032;1840;;; +0;2032;1904;;; +0;2032;2032;;; +0;2048;16;;; +0;2048;96;;; +0;2048;176;;; +0;2048;224;;; +0;2048;272;;; +0;2048;304;;; +0;2048;320;;; +0;2048;336;;; +0;2048;368;;; +0;2048;384;;; +0;2048;400;;; +0;2048;448;;; +0;2048;496;;; +0;2048;544;;; +0;2048;576;;; +0;2048;640;;; +0;2048;704;;; +0;2048;752;;; +0;2048;768;;; +0;2048;912;;; +0;2048;976;;; +0;2048;1056;;; +0;2048;1184;;; +0;2048;1200;;; +0;2048;1232;;; +0;2048;1264;;; +0;2048;1328;;; +0;2048;1392;;; +0;2048;1408;;; +0;2048;1520;;; +0;2048;1552;;; +0;2048;1584;;; +0;2048;1808;;; +0;2048;1840;;; +0;2048;1856;;; +0;2048;1872;;; +0;2048;1904;;; +0;2048;2032;;; +0;2064;16;;; +0;2064;80;;; +0;2064;96;;; +0;2064;176;;; +0;2064;224;;; +0;2064;272;;; +0;2064;320;;; +0;2064;448;;; +0;2064;496;;; +0;2064;544;;; +0;2064;640;;; +0;2064;736;;; +0;2064;752;;; +0;2064;768;;; +0;2064;832;;; +0;2064;848;;; +0;2064;912;;; +0;2064;976;;; +0;2064;1056;;; +0;2064;1072;;; +0;2064;1088;;; +0;2064;1120;;; +0;2064;1136;;; +0;2064;1152;;; +0;2064;1168;;; +0;2064;1184;;; +0;2064;1200;;; +0;2064;1232;;; +0;2064;1264;;; +0;2064;1328;;; +0;2064;1392;;; +0;2064;1408;;; +0;2064;1520;;; +0;2064;1552;;; +0;2064;1584;;; +0;2064;1600;;; +0;2064;1808;;; +0;2064;1904;;; +0;2064;2032;;; +0;2080;16;;; +0;2080;32;;; +0;2080;48;;; +0;2080;80;;; +0;2080;160;;; +0;2080;224;;; +0;2080;272;;; +0;2080;304;;; +0;2080;320;;; +0;2080;336;;; +0;2080;368;;; +0;2080;384;;; +0;2080;400;;; +0;2080;448;;; +0;2080;496;;; +0;2080;544;;; +0;2080;608;;; +0;2080;624;;; +0;2080;640;;; +0;2080;736;;; +0;2080;752;;; +0;2080;768;;; +0;2080;832;;; +0;2080;848;;; +0;2080;912;;; +0;2080;976;;; +0;2080;1056;;; +0;2080;1232;;; +0;2080;1264;;; +0;2080;1344;;; +0;2080;1360;;; +0;2080;1376;;; +0;2080;1408;;; +0;2080;1520;;; +0;2080;1552;;; +0;2080;1808;;; +0;2080;1904;;; +0;2080;2032;;; +0;2096;48;;; +0;2096;80;;; +0;2096;96;;; +0;2096;112;;; +0;2096;128;;; +0;2096;144;;; +0;2096;160;;; +0;2096;224;;; +0;2096;272;;; +0;2096;304;;; +0;2096;320;;; +0;2096;336;;; +0;2096;368;;; +0;2096;384;;; +0;2096;400;;; +0;2096;448;;; +0;2096;496;;; +0;2096;544;;; +0;2096;608;;; +0;2096;640;;; +0;2096;736;;; +0;2096;752;;; +0;2096;768;;; +0;2096;832;;; +0;2096;848;;; +0;2096;912;;; +0;2096;976;;; +0;2096;1056;;; +0;2096;1232;;; +0;2096;1264;;; +0;2096;1296;;; +0;2096;1520;;; +0;2096;1552;;; +0;2096;1808;;; +0;2096;1904;;; +0;2096;2032;;; +0;2112;48;;; +0;2112;80;;; +0;2112;144;;; +0;2112;224;;; +0;2112;272;;; +0;2112;304;;; +0;2112;320;;; +0;2112;336;;; +0;2112;368;;; +0;2112;384;;; +0;2112;400;;; +0;2112;448;;; +0;2112;480;;; +0;2112;544;;; +0;2112;608;;; +0;2112;624;;; +0;2112;640;;; +0;2112;736;;; +0;2112;752;;; +0;2112;768;;; +0;2112;832;;; +0;2112;848;;; +0;2112;928;;; +0;2112;976;;; +0;2112;1056;;; +0;2112;1168;;; +0;2112;1184;;; +0;2112;1200;;; +0;2112;1232;;; +0;2112;1264;;; +0;2112;1296;;; +0;2112;1520;;; +0;2112;1552;;; +0;2112;1568;;; +0;2112;1584;;; +0;2112;1600;;; +0;2112;1808;;; +0;2112;1824;;; +0;2112;1840;;; +0;2112;1904;;; +0;2112;2032;;; +0;2128;48;;; +0;2128;80;;; +0;2128;96;;; +0;2128;144;;; +0;2128;160;;; +0;2128;176;;; +0;2128;192;;; +0;2128;208;;; +0;2128;224;;; +0;2128;272;;; +0;2128;320;;; +0;2128;448;;; +0;2128;480;;; +0;2128;496;;; +0;2128;512;;; +0;2128;528;;; +0;2128;560;;; +0;2128;608;;; +0;2128;624;;; +0;2128;640;;; +0;2128;656;;; +0;2128;672;;; +0;2128;752;;; +0;2128;768;;; +0;2128;928;;; +0;2128;976;;; +0;2128;1040;;; +0;2128;1056;;; +0;2128;1072;;; +0;2128;1088;;; +0;2128;1104;;; +0;2128;1120;;; +0;2128;1168;;; +0;2128;1200;;; +0;2128;1232;;; +0;2128;1264;;; +0;2128;1296;;; +0;2128;1520;;; +0;2128;1552;;; +0;2128;1568;;; +0;2128;1584;;; +0;2128;1904;;; +0;2128;2032;;; +0;2144;48;;; +0;2144;80;;; +0;2144;96;;; +0;2144;176;;; +0;2144;208;;; +0;2144;224;;; +0;2144;272;;; +0;2144;320;;; +0;2144;448;;; +0;2144;528;;; +0;2144;608;;; +0;2144;624;;; +0;2144;640;;; +0;2144;672;;; +0;2144;688;;; +0;2144;752;;; +0;2144;768;;; +0;2144;848;;; +0;2144;928;;; +0;2144;976;;; +0;2144;1024;;; +0;2144;1120;;; +0;2144;1168;;; +0;2144;1200;;; +0;2144;1232;;; +0;2144;1264;;; +0;2144;1296;;; +0;2144;1520;;; +0;2144;1552;;; +0;2144;1568;;; +0;2144;1584;;; +0;2144;1600;;; +0;2144;1712;;; +0;2144;1840;;; +0;2144;1856;;; +0;2144;1872;;; +0;2144;1888;;; +0;2144;1904;;; +0;2144;2032;;; +0;2160;48;;; +0;2160;80;;; +0;2160;96;;; +0;2160;112;;; +0;2160;128;;; +0;2160;176;;; +0;2160;208;;; +0;2160;224;;; +0;2160;272;;; +0;2160;304;;; +0;2160;320;;; +0;2160;336;;; +0;2160;368;;; +0;2160;384;;; +0;2160;400;;; +0;2160;448;;; +0;2160;528;;; +0;2160;608;;; +0;2160;624;;; +0;2160;640;;; +0;2160;656;;; +0;2160;688;;; +0;2160;752;;; +0;2160;768;;; +0;2160;816;;; +0;2160;832;;; +0;2160;848;;; +0;2160;976;;; +0;2160;1040;;; +0;2160;1120;;; +0;2160;1168;;; +0;2160;1232;;; +0;2160;1264;;; +0;2160;1296;;; +0;2160;1520;;; +0;2160;1552;;; +0;2160;1568;;; +0;2160;1584;;; +0;2160;1600;;; +0;2160;1684;;; +0;2160;1696;;; +0;2160;1712;;; +0;2160;2016;;; +0;2160;2032;;; +0;2176;48;;; +0;2176;80;;; +0;2176;96;;; +0;2176;128;;; +0;2176;176;;; +0;2176;208;;; +0;2176;224;;; +0;2176;272;;; +0;2176;304;;; +0;2176;368;;; +0;2176;384;;; +0;2176;400;;; +0;2176;448;;; +0;2176;480;;; +0;2176;496;;; +0;2176;512;;; +0;2176;528;;; +0;2176;608;;; +0;2176;624;;; +0;2176;640;;; +0;2176;752;;; +0;2176;768;;; +0;2176;800;;; +0;2176;816;;; +0;2176;832;;; +0;2176;864;;; +0;2176;880;;; +0;2176;896;;; +0;2176;912;;; +0;2176;928;;; +0;2176;976;;; +0;2176;1056;;; +0;2176;1072;;; +0;2176;1088;;; +0;2176;1168;;; +0;2176;1200;;; +0;2176;1232;;; +0;2176;1264;;; +0;2176;1296;;; +0;2176;1520;;; +0;2176;1552;;; +0;2176;1568;;; +0;2176;1584;;; +0;2176;1684;;; +0;2176;1696;;; +0;2176;2000;;; +0;2176;2016;;; +0;2192;48;;; +0;2192;96;;; +0;2192;128;;; +0;2192;144;;; +0;2192;160;;; +0;2192;176;;; +0;2192;192;;; +0;2192;208;;; +0;2192;224;;; +0;2192;272;;; +0;2192;304;;; +0;2192;320;;; +0;2192;336;;; +0;2192;368;;; +0;2192;384;;; +0;2192;400;;; +0;2192;448;;; +0;2192;480;;; +0;2192;528;;; +0;2192;544;;; +0;2192;560;;; +0;2192;608;;; +0;2192;624;;; +0;2192;640;;; +0;2192;688;;; +0;2192;704;;; +0;2192;752;;; +0;2192;768;;; +0;2192;800;;; +0;2192;816;;; +0;2192;928;;; +0;2192;976;;; +0;2192;1056;;; +0;2192;1088;;; +0;2192;1120;;; +0;2192;1168;;; +0;2192;1184;;; +0;2192;1200;;; +0;2192;1232;;; +0;2192;1264;;; +0;2192;1296;;; +0;2192;1520;;; +0;2192;1552;;; +0;2192;1568;;; +0;2192;1584;;; +0;2192;1600;;; +0;2192;1684;;; +0;2192;1696;;; +0;2192;1712;;; +0;2192;1856;;; +0;2192;1872;;; +0;2192;1888;;; +0;2192;1904;;; +0;2192;1920;;; +0;2192;1936;;; +0;2192;1952;;; +0;2192;2000;;; +0;2208;48;;; +0;2208;96;;; +0;2208;176;;; +0;2208;224;;; +0;2208;272;;; +0;2208;320;;; +0;2208;448;;; +0;2208;480;;; +0;2208;528;;; +0;2208;544;;; +0;2208;560;;; +0;2208;576;;; +0;2208;608;;; +0;2208;624;;; +0;2208;640;;; +0;2208;656;;; +0;2208;672;;; +0;2208;688;;; +0;2208;752;;; +0;2208;768;;; +0;2208;800;;; +0;2208;816;;; +0;2208;880;;; +0;2208;896;;; +0;2208;976;;; +0;2208;1056;;; +0;2208;1120;;; +0;2208;1232;;; +0;2208;1264;;; +0;2208;1296;;; +0;2208;1520;;; +0;2208;1552;;; +0;2208;1824;;; +0;2208;1840;;; +0;2208;1856;;; +0;2208;1936;;; +0;2208;1952;;; +0;2208;2000;;; +0;2224;48;;; +0;2224;64;;; +0;2224;80;;; +0;2224;96;;; +0;2224;112;;; +0;2224;128;;; +0;2224;144;;; +0;2224;160;;; +0;2224;176;;; +0;2224;192;;; +0;2224;224;;; +0;2224;272;;; +0;2224;304;;; +0;2224;320;;; +0;2224;448;;; +0;2224;480;;; +0;2224;528;;; +0;2224;544;;; +0;2224;560;;; +0;2224;576;;; +0;2224;624;;; +0;2224;640;;; +0;2224;752;;; +0;2224;768;;; +0;2224;800;;; +0;2224;816;;; +0;2224;880;;; +0;2224;896;;; +0;2224;944;;; +0;2224;976;;; +0;2224;1056;;; +0;2224;1088;;; +0;2224;1120;;; +0;2224;1136;;; +0;2224;1152;;; +0;2224;1168;;; +0;2224;1184;;; +0;2224;1200;;; +0;2224;1216;;; +0;2224;1232;;; +0;2224;1264;;; +0;2224;1296;;; +0;2224;1520;;; +0;2224;1536;;; +0;2224;1808;;; +0;2224;1824;;; +0;2224;2000;;; +0;2240;160;;; +0;2240;224;;; +0;2240;272;;; +0;2240;304;;; +0;2240;448;;; +0;2240;480;;; +0;2240;528;;; +0;2240;544;;; +0;2240;560;;; +0;2240;624;;; +0;2240;640;;; +0;2240;752;;; +0;2240;768;;; +0;2240;816;;; +0;2240;880;;; +0;2240;896;;; +0;2240;944;;; +0;2240;976;;; +0;2240;1056;;; +0;2240;1088;;; +0;2240;1264;;; +0;2240;1296;;; +0;2240;1520;;; +0;2240;1552;;; +0;2240;1568;;; +0;2240;1584;;; +0;2240;1600;;; +0;2240;1616;;; +0;2240;1632;;; +0;2240;1648;;; +0;2240;1664;;; +0;2240;1680;;; +0;2240;1696;;; +0;2240;1712;;; +0;2240;1728;;; +0;2240;1808;;; +0;2240;1936;;; +0;2240;1952;;; +0;2240;2000;;; +0;2256;48;;; +0;2256;64;;; +0;2256;80;;; +0;2256;96;;; +0;2256;160;;; +0;2256;224;;; +0;2256;272;;; +0;2256;304;;; +0;2256;448;;; +0;2256;480;;; +0;2256;528;;; +0;2256;544;;; +0;2256;560;;; +0;2256;624;;; +0;2256;640;;; +0;2256;752;;; +0;2256;768;;; +0;2256;816;;; +0;2256;880;;; +0;2256;896;;; +0;2256;944;;; +0;2256;976;;; +0;2256;1056;;; +0;2256;1088;;; +0;2256;1264;;; +0;2256;1296;;; +0;2256;1520;;; +0;2256;1568;;; +0;2256;1584;;; +0;2256;1600;;; +0;2256;1616;;; +0;2256;1632;;; +0;2256;1648;;; +0;2256;1664;;; +0;2256;1712;;; +0;2256;1728;;; +0;2256;1744;;; +0;2256;1760;;; +0;2256;1776;;; +0;2256;1792;;; +0;2256;1808;;; +0;2256;1936;;; +0;2256;1952;;; +0;2256;2000;;; +0;2272;48;;; +0;2272;96;;; +0;2272;112;;; +0;2272;176;;; +0;2272;192;;; +0;2272;224;;; +0;2272;272;;; +0;2272;304;;; +0;2272;416;;; +0;2272;432;;; +0;2272;448;;; +0;2272;480;;; +0;2272;528;;; +0;2272;544;;; +0;2272;560;;; +0;2272;624;;; +0;2272;640;;; +0;2272;704;;; +0;2272;720;;; +0;2272;736;;; +0;2272;752;;; +0;2272;768;;; +0;2272;784;;; +0;2272;816;;; +0;2272;880;;; +0;2272;896;;; +0;2272;944;;; +0;2272;976;;; +0;2272;1056;;; +0;2272;1088;;; +0;2272;1264;;; +0;2272;1296;;; +0;2272;1520;;; +0;2272;1552;;; +0;2272;1648;;; +0;2272;1664;;; +0;2272;1840;;; +0;2272;1856;;; +0;2272;1872;;; +0;2272;1888;;; +0;2272;1904;;; +0;2272;1920;;; +0;2272;1936;;; +0;2272;1952;;; +0;2272;2000;;; +0;2288;48;;; +0;2288;112;;; +0;2288;128;;; +0;2288;144;;; +0;2288;160;;; +0;2288;176;;; +0;2288;192;;; +0;2288;224;;; +0;2288;272;;; +0;2288;304;;; +0;2288;448;;; +0;2288;480;;; +0;2288;528;;; +0;2288;624;;; +0;2288;640;;; +0;2288;704;;; +0;2288;752;;; +0;2288;768;;; +0;2288;784;;; +0;2288;816;;; +0;2288;848;;; +0;2288;880;;; +0;2288;896;;; +0;2288;928;;; +0;2288;944;;; +0;2288;976;;; +0;2288;1056;;; +0;2288;1088;;; +0;2288;1104;;; +0;2288;1264;;; +0;2288;1296;;; +0;2288;1520;;; +0;2288;1536;;; +0;2288;1648;;; +0;2288;1664;;; +0;2288;1696;;; +0;2288;1712;;; +0;2288;1728;;; +0;2288;1744;;; +0;2288;1840;;; +0;2288;1856;;; +0;2288;2000;;; +0;2304;48;;; +0;2304;64;;; +0;2304;112;;; +0;2304;224;;; +0;2304;272;;; +0;2304;304;;; +0;2304;320;;; +0;2304;368;;; +0;2304;384;;; +0;2304;400;;; +0;2304;416;;; +0;2304;448;;; +0;2304;480;;; +0;2304;528;;; +0;2304;624;;; +0;2304;640;;; +0;2304;704;;; +0;2304;752;;; +0;2304;768;;; +0;2304;784;;; +0;2304;848;;; +0;2304;880;;; +0;2304;896;;; +0;2304;928;;; +0;2304;976;;; +0;2304;1056;;; +0;2304;1104;;; +0;2304;1264;;; +0;2304;1296;;; +0;2304;1520;;; +0;2304;1536;;; +0;2304;1648;;; +0;2304;1664;;; +0;2304;1696;;; +0;2304;1744;;; +0;2304;1840;;; +0;2304;1856;;; +0;2304;1952;;; +0;2304;1968;;; +0;2304;2000;;; +0;2320;16;;; +0;2320;32;;; +0;2320;48;;; +0;2320;64;;; +0;2320;112;;; +0;2320;128;;; +0;2320;144;;; +0;2320;160;;; +0;2320;176;;; +0;2320;192;;; +0;2320;224;;; +0;2320;272;;; +0;2320;448;;; +0;2320;480;;; +0;2320;528;;; +0;2320;624;;; +0;2320;640;;; +0;2320;704;;; +0;2320;720;;; +0;2320;736;;; +0;2320;752;;; +0;2320;768;;; +0;2320;784;;; +0;2320;848;;; +0;2320;880;;; +0;2320;896;;; +0;2320;928;;; +0;2320;976;;; +0;2320;1056;;; +0;2320;1072;;; +0;2320;1104;;; +0;2320;1264;;; +0;2320;1296;;; +0;2320;1520;;; +0;2320;1536;;; +0;2320;1744;;; +0;2320;1760;;; +0;2320;1776;;; +0;2320;1792;;; +0;2320;1808;;; +0;2320;1824;;; +0;2320;1840;;; +0;2320;1856;;; +0;2320;2000;;; +0;2336;16;;; +0;2336;224;;; +0;2336;368;;; +0;2336;384;;; +0;2336;400;;; +0;2336;416;;; +0;2336;432;;; +0;2336;448;;; +0;2336;480;;; +0;2336;528;;; +0;2336;576;;; +0;2336;592;;; +0;2336;624;;; +0;2336;640;;; +0;2336;752;;; +0;2336;768;;; +0;2336;880;;; +0;2336;896;;; +0;2336;928;;; +0;2336;960;;; +0;2336;976;;; +0;2336;1040;;; +0;2336;1072;;; +0;2336;1104;;; +0;2336;1264;;; +0;2336;1296;;; +0;2336;1520;;; +0;2336;1536;;; +0;2336;1648;;; +0;2336;1664;;; +0;2336;1680;;; +0;2336;2000;;; +0;2352;16;;; +0;2352;32;;; +0;2352;48;;; +0;2352;64;;; +0;2352;112;;; +0;2352;128;;; +0;2352;144;;; +0;2352;160;;; +0;2352;176;;; +0;2352;192;;; +0;2352;224;;; +0;2352;272;;; +0;2352;304;;; +0;2352;320;;; +0;2352;368;;; +0;2352;384;;; +0;2352;448;;; +0;2352;480;;; +0;2352;528;;; +0;2352;576;;; +0;2352;592;;; +0;2352;624;;; +0;2352;640;;; +0;2352;736;;; +0;2352;752;;; +0;2352;768;;; +0;2352;800;;; +0;2352;880;;; +0;2352;896;;; +0;2352;928;;; +0;2352;960;;; +0;2352;976;;; +0;2352;1040;;; +0;2352;1072;;; +0;2352;1104;;; +0;2352;1264;;; +0;2352;1296;;; +0;2352;1520;;; +0;2352;1536;;; +0;2352;1648;;; +0;2352;1664;;; +0;2352;1680;;; +0;2352;1776;;; +0;2352;1792;;; +0;2352;1952;;; +0;2352;1968;;; +0;2352;2000;;; +0;2368;48;;; +0;2368;64;;; +0;2368;112;;; +0;2368;160;;; +0;2368;176;;; +0;2368;192;;; +0;2368;208;;; +0;2368;224;;; +0;2368;272;;; +0;2368;304;;; +0;2368;448;;; +0;2368;480;;; +0;2368;528;;; +0;2368;576;;; +0;2368;592;;; +0;2368;624;;; +0;2368;640;;; +0;2368;688;;; +0;2368;752;;; +0;2368;768;;; +0;2368;800;;; +0;2368;864;;; +0;2368;880;;; +0;2368;896;;; +0;2368;928;;; +0;2368;960;;; +0;2368;976;;; +0;2368;1040;;; +0;2368;1104;;; +0;2368;1264;;; +0;2368;1296;;; +0;2368;1520;;; +0;2368;1536;;; +0;2368;1648;;; +0;2368;1664;;; +0;2368;1680;;; +0;2368;1776;;; +0;2368;1792;;; +0;2368;2000;;; +0;2384;48;;; +0;2384;160;;; +0;2384;192;;; +0;2384;208;;; +0;2384;224;;; +0;2384;272;;; +0;2384;304;;; +0;2384;448;;; +0;2384;480;;; +0;2384;528;;; +0;2384;576;;; +0;2384;592;;; +0;2384;624;;; +0;2384;640;;; +0;2384;672;;; +0;2384;720;;; +0;2384;752;;; +0;2384;768;;; +0;2384;864;;; +0;2384;880;;; +0;2384;896;;; +0;2384;928;;; +0;2384;976;;; +0;2384;1040;;; +0;2384;1072;;; +0;2384;1104;;; +0;2384;1264;;; +0;2384;1296;;; +0;2384;1520;;; +0;2384;1536;;; +0;2384;1552;;; +0;2384;1648;;; +0;2384;1664;;; +0;2384;1680;;; +0;2384;1776;;; +0;2384;1792;;; +0;2384;2000;;; +0;2400;48;;; +0;2400;112;;; +0;2400;128;;; +0;2400;160;;; +0;2400;192;;; +0;2400;208;;; +0;2400;224;;; +0;2400;272;;; +0;2400;304;;; +0;2400;448;;; +0;2400;480;;; +0;2400;528;;; +0;2400;576;;; +0;2400;592;;; +0;2400;624;;; +0;2400;640;;; +0;2400;752;;; +0;2400;768;;; +0;2400;816;;; +0;2400;880;;; +0;2400;896;;; +0;2400;928;;; +0;2400;976;;; +0;2400;1040;;; +0;2400;1072;;; +0;2400;1104;;; +0;2400;1264;;; +0;2400;1296;;; +0;2400;1520;;; +0;2400;1536;;; +0;2400;1552;;; +0;2400;1568;;; +0;2400;1600;;; +0;2400;1616;;; +0;2400;1632;;; +0;2400;1648;;; +0;2400;1664;;; +0;2400;1680;;; +0;2400;1744;;; +0;2400;1760;;; +0;2400;1776;;; +0;2400;1792;;; +0;2400;2000;;; +0;2416;48;;; +0;2416;112;;; +0;2416;128;;; +0;2416;160;;; +0;2416;192;;; +0;2416;208;;; +0;2416;224;;; +0;2416;272;;; +0;2416;304;;; +0;2416;448;;; +0;2416;480;;; +0;2416;528;;; +0;2416;576;;; +0;2416;592;;; +0;2416;624;;; +0;2416;640;;; +0;2416;752;;; +0;2416;768;;; +0;2416;816;;; +0;2416;880;;; +0;2416;896;;; +0;2416;928;;; +0;2416;976;;; +0;2416;1024;;; +0;2416;1072;;; +0;2416;1104;;; +0;2416;1264;;; +0;2416;1296;;; +0;2416;1520;;; +0;2416;1536;;; +0;2416;1552;;; +0;2416;1568;;; +0;2416;1600;;; +0;2416;1616;;; +0;2416;1632;;; +0;2416;1648;;; +0;2416;1664;;; +0;2416;1680;;; +0;2416;1744;;; +0;2416;1760;;; +0;2416;1776;;; +0;2416;1792;;; +0;2416;2000;;; +0;2416;2016;;; +0;2416;2032;;; +0;2432;48;;; +0;2432;112;;; +0;2432;128;;; +0;2432;192;;; +0;2432;208;;; +0;2432;224;;; +0;2432;272;;; +0;2432;304;;; +0;2432;384;;; +0;2432;400;;; +0;2432;448;;; +0;2432;480;;; +0;2432;528;;; +0;2432;576;;; +0;2432;592;;; +0;2432;816;;; +0;2432;880;;; +0;2432;896;;; +0;2432;976;;; +0;2432;992;;; +0;2432;1008;;; +0;2432;1024;;; +0;2432;1040;;; +0;2432;1056;;; +0;2432;1072;;; +0;2432;1104;;; +0;2432;1264;;; +0;2432;1296;;; +0;2432;1520;;; +0;2432;1536;;; +0;2432;1776;;; +0;2432;1792;;; +0;2432;2000;;; +0;2432;2016;;; +0;2432;2032;;; +0;2448;48;;; +0;2448;112;;; +0;2448;160;;; +0;2448;176;;; +0;2448;192;;; +0;2448;208;;; +0;2448;224;;; +0;2448;272;;; +0;2448;304;;; +0;2448;384;;; +0;2448;448;;; +0;2448;480;;; +0;2448;528;;; +0;2448;576;;; +0;2448;592;;; +0;2448;816;;; +0;2448;880;;; +0;2448;896;;; +0;2448;1040;;; +0;2448;1104;;; +0;2448;1120;;; +0;2448;1136;;; +0;2448;1152;;; +0;2448;1168;;; +0;2448;1184;;; +0;2448;1264;;; +0;2448;1280;;; +0;2448;1296;;; +0;2448;1520;;; +0;2448;1536;;; +0;2448;1776;;; +0;2448;1792;;; +0;2448;2000;;; +0;2448;2016;;; +0;2448;2032;;; +0;2464;48;;; +0;2464;64;;; +0;2464;112;;; +0;2464;128;;; +0;2464;160;;; +0;2464;176;;; +0;2464;224;;; +0;2464;272;;; +0;2464;304;;; +0;2464;384;;; +0;2464;400;;; +0;2464;448;;; +0;2464;480;;; +0;2464;528;;; +0;2464;656;;; +0;2464;672;;; +0;2464;720;;; +0;2464;736;;; +0;2464;848;;; +0;2464;880;;; +0;2464;896;;; +0;2464;1040;;; +0;2464;1184;;; +0;2464;1520;;; +0;2464;1536;;; +0;2464;1552;;; +0;2464;1776;;; +0;2464;1792;;; +0;2464;2000;;; +0;2464;2016;;; +0;2464;2032;;; +0;2480;48;;; +0;2480;112;;; +0;2480;128;;; +0;2480;144;;; +0;2480;160;;; +0;2480;176;;; +0;2480;192;;; +0;2480;224;;; +0;2480;272;;; +0;2480;304;;; +0;2480;480;;; +0;2480;528;;; +0;2480;656;;; +0;2480;672;;; +0;2480;688;;; +0;2480;704;;; +0;2480;720;;; +0;2480;736;;; +0;2480;752;;; +0;2480;768;;; +0;2480;880;;; +0;2480;896;;; +0;2480;1040;;; +0;2480;1184;;; +0;2480;1264;;; +0;2480;1280;;; +0;2480;1296;;; +0;2480;1520;;; +0;2480;1536;;; +0;2480;1776;;; +0;2480;1792;;; +0;2480;1952;;; +0;2480;1968;;; +0;2480;1984;;; +0;2480;2000;;; +0;2480;2016;;; +0;2480;2032;;; +0;2496;48;;; +0;2496;64;;; +0;2496;112;;; +0;2496;128;;; +0;2496;144;;; +0;2496;160;;; +0;2496;224;;; +0;2496;272;;; +0;2496;304;;; +0;2496;320;;; +0;2496;336;;; +0;2496;416;;; +0;2496;432;;; +0;2496;448;;; +0;2496;480;;; +0;2496;528;;; +0;2496;592;;; +0;2496;656;;; +0;2496;672;;; +0;2496;688;;; +0;2496;704;;; +0;2496;720;;; +0;2496;736;;; +0;2496;752;;; +0;2496;768;;; +0;2496;784;;; +0;2496;800;;; +0;2496;848;;; +0;2496;880;;; +0;2496;896;;; +0;2496;976;;; +0;2496;992;;; +0;2496;1008;;; +0;2496;1024;;; +0;2496;1040;;; +0;2496;1056;;; +0;2496;1072;;; +0;2496;1088;;; +0;2496;1104;;; +0;2496;1120;;; +0;2496;1136;;; +0;2496;1152;;; +0;2496;1168;;; +0;2496;1184;;; +0;2496;1264;;; +0;2496;1296;;; +0;2496;1520;;; +0;2496;1728;;; +0;2496;1776;;; +0;2496;1792;;; +0;2496;1952;;; +0;2496;2000;;; +0;2496;2016;;; +0;2496;2032;;; +0;2512;48;;; +0;2512;96;;; +0;2512;112;;; +0;2512;128;;; +0;2512;144;;; +0;2512;160;;; +0;2512;176;;; +0;2512;224;;; +0;2512;272;;; +0;2512;336;;; +0;2512;352;;; +0;2512;368;;; +0;2512;384;;; +0;2512;400;;; +0;2512;416;;; +0;2512;480;;; +0;2512;528;;; +0;2512;560;;; +0;2512;608;;; +0;2512;656;;; +0;2512;672;;; +0;2512;720;;; +0;2512;736;;; +0;2512;848;;; +0;2512;880;;; +0;2512;896;;; +0;2512;912;;; +0;2512;976;;; +0;2512;1216;;; +0;2512;1264;;; +0;2512;1280;;; +0;2512;1296;;; +0;2512;1312;;; +0;2512;1328;;; +0;2512;1344;;; +0;2512;1360;;; +0;2512;1376;;; +0;2512;1392;;; +0;2512;1408;;; +0;2512;1520;;; +0;2512;1536;;; +0;2512;1648;;; +0;2512;1664;;; +0;2512;1728;;; +0;2512;1776;;; +0;2512;1792;;; +0;2512;1952;;; +0;2512;2000;;; +0;2512;2016;;; +0;2512;2032;;; +0;2528;48;;; +0;2528;96;;; +0;2528;112;;; +0;2528;224;;; +0;2528;272;;; +0;2528;336;;; +0;2528;480;;; +0;2528;528;;; +0;2528;576;;; +0;2528;656;;; +0;2528;672;;; +0;2528;720;;; +0;2528;736;;; +0;2528;784;;; +0;2528;800;;; +0;2528;816;;; +0;2528;832;;; +0;2528;880;;; +0;2528;896;;; +0;2528;912;;; +0;2528;976;;; +0;2528;1088;;; +0;2528;1216;;; +0;2528;1232;;; +0;2528;1248;;; +0;2528;1264;;; +0;2528;1392;;; +0;2528;1408;;; +0;2528;1424;;; +0;2528;1440;;; +0;2528;1456;;; +0;2528;1472;;; +0;2528;1488;;; +0;2528;1504;;; +0;2528;1520;;; +0;2528;1536;;; +0;2528;1552;;; +0;2528;1648;;; +0;2528;1664;;; +0;2528;1728;;; +0;2528;1744;;; +0;2528;1760;;; +0;2528;1776;;; +0;2528;1792;;; +0;2528;1808;;; +0;2528;1824;;; +0;2528;1840;;; +0;2528;1856;;; +0;2528;1872;;; +0;2528;1888;;; +0;2528;1904;;; +0;2528;1920;;; +0;2528;1936;;; +0;2528;1952;;; +0;2528;1984;;; +0;2528;2000;;; +0;2528;2016;;; +0;2528;2032;;; +0;2544;48;;; +0;2544;64;;; +0;2544;80;;; +0;2544;96;;; +0;2544;112;;; +0;2544;128;;; +0;2544;144;;; +0;2544;160;;; +0;2544;176;;; +0;2544;192;;; +0;2544;208;;; +0;2544;224;;; +0;2544;272;;; +0;2544;352;;; +0;2544;480;;; +0;2544;528;;; +0;2544;880;;; +0;2544;896;;; +0;2544;912;;; +0;2544;928;;; +0;2544;976;;; +0;2544;1088;;; +0;2544;1104;;; +0;2544;1120;;; +0;2544;1136;;; +0;2544;1152;;; +0;2544;1168;;; +0;2544;1184;;; +0;2544;1200;;; +0;2544;1216;;; +0;2544;1232;;; +0;2544;1248;;; +0;2544;1264;;; +0;2544;1280;;; +0;2544;1296;;; +0;2544;1312;;; +0;2544;1328;;; +0;2544;1344;;; +0;2544;1360;;; +0;2544;1520;;; +0;2544;1536;;; +0;2544;1552;;; +0;2544;1568;;; +0;2544;1584;;; +0;2544;1600;;; +0;2544;1616;;; +0;2544;1632;;; +0;2544;1648;;; +0;2544;1664;;; +0;2544;1984;;; +0;2544;2000;;; +0;2544;2016;;; +0;2544;2032;;; +0;2560;288;;; +0;2560;304;;; +0;2560;320;;; +0;2560;336;;; +0;2560;352;;; +0;2560;368;;; +0;2560;384;;; +0;2560;400;;; +0;2560;416;;; +0;2560;432;;; +0;2560;448;;; +0;2560;464;;; +0;2560;544;;; +0;2560;560;;; +0;2560;576;;; +0;2560;592;;; +0;2560;608;;; +0;2560;624;;; +0;2560;640;;; +0;2560;656;;; +0;2560;672;;; +0;2560;688;;; +0;2560;704;;; +0;2560;720;;; +0;2560;736;;; +0;2560;752;;; +0;2560;768;;; +0;2560;784;;; +0;2560;800;;; +0;2560;816;;; +0;2560;832;;; +0;2560;848;;; +0;2560;864;;; +0;2560;880;;; +0;2560;896;;; +0;2560;912;;; +0;2560;928;;; +0;2560;944;;; +0;2560;960;;; +0;2560;1360;;; +0;2560;1376;;; +0;2560;1392;;; +0;2560;1408;;; +0;2560;1424;;; +0;2560;1440;;; +0;2560;1456;;; +0;2560;1472;;; +0;2560;1488;;; +0;2560;1504;;; +0;2560;1520;;; +0;2560;1536;;; +0;2560;1552;;; +0;2560;1568;;; +0;2560;1584;;; +0;2560;1600;;; +0;2560;1616;;; +0;2560;1632;;; +0;2560;1648;;; +0;2560;1664;;; +0;2560;1680;;; +0;2560;1696;;; +0;2560;1712;;; +0;2560;1728;;; +0;2560;1744;;; +0;2560;1760;;; +0;2560;1776;;; +0;2560;1792;;; +0;2560;1808;;; +0;2560;1824;;; +0;2560;1840;;; +0;2560;1856;;; +0;2560;1872;;; +0;2560;1888;;; +0;2560;1904;;; +0;2560;1920;;; +0;2560;1936;;; +0;2560;1952;;; +0;2560;1968;;; +0;2560;1984;;; +0;2560;2000;;; +0;2560;2016;;; +0;2560;2032;;; +1;256;432;;; +1;272;432;;; +1;272;1328;;; +1;288;432;;; +1;400;1456;;; +1;416;1456;;; +1;432;1456;;; +1;672;496;;; +1;688;480;;; +1;688;1312;;; +1;704;1312;;; +1;720;1312;;; +1;1168;416;;; +1;1328;1856;;; +1;1344;1856;;; +1;1360;1072;;; +1;1360;1856;;; +1;1376;1072;;; +1;1392;1072;;; +1;1472;112;;; +1;1872;1712;;; +1;1888;1712;;; +1;2032;1760;;; +1;2048;1760;;; +1;2064;1760;;; +1;2080;1760;;; +1;2096;1760;;; +1;2112;1760;;; +1;2144;1760;;; +1;2176;1744;;; +3;80;1360;;; +4;112;1360;;; +4;2192;1728;;; +4;2208;1600;;; +4;2208;1616;;; +4;2208;1632;;; +4;2208;1648;;; +4;2208;1664;;; +4;2208;1680;;; +4;2208;1696;;; +2;256;1328;;; +2;2016;1584;;; +2;2080;1584;;; +2;2096;1584;;; +17;240;1344;;; +17;2160;1744;;; +236;2304;1728 +236;2352;1696 +236;2432;1616 +236;2448;1584 +236;2448;1616 +236;2448;1648 +236;2448;1664 +236;2464;1616 +236;2464;1648 +236;2464;1664 +236;2464;1680 +236;2480;1600 +236;2480;1696 +236;2480;1840 +236;2496;1600 +236;2496;1712 +236;2512;1600 +78;1456;592;;;; +78;1472;592;;;; +78;1488;592;;;; +78;1504;592;;;; +78;1520;592;;;; +78;1536;592;;;; +78;1552;592;;;; +78;1568;592;;;; +78;1584;592;;;; +78;1600;592;;;; +79;1424;608;;;; +79;1440;592;;;; +80;1616;592;;;; +80;1632;608;;;; +81;1424;624;;;; +81;1440;624;;;; +81;1616;624;;;; +81;1632;624;;;; +82;1456;608;;;; +82;1456;624;;;; +82;1472;608;;;; +82;1472;624;;;; +82;1488;608;;;; +82;1488;624;;;; +82;1504;608;;;; +82;1504;624;;;; +82;1520;608;;;; +82;1520;624;;;; +82;1520;640;;;; +82;1536;608;;;; +82;1536;624;;;; +82;1536;640;;;; +82;1552;608;;;; +82;1552;624;;;; +82;1552;640;;;; +82;1568;608;;;; +82;1568;624;;;; +82;1584;608;;;; +82;1584;624;;;; +82;1600;608;;;; +82;1600;624;;;; +83;1440;608;;;; +83;1616;608;;;; +235;1520;912;ow_castle_door +199;240;560;dkey1;;dkey1Collected;1; +199;672;400;ruby50;;ow_ruby50_swamp;2; +199;736;64;ruby50;;ow_ruby50_mountain;2; +199;928;1824;ruby50;;ow_beach_rupees50;2; +199;1368;140;ruby50;;cave15_outside_r50;2; +199;2000;672;ruby20;;ow_chest_ride_0;; +199;2192;656;ruby20;;ow_chest_ride_1;; +6;2208;1584;;; +7;80;1376;;; +8;112;1376;;; +8;2160;1760;;; +8;2192;1744;;; +8;2208;1712;;; +28;944;328;;;; +28;944;336;;;; +28;1056;312;;;; +28;1056;320;;;; +28;1184;312;;;; +28;1184;320;;;; +90;1520;1696;;;; +56;1952;1104;;;;;; +56;1984;1440;;;;;; +56;1984;1456;;;;;; +56;1984;1472;;;;;; +56;2000;1440;;;;;; +56;2016;1104;;;;;; +56;2016;1440;;;;;; +56;2032;1408;;;;;; +56;2032;1424;;;;;; +56;2048;1472;;;;;; +56;2048;1488;;;;;; +56;2064;1472;;;;;; +56;2080;1472;;;;;; +56;2096;1296;;;;;; +56;2096;1312;;;;;; +56;2096;1328;;;;;; +56;2096;1344;;;;;; +56;2096;1360;;;;;; +56;2096;1376;;;;;; +56;2096;1392;;;;;; +56;2096;1472;;;;;; +56;2112;1472;;;;;; +56;2128;1472;;;;;; +56;2144;1344;;;;;; +56;2144;1360;;;;;; +56;2144;1376;;;;;; +56;2144;1392;;;;;; +56;2144;1408;;;;;; +56;2144;1424;;;;;; +56;2144;1440;;;;;; +56;2144;1456;;;;;; +56;2144;1472;;;;;; +56;2176;1296;;;;;; +56;2176;1312;;;;;; +56;2176;1328;;;;;; +56;2176;1344;;;;;; +56;2192;1456;;;;;; +56;2192;1472;;;;;; +56;2192;1488;;;;;; +56;2208;1344;;;;;; +56;2208;1360;;;;;; +56;2208;1376;;;;;; +56;2208;1392;;;;;; +56;2208;1456;;;;;; +56;2224;1392;;;;;; +56;2224;1456;;;;;; +56;2240;1344;;;;;; +56;2240;1392;;;;;; +56;2240;1456;;;;;; +56;2256;1344;;;;;; +56;2256;1392;;;;;; +56;2256;1456;;;;;; +56;2272;1392;;;;;; +56;2288;1392;;;;;; +56;2288;1440;;;;;; +56;2288;1456;;;;;; +56;2288;1472;;;;;; +56;2288;1488;;;;;; +56;2304;1392;;;;;; +56;2320;1392;;;;;; +56;2336;1296;;;;;; +56;2336;1312;;;;;; +56;2336;1328;;;;;; +56;2336;1344;;;;;; +56;2336;1360;;;;;; +56;2336;1376;;;;;; +56;2336;1392;;;;;; +56;2352;1392;;;;;; +56;2368;1392;;;;;; +56;2368;1408;;;;;; +56;2368;1424;;;;;; +56;2368;1440;;;;;; +56;2368;1456;;;;;; +56;2384;1392;;;;;; +56;2384;1456;;;;;; +56;2400;1392;;;;;; +56;2400;1456;;;;;; +56;2416;1392;;;;;; +56;2416;1456;;;;;; +56;2448;1296;;;;;; +56;2448;1312;;;;;; +56;2448;1328;;;;;; +56;2448;1344;;;;;; +56;2448;1392;;;;;; +56;2448;1408;;;;;; +56;2448;1456;;;;;; +56;2480;1328;;;;;; +56;2480;1344;;;;;; +56;2480;1392;;;;;; +56;2480;1408;;;;;; +56;2480;1456;;;;;; +197;1200;1216;;ow_bigSkullStone +174;-16;96;overworld +174;48;656;toadstool_check +390;288;1296 +390;384;1248 +390;528;1440 +153;64;1440;;;l1;library.map;l1;3;; +153;80;64;;;d8_left;dungeon8.map;d8_left;3;;False +153;96;128;;;d8;dungeon8.map;d8;3;; +153;96;144;;;d8Finished;;;3;4; +153;96;1364;;;cave0;;;3;1; +153;128;416;;;h8;house8.map;h8;3;; +153;144;288;;;c5_1;cave5.map;c5_1;3;; +153;144;672;;;c1n;cave1.map;c1n;3;; +153;192;288;;;c5_2;cave5.map;c5_2;3;; +153;224;1328;;;h3m;house3m.map;h3m;3;; +153;240;1488;;;h2;house2.map;h2;3;; +153;256;1328;15;;h3n;house3n.map;h3n;3;; +153;272;152;;;1;helphouse1.map;1;3;; +153;272;448;;;2;helphouse2.map;2;3;; +153;272;1104;;;pond;;;-1;1; +153;384;64;;;d8_right;dungeon8.map;d8_right;3;;False +153;384;560;;;c4;cave4.map;c4;3;; +153;416;1088;;;h4-1;house4.map;h4-1;3;; +153;416;1216;;;cave_rooster;cave rooster.map;cave_rooster;3;1; +153;416;1344;;;h1;house1.map;h1;3;; +153;416;1472;;;5;helphouse5.map;5;3;; +153;448;672;;;bc1;caveBat1.map;bc1;3;1; +153;448;816;;;c1m;cave1.map;c1m;3;; +153;448;1088;;;h4-2;house4.map;h4-2;3;; +153;528;1072;;;dreamShrine01;dreamShrine01.map;dreamShrine01;3;; +153;560;64;;;cave_20_top;cave20.map;cave_20_top;3;; +153;560;1232;;;s1;shop1.map;s1;3;; +153;560;1824;;;h6;house6.map;h6;3;; +153;576;128;;;cave_20;cave20.map;cave_20;3;; +153;576;1472;;;s2;shop2.map;s2;3;; +153;592;1680;;;d1;dungeon1.map;d1;3;; +153;592;1696;;;d1Finished;;;3;4; +153;672;1936;;;cave8;cave8.map;cave8;3;; +153;704;272;;;d2;dungeon2.map;d2;3;; +153;704;288;;;d2Finished;;;3;4; +153;704;1328;;;8;helphouse8.map;8;3;; +153;800;1104;;;cave6;cave6.map;cave6;3;; +153;864;592;;;ocarina_entry;;;-1;1; +153;864;944;;;cave10_l;cave10.map;cave10_l;3;1; +153;880;800;;;s3;shop3.map;s3;3;; +153;912;448;;;cave2;cave2.map;cave2;3;; +153;912;1424;;;d3;dungeon3_1.map;d3;3;; +153;912;1440;;;d3Finished;;;3;4; +153;944;176;;;cave_19_left;cave19.map;cave_19_left;3;; +153;944;560;;;h9;house9.map;h9;3;; +153;992;1072;;;cave11;cave11.map;cave11;3;; +153;1024;1600;;;ce3w;cave3_2.map;ce3w;3;; +153;1040;1728;;;h7;house7.map;h7;3;; +153;1040;1840;;;bc3;caveBat3.map;bc3;2;1; +153;1056;48;;;egg_entry;egg_entry.map;egg_entry;3;1; +153;1056;1968;;;hauntedhouse;hauntedhouse.map;hauntedhouse;3;; +153;1072;960;;;cave10_r;;;3;4; +153;1168;1024;;;fc1;caveFairy1.map;fc1;3;; +153;1184;64;;;cave_24_right;cave24.map;cave_24_right;3;1; +153;1184;160;;;cave_13;cave13.map;cave_13_left;3;; +153;1200;432;;;photoHouse;photoHouse.map;photoHouse;3;; +153;1232;1808;;;cave30_left;cave30.map;cave30_left;;1; +153;1248;928;;;dc_entry;;;3;4; +153;1248;928;;;cloakOut;;;3;4; +153;1328;992;;;cave33;cave33.map;cave33;-1;1; +153;1328;1600;;;cave7down;cave7.map;cave7down;3;; +153;1344;1872;;;6;helphouse6.map;6;3;; +153;1376;1088;;;4;helphouse4.map;4;3;; +153;1376;1440;;;cave7_2;cave7_2.map;cave7_2;3;; +153;1392;128;;;cave_15_1;cave15.map;cave_15_1;3;; +153;1408;1488;;;cave7up;cave7.map;cave7up;3;; +153;1424;128;;;cave_15_2;cave15.map;cave_15_2;3;; +153;1472;672;;;c2_1;castle2.map;c2_1;3;; +153;1488;1744;;;d5_entry_left;dungeon5_entry.map;left;-1;3;False +153;1520;1744;;;d5_entry_right;dungeon5_entry.map;right;-1;3;False +153;1536;688;;;c2_2;castle2.map;c2_2;3;; +153;1536;816;;;c1_1;castle1.map;c1_1;3;; +153;1536;1712;;;d5;dungeon5.map;d5;3;; +153;1536;1728;;;d5Finished;;;3;4; +153;1552;576;;;tunelcastleleft;castleTunnel.map;tunelcastleleft;2;1; +153;1552;1824;;;caveMirror;caveMirror.map;caveMirror;3;1; +153;1568;1984;;;cave30_right;cave30.map;cave30_right;-1;1; +153;1584;176;;;cave_16;cave16.map;cave_16;3;; +153;1632;96;;;cave_17_ow;cave17.map;cave_17_ow;3;; +153;1680;16;;;house_mountain;house mountain.map;house_mountain;3;; +153;1696;1072;;;shellhouse;shellhouse.map;shellhouse;3;; +153;1712;288;;;underwater_fish;underwater fish.map;underwater_fish;3;; +153;1712;1824;;;bridge;bridge.map;bridge;-1;3;False +153;1728;96;;;cave_25;cave25.map;cave_25;3;; +153;1744;544;;;tunelcastleright;castleTunnel.map;tunelcastleright;3;1; +153;1840;272;;;d4;dungeon4.map;d4;3;; +153;1840;288;;;d4Finished;;;3;4; +153;1840;528;;;3;helphouse3.map;3;3;; +153;1872;288;;;cave_18_left;cave18.map;cave_18_left;3;1; +153;1888;1344;;;cave9right;cave9.map;cave9right;3;1; +153;1888;1728;;;7;helphouse7.map;7;3;; +153;1968;1600;;;h10;house10.map;h10;3;; +153;1984;1072;;;d6;dungeon6.map;d6;3;; +153;1984;1088;;;d6Finished;;;3;4; +153;2000;816;;;d6_top;dungeon6.map;d6_top;3;1;False +153;2016;1152;;;cave32_left;cave32.map;cave32_left;3;; +153;2016;1328;;;desertTemple;desertTemple.map;desertTemple;3;; +153;2048;1600;;;h11;house11.map;h11;3;; +153;2112;96;;;cave_27_exit;cave27.map;cave_27_exit;3;; +153;2112;160;;;cave_23_left;cave23.map;cave_23_left;3;; +153;2128;1184;;;;cave32.map;cave32_right;-1;1; +153;2128;1600;;;h12;house12.map;h12;3;; +153;2144;1040;;;fc2;caveFairy2.map;fc2;3;; +153;2144;1188;;;cave32_right;;;2;4; +153;2176;320;;;cave_18_right;cave18.map;cave_18_right;3;1; +153;2176;1600;;;h13;house13.map;h13;3;; +153;2176;1712;;;h14;house14.map;h14;3;; +153;2208;192;;;cave_23_right;cave23.map;cave_23_right;3;; +153;2224;1552;;;caveVillage;caveVillage.map;caveVillage;3;; +153;2304;128;;;cave_21_0;cave21.map;cave_21_0;3;; +153;2320;1360;;;;caveTemple.map;caveTemple;3;1; +153;2320;1376;;;caveTemple;;;3;4; +153;2336;32;;;d7;dungeon7_1.map;d7;3;; +153;2336;48;;;d7Finished;;;3;4; +153;2336;272;;;cave_29;cave29.map;cave_29;3;; +153;2368;128;;;cave_21_1;cave21.map;cave_21_1;3;; +153;2416;1040;;;cave31;cave31.map;cave31;3;; +153;2432;352;;;cave31_up;cave31.map;cave31_up;-1;1; +153;2448;128;;;cave_21_2;cave21.map;cave_21_2;3;; +153;2448;400;;;house_raft;house raft.map;house_raft;3;; +153;2464;192;;;fcm;caveFairyMountain.map;fcm;3;; +153;2480;64;;;cave_28;cave28.map;cave_28;3;; +153;2496;176;;;cave_22_exit;cave22.map;cave_22_exit;3;; +153;2496;1536;;;cave12;cave12.map;cave12;3;; +153;2528;128;;;cave_26;cave26.map;cave_26;3;; +155;1056;48;ow_egg_entry +69;2272;64;;;;;-8.-12.16.12; +264;2320;16;ow_d7_tower +262;592;1680;;ow_de1 +262;912;1424;;ow_de3 +251;592;1744;dkey1;ow_de1;keyhole_0 +251;912;1488;dkey2;ow_de3;keyhole_1 +251;1840;336;dkey3;ow_de4;keyhole_2 +251;2048;1056;dkey3;ow_de_6;keyhole_3 +49;560;1712;;;;;; +49;624;1712;;;;;; +50;592;1728;;;;;; +263;1952;1024;ow_de_6 +454;1552;1104 +458;384;336 +458;448;416 +458;528;432 +458;560;336 +458;736;400 +421;1696;704 +481;688;128;280; +445;720;688 +445;1424;1776 +445;1680;1968 +445;1712;1584 +445;1744;1712 +445;1744;1744 +445;1840;1200 +445;1904;1136 +448;1056;832;True; +448;1056;928;True; +448;1200;928;True; +448;1216;832;True; +452;1024;1184 +452;1040;1072 +452;1040;1104 +452;1072;1232 +452;1088;1056 +452;1168;1184 +452;1520;1072 +406;48;304;e16; +406;48;1856;e2; +406;48;1952;e2; +406;64;144;e_raven; +406;64;448;e5; +406;80;544;e5; +406;80;1808;e2; +406;80;1984;e3; +406;96;288;e5; +406;96;320;e16; +406;96;816;e5; +406;96;848;e5; +406;112;32;e_raven; +406;112;592;e5; +406;112;944;e5; +406;128;96;e12; +406;128;144;e_raven; +406;128;928;e5; +406;128;1680;e2; +406;128;1984;e3; +406;208;416;e5; +406;208;464;e16; +406;208;928;e5; +406;208;960;e15; +406;224;80;e_raven; +406;224;176;e5; +406;224;336;e5; +406;224;480;e5; +406;224;800;e5; +406;224;1584;e2; +406;224;1728;e2; +406;224;1824;e1; +406;224;1936;e2; +406;224;1952;e3; +406;240;816;e5; +406;240;1616;e2; +406;256;1984;e3; +406;272;304;e16; +406;272;336;e5; +406;272;992;e15; +406;272;1856;e1; +406;288;1712;e2; +406;288;1856;e1; +406;368;176;e3; +406;368;704;moblinSword; +406;368;960;e5; +406;368;1872;e1; +406;368;1888;e1; +406;368;1968;e1; +406;384;144;e3; +406;384;1552;e2; +406;400;96;shroudedStalfos; +406;400;592;e15; +406;416;160;e16; +406;416;576;e15; +406;416;704;e5; +406;416;864;e5; +406;416;1872;e2; +406;432;960;e5; +406;432;1568;e2; +406;432;1616;e2; +406;432;1824;e2; +406;448;352;goponga_flower; +406;448;576;e5; +406;464;304;goponga_flower; +406;528;1616;e2; +406;528;1968;e4; +406;544;96;e3; +406;544;560;e5; +406;560;192;shroudedStalfos; +406;560;928;e5; +406;560;1568;e2; +406;576;208;e16; +406;576;304;goponga_flower_giant; +406;576;416;goponga_flower; +406;576;592;e5; +406;576;944;e5; +406;592;1984;e4; +406;608;400;goponga_flower_giant; +406;608;816;e5; +406;608;1600;e2; +406;672;1360;e_wingedOctorok; +406;688;288;goponga_flower; +406;688;304;goponga_flower; +406;688;1472;e_moblinPigSword; +406;688;1696;e9;$ +406;704;80;e12; +406;704;208;e12; +406;704;320;goponga_flower; +406;704;1568;e9;$ +406;720;288;goponga_flower; +406;720;304;goponga_flower; +406;720;1600;e9;$ +406;720;1952;e3; +406;752;1344;e_wingedOctorok; +406;752;1616;e15; +406;752;1712;e_spinyBeetle; +406;752;1952;e3; +406;768;688;e17; +406;784;1952;e4; +406;864;320;e19; +406;864;1600;e9;$ +406;864;1712;e9;$ +406;880;1328;e_wingedOctorok; +406;880;1696;e9;$ +406;880;1760;e_spinyBeetle; +406;896;64;e12; +406;896;336;e19; +406;896;1184;e_wingedOctorok; +406;896;1376;e_wingedOctorok; +406;928;1728;e9;$ +406;944;1616;e9;$ +406;1024;672;e20; +406;1040;592;e20; +406;1056;688;e20; +406;1088;560;e20; +406;1184;592;e20; +406;1184;672;e20; +406;1200;1840;e17; +406;1232;544;e20; +406;1232;704;e20; +406;1328;448;e19; +406;1328;1072;e_wingedOctorok; +406;1328;1168;e_wingedOctorok; +406;1328;1456;e_bomber; +406;1328;1712;e_bomber; +406;1344;304;e19; +406;1344;336;e19; +406;1344;1840;e17; +406;1360;656;e20;True +406;1360;864;e_darknut; +406;1360;1376;e_wingedOctorok; +406;1360;1600;e19; +406;1376;1200;e_wingedOctorok; +406;1376;1584;e19; +406;1392;560;e_darknutSpear; +406;1392;1344;e_wingedOctorok; +406;1392;1856;e17; +406;1408;704;e_darknut; +406;1408;1056;e_wingedOctorok; +406;1408;1440;e_bomber; +406;1424;1232;e_bomber; +406;1488;1440;e19; +406;1488;1472;e19; +406;1504;1200;e_wingedOctorok; +406;1504;1328;e19; +406;1520;1360;e19; +406;1536;336;e19; +406;1536;432;e19; +406;1552;448;e19; +406;1552;1232;e_wingedOctorok; +406;1552;1344;e19; +406;1552;1440;e19; +406;1648;48;e_tektite; +406;1648;816;e_darknut; +406;1648;1952;e17; +406;1680;352;e_tektite; +406;1680;416;e19; +406;1680;448;e_tektite; +406;1680;1104;e19; +406;1680;1232;e_moblinPigSword; +406;1696;560;e_darknut; +406;1712;48;e_tektite; +406;1712;864;e_darknut; +406;1712;1104;e19; +406;1712;1216;e19; +406;1712;1888;e17; +406;1728;352;e_tektite; +406;1728;1232;e19; +406;1808;16;e_tektite; +406;1808;1344;e17; +406;1808;1712;e_bomber; +406;1808;1840;e17; +406;1808;1952;e_spinyBeetle; +406;1824;1840;e_bomber; +406;1840;1712;e_spinyBeetle; +406;1840;1952;e17; +406;1856;1744;e_spinyBeetle;1 +406;1872;80;e_tektite; +406;1872;1856;e17; +406;1888;432;e_bomber; +406;1904;1312;e17; +406;1968;1424;e_armos; +406;1968;1472;e9;$ +406;1984;1376;e_armos; +406;1984;1424;e9;$ +406;2000;336;e_tektite; +406;2000;1504;e_armos; +406;2032;1504;e9;$ +406;2048;48;e_spinyBeetle;1 +406;2048;1376;e_armos; +406;2064;416;e_tektite; +406;2096;432;e_tektite; +406;2128;1184;e_armos;True +406;2128;1440;e_armos; +406;2128;1456;e9;$ +406;2144;160;e_tektite; +406;2144;336;e16; +406;2144;1312;e_armos; +406;2160;1248;e_bomber; +406;2160;1312;e9;$ +406;2160;1344;e9;$ +406;2160;1472;e_armos; +406;2176;1440;e9;$ +406;2192;432;e_tektite; +406;2192;1312;e9;$ +406;2192;1344;e9;$ +406;2192;1440;e_armos; +406;2208;1312;e_armos; +406;2208;1488;e_armos; +406;2272;1472;e9;$ +406;2288;1424;e_armos; +406;2304;1088;e_bomber; +406;2304;1216;e_tektite; +406;2304;1488;e9;$ +406;2320;1328;e_armos; +406;2320;1360;e_armos; +406;2320;1424;e_armos; +406;2320;1712;e3; +406;2336;1056;e_bomber; +406;2352;208;e_tektite; +406;2352;416;e16; +406;2352;1232;e_tektite; +406;2352;1328;e_armos; +406;2352;1360;e_armos; +406;2352;1472;e_armos; +406;2352;1488;e9;$ +406;2368;320;e16; +406;2368;432;e16; +406;2368;1696;e3; +406;2368;1744;e3; +406;2432;1456;e_armos; +406;2448;80;e_tektite; +406;2448;1712;e3; +406;2448;1984;e3; +406;2464;320;e2; +406;2464;1440;e15; +406;2464;1488;e_armos; +406;2464;1584;e3; +406;2464;1760;e_pokey; +406;2464;1872;e_pokey; +406;2464;1952;e3; +406;2480;336;e2; +406;2480;1216;e_bomber; +406;2496;1456;e_armos; +406;2496;1568;e3; +406;2496;1760;e3; +406;2512;1440;e9;$ +406;2512;1856;e_pokey; +406;2528;80;e_tektite; +406;2528;208;e_tektite; +406;2528;1200;e_tektite; +406;2528;1712;e_pokey; +22;64;1440;;;; +22;80;64;;;; +22;96;128;;;; +22;128;416;;;; +22;144;288;;;; +22;144;672;;;; +22;192;288;;;; +22;224;624;;;; +22;224;768;;;; +22;224;1328;;;; +22;240;624;;;; +22;240;768;;;; +22;240;1488;;;; +22;256;624;;;; +22;256;768;;;; +22;256;1328;;;; +22;272;152;;;; +22;272;448;;;; +22;272;624;;;; +22;272;768;;;; +22;368;320;;;; +22;368;336;;;; +22;368;352;;;; +22;368;368;;;; +22;368;384;;;; +22;368;400;;;; +22;368;416;;;; +22;384;64;;;; +22;384;288;;;; +22;384;304;;;; +22;384;432;;;; +22;384;560;;;; +22;400;432;;;; +22;400;448;;;; +22;416;464;;;; +22;416;1088;;;; +22;416;1344;;;; +22;416;1472;;;; +22;432;464;;;; +22;448;816;;;; +22;448;1088;;;; +22;464;432;;;; +22;496;0;;;; +22;496;16;;;; +22;496;32;;;; +22;496;48;;;; +22;496;64;;;; +22;512;0;;;; +22;512;16;;;; +22;512;32;;;; +22;512;48;;;; +22;512;64;;;; +22;512;416;;;; +22;528;0;;;; +22;528;16;;;; +22;528;32;;;; +22;528;48;;;; +22;528;64;;;; +22;528;1072;;;; +22;544;0;;;; +22;544;16;;;; +22;544;32;;;; +22;544;48;;;; +22;544;896;;;; +22;560;0;;;; +22;560;16;;;; +22;560;32;;;; +22;560;64;;;; +22;560;896;;;; +22;560;1232;;;; +22;560;1824;;;; +22;576;0;;;; +22;576;16;;;; +22;576;32;;;; +22;576;48;;;; +22;576;128;;;; +22;576;896;;;; +22;576;1472;;;; +22;592;0;;;; +22;592;16;;;; +22;592;32;;;; +22;592;48;;;; +22;592;64;;;; +22;592;896;;;; +22;592;1680;;;; +22;608;0;;;; +22;608;16;;;; +22;608;32;;;; +22;608;48;;;; +22;608;64;;;; +22;624;0;;;; +22;624;16;;;; +22;624;32;;;; +22;624;48;;;; +22;624;64;;;; +22;640;0;;;; +22;640;16;;;; +22;640;32;;;; +22;640;48;;;; +22;640;64;;;; +22;672;1936;;;; +22;704;272;;;; +22;704;432;;;; +22;704;448;;;; +22;704;464;;;; +22;704;1328;;;; +22;720;416;;;; +22;736;288;;;; +22;736;304;;;; +22;736;416;;;; +22;752;320;;;; +22;752;336;;;; +22;752;352;;;; +22;752;400;;;; +22;800;1104;;;; +22;912;448;;;; +22;944;176;;;; +22;944;560;;;; +22;1040;1728;;;; +22;1056;48;;;; +22;1056;1968;;;; +22;1184;160;;;; +22;1200;432;;;; +22;1328;1600;;;; +22;1344;1872;;;; +22;1376;1088;;;; +22;1392;128;;;; +22;1408;1488;;;; +22;1424;128;;;; +22;1536;816;;;; +22;1584;176;;;; +22;1632;96;;;; +22;1680;16;;;; +22;1696;1072;;;; +22;1712;288;;;; +22;1712;1824;;;; +22;1728;96;;;; +22;1760;992;;;; +22;1824;1024;;;; +22;1840;272;;;; +22;1840;1024;;;; +22;1856;1024;;;; +22;1872;1024;;;; +22;1888;1728;;;; +22;1968;1600;;;; +22;1984;1072;;;; +22;2016;1152;;;; +22;2016;1328;;;; +22;2032;320;;;; +22;2048;1600;;;; +22;2112;96;;;; +22;2112;160;;;; +22;2128;1600;;;; +22;2176;320;;;; +22;2176;1600;;;; +22;2176;1712;;;; +22;2208;192;;;; +22;2304;128;;;; +22;2320;1664;;;; +22;2336;32;;;; +22;2368;128;;;; +22;2416;1584;;;; +22;2448;128;;;; +22;2448;400;;;; +22;2480;64;;;; +22;2496;176;;;; +22;2496;1536;;;; +22;2528;128;;;; +394;568;684; +138;1168;416;3 +138;1168;432;11 +138;2016;1584;3 +138;2032;1760;3 +138;2048;1760;3 +138;2064;1760;3 +138;2080;1584;3 +138;2080;1760;3 +138;2096;1584;3 +138;2096;1760;3 +138;2112;1760;3 +138;2144;1760;3 +138;2160;1744;1 +138;2160;1760;7 +138;2176;1744;3 +138;2192;1728;5 +138;2192;1744;7 +138;2208;1584;3 +138;2208;1600;5 +138;2208;1616;5 +138;2208;1632;5 +138;2208;1648;5 +138;2208;1664;5 +138;2208;1680;5 +138;2208;1696;5 +138;2208;1712;7 +150;404;1373; +150;468;1341; +150;1940;1584; +150;1956;1744; +149;240;1344; +145;272;1328; +144;80;1376; +144;372;1373; +144;1940;1744; +146;112;1376; +146;460;1373; +142;80;1360; +142;372;1317; +142;372;1333; +142;372;1349; +142;372;1365; +142;468;1301; +142;468;1357; +142;1940;1600; +142;1940;1632; +142;1940;1648; +142;1940;1664; +142;1940;1680; +142;1940;1696; +142;1940;1712; +142;1940;1728; +143;112;1360; +140;388;1301; +140;388;1381; +140;404;1301; +140;420;1301; +140;436;1301; +140;436;1381; +140;452;1301; +140;452;1381; +139;372;1301; +366;272;1087 +115;32;448;;;;;; +115;48;400;;;;;; +115;48;1408;;;;;; +115;64;1376;;;;;; +115;96;1616;;;;;; +115;128;1248;;;;;; +115;128;1568;;;;;; +115;144;1456;;;;;; +115;160;1344;;;;;; +115;192;1664;;;;;; +115;208;416;;;;;; +115;208;1232;;;;;; +115;208;1360;;;;;; +115;208;1632;;;;;; +115;224;1120;;;;;; +115;224;1424;;;;;; +115;224;1744;;;;;; +115;240;1680;;;;;; +115;256;1184;;;;;; +115;256;1552;;;;;; +115;288;1088;;;;;; +115;288;1312;;;;;; +115;288;1408;;;;;; +115;288;1696;;;;;; +115;304;1376;;;;;; +115;304;1504;;;;;; +115;304;1632;;;;;; +115;320;1456;;;;;; +115;336;1440;;;;;; +115;352;1328;;;;;; +115;352;1504;;;;;; +115;368;1568;;;;;; +115;368;1680;;;;;; +115;368;1744;;;;;; +115;384;1200;;;;;; +115;384;1216;;;;;; +115;384;1232;;;;;; +115;400;1104;;;;;; +115;400;1184;;;;;; +115;400;1248;;;;;; +115;416;1184;;;;;; +115;416;1248;;;;;; +115;416;1696;;;;;; +115;432;1184;;;;;; +115;432;1248;;;;;; +115;432;1552;;;;;; +115;448;1200;;;;;; +115;448;1216;;;;;; +115;448;1232;;;;;; +115;448;1408;;;;;; +115;464;1120;;;;;; +115;464;1680;;;;;; +115;496;1088;;;;;; +115;512;1472;;;;;; +115;544;1568;;;;;; +115;560;1104;;;;;; +115;560;1616;;;;;; +115;592;1056;;;;;; +115;592;1168;;;;;; +115;592;1584;;;;;; +115;608;1120;;;;;; +115;672;832;;;;;; +115;672;848;;;;;; +115;672;864;;;;;; +115;672;1344;;;;;; +115;688;832;;;;;; +115;688;864;;;;;; +115;704;848;;;;;; +115;704;864;;;;;; +115;720;1360;;;;;; +115;768;560;;;;;; +115;784;592;;;;;; +115;784;1200;;;;;; +115;816;544;;;;;; +115;832;1056;;;;;; +115;848;640;;;;;; +115;864;1136;;;;;; +115;944;624;;;;;; +115;944;1120;;;;;; +115;1056;1104;;;;;; +115;1072;1936;;;;;; +115;1120;1984;;;;;; +115;1216;1872;;;;;; +115;1248;1920;;;;;; +115;1264;1904;;;;;; +115;1280;1184;;;;;; +115;1280;1824;;;;;; +115;1312;1168;;;;;; +115;1312;1248;;;;;; +115;1328;1072;;;;;; +115;1344;1456;;;;;; +115;1360;736;;;;;; +115;1376;688;;;;;; +115;1392;1040;;;;;; +115;1408;1120;;;;;; +115;1408;1216;;;;;; +115;1424;1936;;;;;; +115;1440;1088;;;;;; +115;1440;2016;;;;;; +115;1456;1056;;;;;; +115;1472;1184;;;;;; +115;1472;1248;;;;;; +115;1472;1328;;;;;; +115;1504;1040;;;;;; +115;1520;1280;;;;;; +115;1520;1360;;;;;; +115;1520;1408;;;;;; +115;1520;1520;;;;;; +115;1536;1264;;;;;; +115;1552;1344;;;;;; +115;1568;1200;;;;;; +115;1584;1104;;;;;; +115;1584;1248;;;;;; +115;1584;1856;;;;;; +115;1600;1424;;;;;; +115;1616;1440;;;;;; +115;1616;1856;;;;;; +115;1632;1824;;;;;; +115;1648;1936;;;;;; +115;1648;2000;;;;;; +115;1680;1792;;;;;; +115;1712;1776;;;;;; +115;1728;544;;;;;; +115;1728;560;;;;;; +115;1728;1888;;;;;; +115;1728;1984;;;;;; +115;1744;560;;;;;; +115;1744;1936;;;;;; +115;1760;544;;;;;; +115;1760;560;;;;;; +115;1760;1104;;;;;; +115;1776;1216;;;;;; +115;1776;1888;;;;;; +115;1792;1056;;;;;; +115;1792;1552;;;;;; +115;1808;1728;;;;;; +115;1824;656;;;;;; +115;1824;1808;;;;;; +115;1824;1904;;;;;; +115;1840;1056;;;;;; +115;1840;1760;;;;;; +115;1840;1840;;;;;; +115;1856;1600;;;;;; +115;1872;1040;;;;;; +115;1872;1168;;;;;; +115;1872;1264;;;;;; +115;1872;1520;;;;;; +115;1872;1536;;;;;; +115;1872;1680;;;;;; +115;1872;1856;;;;;; +115;1888;1312;;;;;; +115;1888;1632;;;;;; +115;1888;1792;;;;;; +115;1904;1248;;;;;; +115;1904;1280;;;;;; +115;1904;1408;;;;;; +115;1904;1616;;;;;; +115;1952;1984;;;;;; +115;1968;1856;;;;;; +115;1968;1936;;;;;; +115;1968;2000;;;;;; +115;1984;1696;;;;;; +115;1984;1888;;;;;; +115;1984;1968;;;;;; +115;2016;1744;;;;;; +115;2032;1728;;;;;; +115;2032;2016;;;;;; +115;2048;1952;;;;;; +115;2064;1568;;;;;; +115;2064;1712;;;;;; +115;2064;2000;;;;;; +115;2096;1968;;;;;; +115;2128;1792;;;;;; +115;2128;2016;;;;;; +115;2144;1984;;;;;; +115;2160;1904;;;;;; +115;2160;1936;;;;;; +115;2176;1888;;;;;; +115;2192;1968;;;;;; +115;2208;1808;;;;;; +115;2224;1728;;;;;; +115;2240;1984;;;;;; +118;1152;1040;;;;;; +118;1168;1072;;;;;; +118;1184;1056;;;;;; +118;1184;1088;;;;;; +118;1200;1104;;;;;; +118;1216;1104;;;;;; +118;1216;1120;;;;;; +118;1232;1056;;;;;; +118;1232;1088;;;;;; +118;1248;1072;;;;;; +119;736;1664;;;;;; +119;832;1712;;;;;; +119;864;1600;;;;;; +119;880;1648;;;;;; +116;48;624;;;;;; +116;64;992;;;;;; +116;80;688;;;;;; +116;96;704;;;;;; +116;96;800;;;;;; +116;96;960;;;;;; +116;112;848;;;;;; +116;144;544;;;;;; +116;144;720;;;;;; +116;144;912;;;;;; +116;224;624;;;;;; +116;224;736;;;;;; +116;224;976;;;;;; +116;240;832;;;;;; +116;240;960;;;;;; +116;240;992;;;;;; +116;256;976;;;;;; +116;272;688;;;;;; +116;272;848;;;;;; +116;288;672;;;;;; +116;304;560;;;;;; +116;368;848;;;;;; +116;368;960;;;;;; +116;384;688;;;;;; +116;384;704;;;;;; +116;384;720;;;;;; +116;400;608;;;;;; +116;400;688;;;;;; +116;400;704;;;;;; +116;400;720;;;;;; +116;416;688;;;;;; +116;416;704;;;;;; +116;416;720;;;;;; +116;416;944;;;;;; +116;432;592;;;;;; +116;528;560;;;;;; +116;528;912;;;;;; +116;544;864;;;;;; +116;592;576;;;;;; +116;592;816;;;;;; +116;608;800;;;;;; +117;112;1056;;;;;; +117;128;1024;;;;;; +195;-16;480;; +195;-16;736;; +195;-16;864;; +195;-16;992;; +195;0;608;; +195;144;480;; +195;144;608;; +195;144;736;; +195;144;864;; +195;304;480;; +195;304;608;; +195;304;736;; +195;304;864;; +195;464;480;; +195;464;608;; +195;464;736;; +195;464;864;; +342;1344;32;;;;;; +342;1344;48;;;;;; +342;1376;32;;;;;; +342;1376;48;;;;;; +342;1392;32;;;;;; +342;1392;48;;;;;; +342;1408;32;;;;;; +342;1408;48;;;;;; +342;1504;32;;;;;; +342;1504;48;;;;;; +342;1520;32;;;;;; +342;1520;48;;;;;; +342;1536;32;;;;;; +342;1536;48;;;;;; +342;1552;32;;;;;; +342;1552;48;;;;;; +342;1888;48;;;;;; +342;2330;1592;12;14;;;; +363;288;1488;!npc_grandmother_moved;npc_grandmother +363;2192;1616;npc_grandmother_moved;npc_grandmother +215;80;32;;;;;;; +215;80;1200;;;;;;; +215;80;1216;;;;;;; +215;96;32;;;;;;; +215;96;1184;;;;;;; +215;112;32;;;;;;; +215;112;432;;;;;;; +215;128;432;;;;;;; +215;128;1264;;;;;;; +215;128;1280;;;;;;; +215;144;432;;;;;;; +215;192;240;;;;;;; +215;192;256;;;;;;; +215;208;256;;;;;;; +215;224;240;;;;;;; +215;224;256;;;;;;; +215;224;448;;;;;;; +215;224;1360;;;;;;; +215;240;80;;;;;;; +215;240;96;;;;;;; +215;240;240;;;;;;; +215;240;256;;;;;;; +215;240;448;;;;;;; +215;240;1280;;;;;;; +215;240;1360;;;;;;; +215;256;96;;;;;;; +215;256;352;;;;;;; +215;256;464;;;;;;; +215;256;1280;;;;;;; +215;256;1296;;;;;;; +215;256;1344;;;;;;; +215;256;1360;;;;;;; +215;272;96;;;;;;; +215;272;336;;;;;;; +215;272;352;;;;;;; +215;272;464;;;;;;; +215;272;1072;;;;;;; +215;272;1280;;;;;;; +215;272;1344;;;;;;; +215;272;1360;;;;;;; +215;288;96;;;;;;; +215;288;352;;;;;;; +215;288;1072;;;;;;; +215;288;1328;;;;;;; +215;288;1344;;;;;;; +215;288;1360;;;;;;; +215;304;96;;;;;;; +215;304;320;;;;;;; +215;304;336;;;;;;; +215;304;352;;;;;;; +215;304;368;;;;;;; +215;304;384;;;;;;; +215;304;448;;;;;;; +215;304;1344;;;;;;; +215;320;96;;;;;;; +215;320;448;;;;;;; +215;320;464;;;;;;; +215;384;1312;;;;;;; +215;384;1360;;;;;;; +215;400;1360;;;;;;; +215;432;1360;;;;;;; +215;448;1360;;;;;;; +215;480;1312;;;;;;; +215;480;1328;;;;;;; +215;496;1280;;;;;;; +215;496;1296;;;;;;; +215;496;1312;;;;;;; +215;496;1328;;;;;;; +215;496;1344;;;;;;; +215;496;1360;;;;;;; +215;496;1376;;;;;;; +215;496;1392;;;;;;; +215;496;1408;;;;;;; +215;512;1280;;;;;;; +215;512;1296;;;;;;; +215;512;1312;;;;;;; +215;512;1328;;;;;;; +215;512;1344;;;;;;; +215;512;1360;;;;;;; +215;512;1376;;;;;;; +215;512;1392;;;;;;; +215;512;1408;;;;;;; +215;528;1280;;;;;;; +215;528;1296;;;;;;; +215;528;1392;;;;;;; +215;528;1408;;;;;;; +215;544;1280;;;;;;; +215;544;1296;;;;;;; +215;544;1392;;;;;;; +215;544;1408;;;;;;; +215;560;1280;;;;;;; +215;560;1296;;;;;;; +215;560;1392;;;;;;; +215;560;1408;;;;;;; +215;576;1280;;;;;;; +215;576;1296;;;;;;; +215;576;1392;;;;;;; +215;576;1408;;;;;;; +215;592;1280;;;;;;; +215;592;1296;;;;;;; +215;592;1392;;;;;;; +215;592;1408;;;;;;; +215;608;1280;;;;;;; +215;608;1296;;;;;;; +215;608;1392;;;;;;; +215;608;1408;;;;;;; +215;624;1280;;;;;;; +215;624;1296;;;;;;; +215;624;1312;;;;;;; +215;624;1328;;;;;;; +215;624;1344;;;;;;; +215;624;1360;;;;;;; +215;624;1376;;;;;;; +215;624;1392;;;;;;; +215;624;1408;;;;;;; +215;672;1296;;;;;;; +215;672;1312;;;;;;; +215;672;1360;;;;;;; +215;672;1376;;;;;;; +215;672;1392;;;;;;; +215;672;1408;;;;;;; +215;672;1424;;;;;;; +215;672;1440;;;;;;; +215;672;1456;;;;;;; +215;672;1472;;;;;;; +215;672;1568;;;;;;; +215;672;1584;;;;;;; +215;672;1648;;;;;;; +215;672;1664;;;;;;; +215;672;1680;;;;;;; +215;672;1712;;;;;;; +215;672;1760;;;;;;; +215;688;1296;;;;;;; +215;688;1376;;;;;;; +215;688;1392;;;;;;; +215;688;1408;;;;;;; +215;688;1424;;;;;;; +215;688;1440;;;;;;; +215;688;1456;;;;;;; +215;688;1472;;;;;;; +215;688;1584;;;;;;; +215;688;1632;;;;;;; +215;688;1648;;;;;;; +215;688;1664;;;;;;; +215;688;1712;;;;;;; +215;704;576;;;;;;; +215;704;1296;;;;;;; +215;704;1376;;;;;;; +215;704;1392;;;;;;; +215;704;1408;;;;;;; +215;704;1424;;;;;;; +215;704;1440;;;;;;; +215;704;1456;;;;;;; +215;704;1568;;;;;;; +215;704;1584;;;;;;; +215;704;1600;;;;;;; +215;704;1760;;;;;;; +215;720;560;;;;;;; +215;720;576;;;;;;; +215;720;592;;;;;;; +215;720;944;;;;;;; +215;720;1296;;;;;;; +215;720;1376;;;;;;; +215;720;1392;;;;;;; +215;720;1408;;;;;;; +215;720;1424;;;;;;; +215;720;1440;;;;;;; +215;720;1456;;;;;;; +215;720;1504;;;;;;; +215;720;1520;;;;;;; +215;720;1536;;;;;;; +215;720;1552;;;;;;; +215;720;1568;;;;;;; +215;736;576;;;;;;; +215;736;928;;;;;;; +215;736;960;;;;;;; +215;736;1360;;;;;;; +215;736;1376;;;;;;; +215;736;1392;;;;;;; +215;736;1408;;;;;;; +215;736;1424;;;;;;; +215;736;1440;;;;;;; +215;736;1488;;;;;;; +215;736;1504;;;;;;; +215;736;1520;;;;;;; +215;736;1536;;;;;;; +215;736;1552;;;;;;; +215;752;1232;;;;;;; +215;752;1264;;;;;;; +215;752;1280;;;;;;; +215;752;1296;;;;;;; +215;752;1344;;;;;;; +215;752;1360;;;;;;; +215;752;1376;;;;;;; +215;752;1392;;;;;;; +215;752;1408;;;;;;; +215;752;1424;;;;;;; +215;752;1488;;;;;;; +215;752;1504;;;;;;; +215;752;1520;;;;;;; +215;752;1536;;;;;;; +215;752;1552;;;;;;; +215;768;928;;;;;;; +215;768;960;;;;;;; +215;768;1104;;;;;;; +215;768;1152;;;;;;; +215;768;1168;;;;;;; +215;768;1216;;;;;;; +215;768;1232;;;;;;; +215;768;1264;;;;;;; +215;768;1280;;;;;;; +215;768;1296;;;;;;; +215;768;1344;;;;;;; +215;768;1360;;;;;;; +215;768;1376;;;;;;; +215;768;1392;;;;;;; +215;768;1408;;;;;;; +215;768;1424;;;;;;; +215;768;1440;;;;;;; +215;768;1504;;;;;;; +215;768;1520;;;;;;; +215;768;1536;;;;;;; +215;768;1552;;;;;;; +215;784;944;;;;;;; +215;784;1120;;;;;;; +215;784;1152;;;;;;; +215;784;1168;;;;;;; +215;784;1264;;;;;;; +215;784;1280;;;;;;; +215;784;1296;;;;;;; +215;784;1312;;;;;;; +215;784;1328;;;;;;; +215;784;1552;;;;;;; +215;784;1744;;;;;;; +215;800;1056;;;;;;; +215;800;1120;;;;;;; +215;800;1136;;;;;;; +215;800;1152;;;;;;; +215;800;1168;;;;;;; +215;800;1200;;;;;;; +215;800;1216;;;;;;; +215;800;1248;;;;;;; +215;800;1264;;;;;;; +215;800;1280;;;;;;; +215;800;1296;;;;;;; +215;800;1312;;;;;;; +215;800;1328;;;;;;; +215;800;1552;;;;;;; +215;800;1760;;;;;;; +215;816;1120;;;;;;; +215;816;1136;;;;;;; +215;816;1152;;;;;;; +215;816;1168;;;;;;; +215;816;1200;;;;;;; +215;816;1216;;;;;;; +215;816;1248;;;;;;; +215;816;1264;;;;;;; +215;816;1312;;;;;;; +215;816;1328;;;;;;; +215;816;1552;;;;;;; +215;816;1760;;;;;;; +215;832;608;;;;;;; +215;832;1120;;;;;;; +215;832;1136;;;;;;; +215;832;1152;;;;;;; +215;832;1168;;;;;;; +215;832;1216;;;;;;; +215;832;1264;;;;;;; +215;832;1296;;;;;;; +215;832;1312;;;;;;; +215;832;1328;;;;;;; +215;832;1344;;;;;;; +215;832;1360;;;;;;; +215;832;1376;;;;;;; +215;832;1392;;;;;;; +215;832;1408;;;;;;; +215;832;1424;;;;;;; +215;832;1440;;;;;;; +215;832;1456;;;;;;; +215;832;1472;;;;;;; +215;832;1488;;;;;;; +215;832;1504;;;;;;; +215;832;1552;;;;;;; +215;832;1744;;;;;;; +215;832;1760;;;;;;; +215;848;1120;;;;;;; +215;848;1136;;;;;;; +215;848;1152;;;;;;; +215;848;1168;;;;;;; +215;848;1232;;;;;;; +215;848;1264;;;;;;; +215;848;1280;;;;;;; +215;848;1296;;;;;;; +215;848;1312;;;;;;; +215;848;1328;;;;;;; +215;848;1344;;;;;;; +215;848;1360;;;;;;; +215;848;1376;;;;;;; +215;848;1392;;;;;;; +215;848;1408;;;;;;; +215;848;1424;;;;;;; +215;848;1440;;;;;;; +215;848;1456;;;;;;; +215;848;1472;;;;;;; +215;848;1488;;;;;;; +215;848;1504;;;;;;; +215;848;1552;;;;;;; +215;848;1744;;;;;;; +215;848;1760;;;;;;; +215;864;624;;;;;;; +215;864;1120;;;;;;; +215;864;1152;;;;;;; +215;864;1168;;;;;;; +215;864;1232;;;;;;; +215;864;1248;;;;;;; +215;864;1264;;;;;;; +215;864;1280;;;;;;; +215;864;1296;;;;;;; +215;864;1488;;;;;;; +215;864;1504;;;;;;; +215;864;1552;;;;;;; +215;864;1568;;;;;;; +215;864;1744;;;;;;; +215;864;1760;;;;;;; +215;880;624;;;;;;; +215;880;1120;;;;;;; +215;880;1168;;;;;;; +215;880;1280;;;;;;; +215;880;1296;;;;;;; +215;880;1344;;;;;;; +215;880;1504;;;;;;; +215;880;1712;;;;;;; +215;880;1728;;;;;;; +215;880;1760;;;;;;; +215;896;624;;;;;;; +215;896;1120;;;;;;; +215;896;1136;;;;;;; +215;896;1168;;;;;;; +215;896;1184;;;;;;; +215;896;1264;;;;;;; +215;896;1280;;;;;;; +215;896;1296;;;;;;; +215;896;1328;;;;;;; +215;896;1360;;;;;;; +215;896;1712;;;;;;; +215;896;1728;;;;;;; +215;896;1744;;;;;;; +215;896;1760;;;;;;; +215;912;576;;;;;;; +215;912;592;;;;;;; +215;912;608;;;;;;; +215;912;976;;;;;;; +215;912;1120;;;;;;; +215;912;1136;;;;;;; +215;912;1152;;;;;;; +215;912;1168;;;;;;; +215;912;1184;;;;;;; +215;912;1280;;;;;;; +215;912;1296;;;;;;; +215;912;1344;;;;;;; +215;912;1552;;;;;;; +215;912;1648;;;;;;; +215;912;1664;;;;;;; +215;912;1680;;;;;;; +215;912;1728;;;;;;; +215;912;1744;;;;;;; +215;912;1760;;;;;;; +215;928;576;;;;;;; +215;928;592;;;;;;; +215;928;880;;;;;;; +215;928;912;;;;;;; +215;928;928;;;;;;; +215;928;944;;;;;;; +215;928;960;;;;;;; +215;928;1120;;;;;;; +215;928;1152;;;;;;; +215;928;1168;;;;;;; +215;928;1184;;;;;;; +215;928;1264;;;;;;; +215;928;1280;;;;;;; +215;928;1296;;;;;;; +215;928;1552;;;;;;; +215;928;1568;;;;;;; +215;928;1648;;;;;;; +215;928;1664;;;;;;; +215;928;1680;;;;;;; +215;928;1696;;;;;;; +215;928;1728;;;;;;; +215;928;1744;;;;;;; +215;928;1760;;;;;;; +215;944;576;;;;;;; +215;944;592;;;;;;; +215;944;944;;;;;;; +215;944;1088;;;;;;; +215;944;1104;;;;;;; +215;944;1152;;;;;;; +215;944;1184;;;;;;; +215;944;1200;;;;;;; +215;944;1216;;;;;;; +215;944;1552;;;;;;; +215;944;1568;;;;;;; +215;944;1600;;;;;;; +215;944;1616;;;;;;; +215;944;1632;;;;;;; +215;944;1648;;;;;;; +215;944;1664;;;;;;; +215;944;1680;;;;;;; +215;944;1696;;;;;;; +215;960;576;;;;;;; +215;960;1184;;;;;;; +215;960;1200;;;;;;; +215;960;1216;;;;;;; +215;960;1248;;;;;;; +215;960;1552;;;;;;; +215;960;1568;;;;;;; +215;976;576;;;;;;; +215;976;1200;;;;;;; +215;976;1216;;;;;;; +215;976;1248;;;;;;; +215;976;1552;;;;;;; +215;976;1568;;;;;;; +215;992;1088;;;;;;; +215;992;1104;;;;;;; +215;992;1120;;;;;;; +215;992;1136;;;;;;; +215;992;1168;;;;;;; +215;992;1248;;;;;;; +215;992;1552;;;;;;; +215;992;1568;;;;;;; +215;992;1584;;;;;;; +215;992;1600;;;;;;; +215;992;1616;;;;;;; +215;992;1632;;;;;;; +215;992;1648;;;;;;; +215;992;1664;;;;;;; +215;992;1680;;;;;;; +215;992;1696;;;;;;; +215;992;1712;;;;;;; +215;992;1728;;;;;;; +215;1008;432;;;;;;; +215;1008;448;;;;;;; +215;1008;528;;;;;;; +215;1008;544;;;;;;; +215;1008;560;;;;;;; +215;1008;816;;;;;;; +215;1008;832;;;;;;; +215;1008;848;;;;;;; +215;1008;864;;;;;;; +215;1008;896;;;;;;; +215;1008;912;;;;;;; +215;1008;928;;;;;;; +215;1008;944;;;;;;; +215;1008;960;;;;;;; +215;1008;1088;;;;;;; +215;1008;1104;;;;;;; +215;1008;1120;;;;;;; +215;1008;1136;;;;;;; +215;1008;1184;;;;;;; +215;1008;1248;;;;;;; +215;1008;1552;;;;;;; +215;1008;1744;;;;;;; +215;1008;1760;;;;;;; +215;1024;432;;;;;;; +215;1024;544;;;;;;; +215;1024;832;;;;;;; +215;1024;864;;;;;;; +215;1024;896;;;;;;; +215;1024;928;;;;;;; +215;1024;944;;;;;;; +215;1024;1040;;;;;;; +215;1024;1056;;;;;;; +215;1024;1072;;;;;;; +215;1024;1088;;;;;;; +215;1024;1104;;;;;;; +215;1024;1136;;;;;;; +215;1024;1552;;;;;;; +215;1024;1616;;;;;;; +215;1024;1760;;;;;;; +215;1040;832;;;;;;; +215;1040;864;;;;;;; +215;1040;880;;;;;;; +215;1040;928;;;;;;; +215;1040;1040;;;;;;; +215;1040;1056;;;;;;; +215;1040;1552;;;;;;; +215;1040;1760;;;;;;; +215;1056;880;;;;;;; +215;1056;912;;;;;;; +215;1056;928;;;;;;; +215;1056;960;;;;;;; +215;1056;1120;;;;;;; +215;1056;1840;;;;;;; +215;1056;1984;;;;;;; +215;1072;400;;;;;;; +215;1072;816;;;;;;; +215;1072;848;;;;;;; +215;1072;880;;;;;;; +215;1072;960;;;;;;; +215;1072;1552;;;;;;; +215;1072;1568;;;;;;; +215;1072;1584;;;;;;; +215;1072;1648;;;;;;; +215;1072;1664;;;;;;; +215;1072;1840;;;;;;; +215;1072;1984;;;;;;; +215;1088;800;;;;;;; +215;1088;832;;;;;;; +215;1088;896;;;;;;; +215;1088;1104;;;;;;; +215;1088;1584;;;;;;; +215;1088;1808;;;;;;; +215;1088;1824;;;;;;; +215;1088;1840;;;;;;; +215;1104;800;;;;;;; +215;1104;832;;;;;;; +215;1104;864;;;;;;; +215;1104;896;;;;;;; +215;1104;912;;;;;;; +215;1104;944;;;;;;; +215;1104;1552;;;;;;; +215;1104;1568;;;;;;; +215;1104;1584;;;;;;; +215;1104;1808;;;;;;; +215;1104;1824;;;;;;; +215;1104;1952;;;;;;; +215;1120;928;;;;;;; +215;1120;944;;;;;;; +215;1120;1568;;;;;;; +215;1120;1632;;;;;;; +215;1120;1680;;;;;;; +215;1120;1712;;;;;;; +215;1120;1808;;;;;;; +215;1120;1824;;;;;;; +215;1136;928;;;;;;; +215;1136;944;;;;;;; +215;1136;960;;;;;;; +215;1136;1568;;;;;;; +215;1136;1632;;;;;;; +215;1136;1680;;;;;;; +215;1136;1712;;;;;;; +215;1136;1808;;;;;;; +215;1136;1824;;;;;;; +215;1152;800;;;;;;; +215;1152;832;;;;;;; +215;1152;848;;;;;;; +215;1152;864;;;;;;; +215;1152;880;;;;;;; +215;1152;912;;;;;;; +215;1152;944;;;;;;; +215;1152;960;;;;;;; +215;1152;1648;;;;;;; +215;1152;1664;;;;;;; +215;1152;1808;;;;;;; +215;1152;1824;;;;;;; +215;1168;336;;;;;;; +215;1168;800;;;;;;; +215;1168;880;;;;;;; +215;1168;960;;;;;;; +215;1168;1808;;;;;;; +215;1168;1824;;;;;;; +215;1184;336;;;;;;; +215;1184;800;;;;;;; +215;1184;880;;;;;;; +215;1184;960;;;;;;; +215;1184;1072;;;;;;; +215;1184;1808;;;;;;; +215;1184;1824;;;;;;; +215;1200;800;;;;;;; +215;1200;816;;;;;;; +215;1200;848;;;;;;; +215;1200;864;;;;;;; +215;1200;880;;;;;;; +215;1200;896;;;;;;; +215;1200;928;;;;;;; +215;1200;944;;;;;;; +215;1200;1088;;;;;;; +215;1200;1504;;;;;;; +215;1200;1648;;;;;;; +215;1200;1664;;;;;;; +215;1200;1808;;;;;;; +215;1200;1824;;;;;;; +215;1200;1840;;;;;;; +215;1216;800;;;;;;; +215;1216;832;;;;;;; +215;1216;864;;;;;;; +215;1216;896;;;;;;; +215;1216;928;;;;;;; +215;1216;1088;;;;;;; +215;1216;1472;;;;;;; +215;1216;1488;;;;;;; +215;1216;1504;;;;;;; +215;1216;1808;;;;;;; +215;1216;1824;;;;;;; +215;1232;800;;;;;;; +215;1232;816;;;;;;; +215;1232;832;;;;;;; +215;1232;848;;;;;;; +215;1232;864;;;;;;; +215;1232;896;;;;;;; +215;1232;992;;;;;;; +215;1232;1072;;;;;;; +215;1232;1648;;;;;;; +215;1232;1664;;;;;;; +215;1248;800;;;;;;; +215;1248;864;;;;;;; +215;1248;880;;;;;;; +215;1248;896;;;;;;; +215;1248;944;;;;;;; +215;1248;976;;;;;;; +215;1248;992;;;;;;; +215;1264;800;;;;;;; +215;1264;816;;;;;;; +215;1264;848;;;;;;; +215;1264;864;;;;;;; +215;1264;880;;;;;;; +215;1264;896;;;;;;; +215;1264;912;;;;;;; +215;1264;928;;;;;;; +215;1264;944;;;;;;; +215;1264;976;;;;;;; +215;1280;976;;;;;;; +215;1312;1616;;;;;;; +215;1312;1632;;;;;;; +215;1312;1648;;;;;;; +215;1312;1664;;;;;;; +215;1312;1680;;;;;;; +215;1312;1696;;;;;;; +215;1312;1712;;;;;;; +215;1312;1728;;;;;;; +215;1328;1616;;;;;;; +215;1328;1632;;;;;;; +215;1328;1648;;;;;;; +215;1344;1616;;;;;;; +215;1344;1632;;;;;;; +215;1360;1584;;;;;;; +215;1360;1600;;;;;;; +215;1360;1616;;;;;;; +215;1376;1584;;;;;;; +215;1392;1504;;;;;;; +215;1392;1520;;;;;;; +215;1392;1536;;;;;;; +215;1392;1552;;;;;;; +215;1408;1504;;;;;;; +215;1424;416;;;;;;; +215;1424;1504;;;;;;; +215;1440;416;;;;;;; +215;1440;1440;;;;;;; +215;1440;1456;;;;;;; +215;1440;1472;;;;;;; +215;1456;416;;;;;;; +215;1456;1888;;;;;;; +215;1472;416;;;;;;; +215;1472;1888;;;;;;; +215;1472;1904;;;;;;; +215;1488;416;;;;;;; +215;1488;1904;;;;;;; +215;1504;368;;;;;;; +215;1504;384;;;;;;; +215;1504;416;;;;;;; +215;1520;400;;;;;;; +215;1536;400;;;;;;; +215;1568;384;;;;;;; +215;1584;384;;;;;;; +215;1600;400;;;;;;; +215;1616;400;;;;;;; +215;1632;400;;;;;;; +215;1648;384;;;;;;; +215;1664;384;;;;;;; +215;1680;400;;;;;;; +215;1696;400;;;;;;; +215;1712;400;;;;;;; +215;1712;1488;;;;;;; +215;1728;384;;;;;;; +215;1728;1488;;;;;;; +215;1744;384;;;;;;; +215;1744;1488;;;;;;; +215;1744;1504;;;;;;; +215;1744;1520;;;;;;; +215;1744;1536;;;;;;; +215;1760;400;;;;;;; +215;1760;1488;;;;;;; +215;1760;1504;;;;;;; +215;1776;400;;;;;;; +215;1776;1488;;;;;;; +215;1792;400;;;;;;; +215;1792;1488;;;;;;; +215;1792;1536;;;;;;; +215;1792;1568;;;;;;; +215;1792;1600;;;;;;; +215;1792;1616;;;;;;; +215;1792;1632;;;;;;; +215;1792;1648;;;;;;; +215;1808;400;;;;;;; +215;1808;1488;;;;;;; +215;1808;1552;;;;;;; +215;1808;1616;;;;;;; +215;1808;1632;;;;;;; +215;1808;1648;;;;;;; +215;1808;1664;;;;;;; +215;1808;1680;;;;;;; +215;1808;1744;;;;;;; +215;1808;1760;;;;;;; +215;1808;1776;;;;;;; +215;1824;400;;;;;;; +215;1824;1488;;;;;;; +215;1824;1632;;;;;;; +215;1840;400;;;;;;; +215;1840;1488;;;;;;; +215;1856;400;;;;;;; +215;1856;416;;;;;;; +215;1856;1488;;;;;;; +215;1856;1504;;;;;;; +215;1856;1712;;;;;;; +215;1856;1728;;;;;;; +215;1872;400;;;;;;; +215;1872;416;;;;;;; +215;1872;1280;;;;;;; +215;1872;1296;;;;;;; +215;1872;1472;;;;;;; +215;1872;1488;;;;;;; +215;1872;1504;;;;;;; +215;1872;1552;;;;;;; +215;1872;1696;;;;;;; +215;1872;1744;;;;;;; +215;1888;400;;;;;;; +215;1888;416;;;;;;; +215;1888;432;;;;;;; +215;1888;1440;;;;;;; +215;1888;1456;;;;;;; +215;1888;1472;;;;;;; +215;1888;1488;;;;;;; +215;1888;1536;;;;;;; +215;1888;1552;;;;;;; +215;1888;1696;;;;;;; +215;1888;1744;;;;;;; +215;1904;416;;;;;;; +215;1904;432;;;;;;; +215;1904;1504;;;;;;; +215;1904;1520;;;;;;; +215;1904;1536;;;;;;; +215;1904;1552;;;;;;; +215;1920;416;;;;;;; +215;1936;416;;;;;;; +215;1952;416;;;;;;; +215;1952;1632;;;;;;; +215;1952;1648;;;;;;; +215;1952;1664;;;;;;; +215;1952;1680;;;;;;; +215;1952;1696;;;;;;; +215;1952;1712;;;;;;; +215;1952;1728;;;;;;; +215;1968;416;;;;;;; +215;1968;1632;;;;;;; +215;1968;1648;;;;;;; +215;1968;1664;;;;;;; +215;1968;1680;;;;;;; +215;1968;1744;;;;;;; +215;1984;416;;;;;;; +215;1984;1632;;;;;;; +215;1984;1648;;;;;;; +215;1984;1664;;;;;;; +215;1984;1760;;;;;;; +215;2000;336;;;;;;; +215;2000;400;;;;;;; +215;2000;1632;;;;;;; +215;2000;1648;;;;;;; +215;2000;1664;;;;;;; +215;2000;1760;;;;;;; +215;2016;352;;;;;;; +215;2016;416;;;;;;; +215;2016;1632;;;;;;; +215;2016;1648;;;;;;; +215;2016;1664;;;;;;; +215;2016;1760;;;;;;; +215;2032;352;;;;;;; +215;2032;416;;;;;;; +215;2032;1632;;;;;;; +215;2032;1648;;;;;;; +215;2032;1664;;;;;;; +215;2048;352;;;;;;; +215;2048;416;;;;;;; +215;2048;1632;;;;;;; +215;2048;1648;;;;;;; +215;2048;1664;;;;;;; +215;2064;336;;;;;;; +215;2064;400;;;;;;; +215;2064;1632;;;;;;; +215;2064;1648;;;;;;; +215;2064;1664;;;;;;; +215;2064;1680;;;;;;; +215;2064;1744;;;;;;; +215;2080;352;;;;;;; +215;2080;416;;;;;;; +215;2080;1632;;;;;;; +215;2080;1648;;;;;;; +215;2080;1664;;;;;;; +215;2080;1680;;;;;;; +215;2080;1696;;;;;;; +215;2080;1712;;;;;;; +215;2080;1728;;;;;;; +215;2080;1744;;;;;;; +215;2096;352;;;;;;; +215;2096;416;;;;;;; +215;2096;1632;;;;;;; +215;2096;1648;;;;;;; +215;2096;1664;;;;;;; +215;2096;1680;;;;;;; +215;2096;1696;;;;;;; +215;2096;1712;;;;;;; +215;2096;1728;;;;;;; +215;2112;352;;;;;;; +215;2112;416;;;;;;; +215;2112;1632;;;;;;; +215;2112;1648;;;;;;; +215;2112;1664;;;;;;; +215;2112;1680;;;;;;; +215;2112;1696;;;;;;; +215;2112;1712;;;;;;; +215;2112;1728;;;;;;; +215;2128;1632;;;;;;; +215;2128;1648;;;;;;; +215;2128;1664;;;;;;; +215;2128;1680;;;;;;; +215;2144;336;;;;;;; +215;2144;1632;;;;;;; +215;2144;1648;;;;;;; +215;2144;1664;;;;;;; +215;2144;1680;;;;;;; +215;2144;1744;;;;;;; +215;2160;352;;;;;;; +215;2160;416;;;;;;; +215;2160;1632;;;;;;; +215;2160;1648;;;;;;; +215;2160;1664;;;;;;; +215;2176;352;;;;;;; +215;2176;416;;;;;;; +215;2176;1632;;;;;;; +215;2176;1648;;;;;;; +215;2176;1664;;;;;;; +215;2192;352;;;;;;; +215;2192;416;;;;;;; +215;2208;336;;;;;;; +215;2432;416;;;;;;; +215;2448;416;;;;;;; +215;2512;1088;;;;;;; +215;2512;1104;;;;;;; +215;2528;1104;;;;;;; +215;2528;1120;;;;;;; +216;2016;1600;;;;;;; +216;2080;1600;;;;;;; +216;2096;1600;;;;;;; +217;272;1456;;;;;;; +217;272;1472;;;;;;; +217;272;1488;;;;;;; +217;448;1344;;;;;;; +217;1088;1952;;;;;;; +217;1088;1968;;;;;;; +217;2480;400;;;;;;; +218;96;416;;;;;;; +218;208;1456;;;;;;; +218;208;1472;;;;;;; +218;208;1488;;;;;;; +218;384;1328;;;;;;; +218;384;1344;;;;;;; +219;400;1312;;;;;;; +219;416;1312;;;;;;; +219;432;1312;;;;;;; +219;1040;1936;;;;;;; +219;1056;1936;;;;;;; +220;96;624;;;;;;; +220;96;640;;;;;;; +220;96;656;;;;;;; +220;96;672;;;;;;; +220;112;688;;;;;;; +220;112;1040;;;;;;; +220;128;688;;;;;;; +220;128;992;;;;;;; +220;128;1008;;;;;;; +220;128;1040;;;;;;; +220;128;1056;;;;;;; +220;128;1072;;;;;;; +220;144;688;;;;;;; +220;192;784;;;;;;; +220;192;800;;;;;;; +220;208;800;;;;;;; +220;256;752;;;;;;; +220;272;608;;;;;;; +220;272;624;;;;;;; +220;272;640;;;;;;; +220;272;656;;;;;;; +220;272;720;;;;;;; +220;272;736;;;;;;; +220;272;752;;;;;;; +220;288;688;;;;;;; +220;288;704;;;;;;; +220;288;720;;;;;;; +220;336;544;;;;;;; +220;336;560;;;;;;; +220;352;576;;;;;;; +220;368;720;;;;;;; +220;368;736;;;;;;; +220;384;736;;;;;;; +220;384;752;;;;;;; +220;416;608;;;;;;; +220;416;624;;;;;;; +220;416;640;;;;;;; +220;416;656;;;;;;; +220;432;672;;;;;;; +220;448;576;;;;;;; +220;448;592;;;;;;; +220;528;592;;;;;;; +220;528;672;;;;;;; +220;528;688;;;;;;; +220;528;704;;;;;;; +220;528;720;;;;;;; +220;544;592;;;;;;; +220;544;720;;;;;;; +220;544;736;;;;;;; +220;544;752;;;;;;; +220;560;592;;;;;;; +220;560;720;;;;;;; +220;560;736;;;;;;; +220;560;752;;;;;;; +220;576;592;;;;;;; +220;576;720;;;;;;; +220;576;736;;;;;;; +220;576;752;;;;;;; +220;576;880;;;;;;; +220;576;896;;;;;;; +220;592;592;;;;;;; +220;592;720;;;;;;; +220;592;736;;;;;;; +220;592;768;;;;;;; +220;592;784;;;;;;; +220;592;848;;;;;;; +220;592;864;;;;;;; +220;592;880;;;;;;; +220;592;896;;;;;;; +220;592;976;;;;;;; +220;608;592;;;;;;; +220;608;672;;;;;;; +220;608;688;;;;;;; +220;608;704;;;;;;; +220;608;720;;;;;;; +220;608;816;;;;;;; +220;608;832;;;;;;; +220;608;848;;;;;;; +220;608;912;;;;;;; +220;608;928;;;;;;; +220;608;944;;;;;;; +220;608;960;;;;;;; +220;608;976;;;;;;; +220;624;608;;;;;;; +221;336;448;;;;;;; +221;336;464;;;;;;; +221;352;464;;;;;;; +55;992;783;;;;;; +55;992;799;;;;;; +55;992;815;;;;;; +55;992;831;;;;;; +55;992;879;;;;;; +55;992;895;;;;;; +55;992;911;;;;;; +55;992;927;;;;;; +55;992;943;;;;;; +55;992;959;;;;;; +55;1008;783;;;;;; +55;1008;975;;;;;; +55;1024;783;;;;;; +55;1024;975;;;;;; +55;1040;783;;;;;; +55;1040;975;;;;;; +55;1056;783;;;;;; +55;1056;975;;;;;; +55;1072;783;;;;;; +55;1072;975;;;;;; +55;1088;783;;;;;; +55;1088;975;;;;;; +55;1104;783;;;;;; +55;1104;975;;;;;; +55;1120;783;;;;;; +55;1120;975;;;;;; +55;1136;783;;;;;; +55;1136;975;;;;;; +55;1152;783;;;;;; +55;1152;975;;;;;; +55;1168;783;;;;;; +55;1168;975;;;;;; +55;1184;975;;;;;; +55;1200;975;;;;;; +55;1216;783;;;;;; +55;1232;783;;;;;; +55;1233;959;;;;;; +55;1248;783;;;;;; +55;1249;959;;;;;; +55;1265;959;;;;;; +55;1281;799;;;;;; +55;1281;815;;;;;; +55;1281;831;;;;;; +55;1281;847;;;;;; +55;1281;863;;;;;; +55;1281;879;;;;;; +55;1281;895;;;;;; +55;1281;911;;;;;; +55;1281;927;;;;;; +55;1281;943;;;;;; +55;1281;959;;;;;; +222;688;848;0;;;;;;; +222;1024;816;0;;;;;;; +222;1024;848;0;;;;;;; +222;1040;912;0;;;;;;; +222;1040;944;0;;;;;;; +222;1056;816;0;;;;;;; +222;1056;848;0;;;;;;; +222;1072;912;0;;;;;;; +222;1072;944;-1;ow_gravestone;;;;;; +222;1088;816;0;;;;;;; +222;1088;848;0;;;;;;; +222;1184;816;0;;;;;;; +222;1184;848;0;;;;;;; +222;1184;912;;ow_grave_2;;;;;;ow_grave_reset +222;1184;944;;ow_grave_1;;;;;;ow_grave_reset +222;1216;816;0;;;;;;; +222;1216;848;0;;;;;;; +222;1216;912;;ow_grave_3;;;;;;ow_grave_reset +222;1216;944;;ow_grave_0;;;;;;ow_grave_reset +222;1248;816;0;;;;;;; +222;1248;848;0;;;;;;; +255;1184;896;dc_spawn_entry +253;688;856;128;ghost_grave_powder;;8;100;False; +253;2512;1760;128;desert_bones_powder;;;125;False; +340;80;432;;;;;; +340;96;464;;;;;; +340;96;1360;12;12;;2;0; +340;112;448;;;;;; +340;112;464;;;;;; +340;112;576;;;;;; +340;128;448;;;;;; +340;144;448;;;;;; +340;192;432;;;;;; +340;208;432;;;;;; +340;256;1600;;;;;; +340;288;576;;;;;; +340;288;592;;;;;; +340;384;1600;;;;;; +340;384;1616;;;;;; +340;400;1616;;;;;; +340;416;1616;;;;;; +340;528;944;;;;;; +340;560;912;;;;;; +340;560;976;;;;;; +340;592;944;;;;;; +340;672;1632;;;;;; +340;688;560;;;;;; +340;688;576;;;;;; +340;688;592;;;;;; +340;688;1600;;;;;; +340;704;544;;;;;; +340;704;560;;;;;; +340;704;592;;;;;; +340;704;608;;;;;; +340;720;544;;;;;; +340;720;608;;;;;; +340;720;1744;;;;;; +340;720;1760;;;;;; +340;736;544;;;;;; +340;736;560;;;;;; +340;736;592;;;;;; +340;736;608;;;;;; +340;736;1456;;;;;; +340;736;1744;;;;;; +340;736;1760;;;;;; +340;752;560;;;;;; +340;752;576;;;;;; +340;752;592;;;;;; +340;752;1440;;;;;; +340;752;1456;;;;;; +340;752;1472;;;;;; +340;752;1584;;;;;; +340;752;1744;;;;;; +340;752;1760;;;;;; +340;768;1456;;;;;; +340;768;1472;;;;;; +340;768;1488;;;;;; +340;768;1744;;;;;; +340;768;1760;;;;;; +340;848;736;;;;;; +340;912;848;;;;;; +340;912;864;;;;;; +340;992;1216;;;;;; +340;1024;704;;;;;; +340;1024;1184;;;;;; +340;1040;480;;;;;; +340;1040;1072;;;;;; +340;1040;1104;;;;;; +340;1056;1200;;;;;; +340;1072;448;;;;;; +340;1072;688;;;;;; +340;1072;1088;;;;;; +340;1072;1120;;;;;; +340;1072;1232;;;;;; +340;1088;1056;;;;;; +340;1104;1088;;;;;; +340;1104;1168;;;;;; +340;1168;544;;;;;; +340;1168;1184;;;;;; +340;1184;1216;;;;;; +340;1184;1968;;;;;; +340;1200;1968;;;;;; +340;1216;592;;;;;; +340;1216;1968;;;;;; +340;1248;1872;;;;;; +340;1360;992;;;;;; +340;1376;992;;;;;; +340;1392;992;;;;;; +340;1392;1200;;;;;; +340;1408;992;;;;;; +340;1424;992;;;;;; +340;1488;1968;;;;;; +340;1488;1984;;;;;; +340;1488;2000;;;;;; +340;1488;2016;;;;;; +340;1504;1184;;;;;; +340;1504;1216;;;;;; +340;1504;1952;;;;;; +340;1504;1968;;;;;; +340;1504;1984;;;;;; +340;1504;2000;;;;;; +340;1504;2016;;;;;; +340;1520;1072;;;;;; +340;1520;1952;;;;;; +340;1520;1968;;;;;; +340;1520;2016;;;;;; +340;1552;1104;;;;;; +340;1568;1184;;;;;; +340;1568;1216;;;;;; +340;1648;688;;;;;; +340;1664;736;;;;;; +340;1696;656;;;;;; +340;1696;704;;;;;; +340;1728;736;;;;;; +340;1744;688;;;;;; +340;2336;192;;;;;; +343;1328;992;2 +344;96;1360;cave0.map;cave0 +344;2330;1592;cave12.map;cave12_fall +344;2336;192;cave29.map;hole_entry +397;1208;1064;ow_honeycomb_fallen +200;80;32;;ow_mountain_heartMeter;heartMeter;; +200;416;2000;;ow_sword_1;sword1;; +200;720;576;;ow_heartMeter_cross;heartMeter;; +200;1376;944;s;ow_castle_heartMeter;heartMeter;; +200;1952;688;w;;arrow;; +200;1952;704;w;;powder_10;; +200;1952;928;w;;arrow;; +200;1952;944;w;;ruby10;; +200;1968;720;w;;bomb_10;; +200;2000;576;w;;ruby10;; +200;2032;864;w;;ruby10;; +200;2064;928;w;;ruby10;; +200;2144;720;w;;heart_3;; +200;2160;928;w;;ruby10;; +200;2176;560;w;;ruby10;; +200;2208;848;w;;arrow;; +200;2208;864;w;;powder_10;; +200;2224;848;w;;heart_3;; +200;2224;864;w;;ruby10;; +200;2224;960;w;;ruby10;; +200;2288;912;w;;ruby10;; +200;2320;800;w;;ruby10;; +200;2320;912;w;;ruby10;; +200;2336;720;w;;arrow;; +200;2352;608;w;;ruby10;; +200;2352;656;w;;bomb_10;; +200;2352;912;w;;ruby10;; +200;2432;848;w;;ruby10;; +200;2448;736;w;;heart_3;; +200;2448;928;w;;ruby10;; +200;2464;960;w;;arrow;; +200;2480;944;w;;bomb_10;; +200;2496;560;w;;ruby10;; +200;2496;960;w;;powder_10;; +200;2512;544;w;;ruby10;; +200;2512;800;w;;ruby10;; +200;2544;576;w;;ruby10;; +200;2544;704;w;;ruby10;; +200;2544;800;w;;ruby10;; +200;2544;832;w;;ruby10;; +200;2544;864;w;;ruby10;; +162;80;1656;;26;;8;;;;; +162;96;1336;;24;;8;;;;True; +162;96;1720;;26;;8;;;;; +162;112;1592;;26;;8;;;;; +162;112;1784;;26;;8;;;;; +162;240;216;;26;;8;;;;; +162;240;1704;;26;;8;;;;; +162;256;1784;;40;;8;;;;; +162;288;248;;42;;8;;;;; +162;464;1144;;26;;8;;;;; +162;544;120;;26;;8;;;;; +162;544;1912;;42;48;8;;;;; +162;608;120;;26;;8;;;;; +162;768;120;;42;;8;;;;; +162;868;1344;-10;4;4;;;;;; +162;928;440;;26;;8;;;;; +162;944;328;;26;;8;;;;; +162;944;440;;26;;8;;;;; +162;1024;408;;26;;8;;;;; +162;1056;312;;26;;8;;;;; +162;1184;312;;26;;8;;;;; +162;1248;72;;26;;8;;;;; +162;1252;1184;-10;4;4;;;;;; +162;1472;120;;26;;8;;;;; +162;1672;1968;10;2;4;32;;;;; +162;1716;1968;-10;2;4;32;;;;; +162;1808;1144;;26;32;8;;;;; +162;1824;232;;60;48;8;;1.5;;; +162;1832;1376;10;2;4;;;;;; +162;1876;1376;-10;2;4;;;;;; +162;1984;224;;66;;8;;1.5;;; +162;2000;1192;;26;;8;;;;; +162;2016;224;;66;;8;;1.5;;; +162;2040;1088;10;4;4;;;;;; +162;2048;224;;66;;8;;1.5;;; +162;2072;1104;10;4;4;;;;;; +162;2224;1944;;26;;8;;;;; +162;2312;336;10;2;4;32;;;;; +162;2336;120;;74;;8;;2;;; +162;2356;336;-10;2;4;32;;;;; +162;2384;120;;26;;8;;;;; +163;1952;608;32;64 +163;1968;480;48; +163;2048;608;32;64 +163;2144;480;32; +163;2448;992;48; +168;48;672;spawn_toadstool;!has_powder&!has_toadstool; +168;1168;896;ow_grave_reset;ow_grave_leave&!dc_spawn_entry; +168;1208;1040;tarin_sequence;tarin=2; +168;1248;896;ow_grave_follower;has_bowWow|maria_state=3|has_ghost|has_rooster; +167;2272;1536;ow_quicksand_entry;0 +170;1120;928;ow_grave_leave;2;;48;True +170;1136;928;ow_grave_leave;;;48; +170;1152;880;ow_grave_leave;3;128;;True +170;1152;896;ow_grave_leave;1;128;; +170;1968;480;raft_active;3;48;;True +170;2144;480;raft_active;3;32;;True +170;2320;1664;ow_quicksand_entry;1;;; +170;2416;1584;ow_quicksand_entry;;;; +25;80;1656;;;; +25;80;1664;;;; +25;96;1336;;;; +25;96;1344;;;; +25;96;1720;;;; +25;96;1728;;;; +25;112;1592;;;; +25;112;1600;;;; +25;112;1784;;;; +25;112;1792;;;; +25;240;216;;;; +25;240;224;;;; +25;240;1704;;;; +25;240;1712;;;; +25;256;1784;;;; +25;256;1792;;;; +25;288;248;;;; +25;288;256;;;; +25;288;272;;;; +25;464;1144;;;; +25;464;1152;;;; +25;544;120;;;; +25;544;128;;;; +25;544;1912;;;; +25;544;1936;;;; +25;560;1912;;;; +25;560;1936;;;; +25;576;1912;;;; +25;576;1936;;;; +25;608;120;;;; +25;608;128;;;; +25;768;120;;;; +25;768;144;;;; +25;928;448;;;; +25;944;448;;;; +25;1024;416;;;; +25;1248;72;;;; +25;1248;80;;;; +25;1472;120;;;; +25;1472;128;;;; +25;1808;1144;;;; +25;1808;1152;;;; +25;1824;232;;;; +25;1824;272;;;; +25;1824;1144;;;; +25;1824;1152;;;; +25;1840;232;;;; +25;1840;256;;;; +25;1856;232;;;; +25;1856;272;;;; +25;2000;1200;;;; +25;2224;1944;;;; +25;2224;1952;;;; +25;2336;120;;;; +25;2336;128;;;; +25;2336;144;;;; +25;2336;160;;;; +25;2336;176;;;; +25;2384;120;;;; +25;2384;128;;;; +26;928;432;;;; +26;944;432;;;; +26;1024;400;;;; +26;2000;1184;;;; +27;864;1344;;;; +27;1248;1184;;;; +27;1672;1968;;;; +27;1672;1984;;;; +27;1712;1968;;;; +27;1712;1984;;;; +27;1832;1376;;;; +27;1872;1376;;;; +27;2040;1088;;;; +27;2072;1104;;;; +27;2312;336;;;; +27;2312;352;;;; +27;2352;336;;;; +27;2352;352;;;; +364;592;1688;; +364;912;1432;; +501;2304;1568;ow_quicksand_entry;ow_desertLanmola +510;80;128;ow_tutle_rock +375;1536;1646;npc_mermaid_gone +375;1568;1600;!npc_mermaid_gone +265;1552;1808;ow_mermaid_statue +460;728;1808 +68;48;160;;;;;; +68;144;160;;;;;; +68;160;128;;;;;; +68;176;128;;;;;; +68;176;208;;;;;; +68;176;224;;;;;; +68;192;128;;;;;; +68;208;128;;;;;; +68;496;144;;;;;; +68;496;192;;;;;; +68;496;208;;;;;; +68;512;176;;;;;; +68;528;144;;;;;; +68;528;160;;;;;; +68;544;192;;;;;; +68;560;160;;;;;; +68;560;224;;;;;; +68;576;192;;;;;; +68;592;96;;;;;; +68;592;144;;;;;; +68;592;160;;;;;; +68;592;176;;;;;; +68;608;224;;;;;; +68;624;144;;;;;; +68;624;192;;;;;; +68;640;160;;;;;; +68;640;176;;;;;; +68;640;208;;;;;; +68;640;224;;;;;; +68;656;208;;;;;; +68;672;224;;;;;; +68;960;192;;;;;; +68;960;208;;;;;; +68;976;208;;;;;; +68;976;224;;;;;; +68;1120;208;;;;;; +68;1120;224;;;;;; +68;1296;32;;;;;; +68;1407;149;;;;;; +68;1407;176;;;;;; +68;1408;136;;;;;; +68;1408;163;;;;;; +68;1440;32;;;;;; +68;1456;32;;;;;; +68;1584;48;;;;;; +288;-16;64 +384;1840;968 +165;688;1760;;stone; +165;1408;720;ow_goldLeafCrow;stone; +164;48;688;spawn_toadstool;1;item;..toadstool.; +164;96;128;ow_tutle_rock;;c1;; +164;96;128;ghost_blockade;1;pushDialog;ghost_blockade; +164;216;1344;final_show;1;bobWowSmall;; +164;224;624;raccoon_transformed;;teleporter;20.16.64.16; +164;224;640;raccoon_warning;;pushDialog;raccoon_warning; +164;240;640;raccoon_warning;;pushDialog;raccoon_warning; +164;240;976;shellsFound;;chest;shellChest..shell_2.1; +164;240;976;shellsFound;1;chest;ruby20..shell_2.1; +164;256;640;raccoon_warning;;pushDialog;raccoon_warning; +164;256;1344;final_show;1;bobWowSmall;bowWow3; +164;272;640;raccoon_warning;;pushDialog;raccoon_warning; +164;288;704;final_show;1;personNew;.tarin mushroom.tarinMushroom.hidden.; +164;288;704;final_show;1;personNew;.tarin.tarinFinal.stand_3.; +164;368;1216;maria_state;1;maria;; +164;368;1216;maria_state;6;maria;; +164;400;1984;final_show;1;e2;; +164;416;1216;ow_weather_bird;1;stairsCastle;; +164;432;2000;final_show;1;e2;; +164;448;672;ow_woods_stone;1;stairsWoods;; +164;448;672;ow_woods_stone;;stoneWoods;..ow_woods_stone;False +164;592;1680;ghost_blockade;1;pushDialog;ghost_blockade; +164;688;880;ghost_grave_powder;1;dialogBox;ghost_grave_powder_dialog; +164;704;272;ghost_blockade;1;pushDialog;ghost_blockade; +164;752;96;ow_mountain_stone;;stone;..ow_mountain_stone;False +164;784;1696;frogStairs;;water2;; +164;784;1696;frogStairs;1;stairsCastle;; +164;784;1696;frogStairs;1;door;16.16.caveFrogs.caveFrogs$map.caveFrogs.3.1.True; +164;784;1696;frogStairs;;water;; +164;896;1984;maria_state;2;maria;; +164;912;1424;ghost_blockade;1;pushDialog;ghost_blockade; +164;1024;848;ow_ghini_0;1;e21;false.true; +164;1040;912;ow_ghini_3;1;e21;false.true; +164;1040;944;ow_ghini_5;1;e21;false.true; +164;1072;912;ow_ghini_4;1;e21;false.true; +164;1072;944;ow_gravestone;1;stairsCastle;; +164;1072;944;ow_gravestone;1;door;16.16..cave10$map.cave10_r.3.1.False;False +164;1088;816;ow_ghini_1;1;e21;false.true; +164;1088;848;ow_ghini_2;1;e21;false.true; +164;1184;64;ow_mountain_bush;1;stairsCastle;; +164;1184;64;ow_mountain_bush;;bush;......ow_mountain_bush;False +164;1184;816;ow_ghini_10;1;e21;false.true; +164;1184;848;ow_ghini_9;1;e21;false.true; +164;1184;912;ow_ghini_6;1;e21;false.true; +164;1200;1216;ow_bigSkullStone;1;stoneSpawner;; +164;1200;1232;ow_bigSkullStone;1;stoneSpawner;; +164;1216;944;ow_ghini_7;1;e21;false.true; +164;1216;1216;ow_bigSkullStone;1;stoneSpawner;; +164;1216;1232;ow_bigSkullStone;1;stoneSpawner;; +164;1224;1096;tarin_state;4;personNew;.tarin.tarin.stand_0.; +164;1232;92;seq_tarin;1;personNew;.tarin.seqTarin..; +164;1248;848;ow_ghini_11;1;e_giantGhini;true; +164;1248;912;ow_grave_follower;1;gravestone;0.......; +164;1248;912;ow_ghini_8;1;e21;false.true; +164;1248;912;ow_grave_follower;0;gravestone;15.ow_grave_4......ow_grave_reset; +164;1248;916;ow_grave_follower;1;pushDialog;grave_locked.16.12; +164;1360;29;maria_state;5;maria;; +164;1520;928;ow_castle_door;0;pushDialog;photo_sequence_4.48.16; +164;1536;1712;ghost_blockade;1;pushDialog;ghost_blockade; +164;1552;160;npc_lost_boy_state;1;lostBoy;;False +164;1568;144;ow_npc_bag;1;npc_bag;; +164;1744;544;ow_castle_bush;1;stairsCastle;; +164;1744;544;ow_castle_bush;;bush;......ow_castle_bush;False +164;1744;1344;ow_village_tunnel;;bush;......ow_village_tunnel;False +164;1776;544;ow_castle_bush;1;dialogBox;ow_castle_bush_sound;False +164;1824;928;monkeyBusiness;3;oneWayBridge2;; +164;1840;216;ow_de4;;waterfallSound;; +164;1840;272;ghost_blockade;1;pushDialog;ghost_blockade; +164;1840;296;ow_de4;;waterfallSound;; +164;1840;944;monkeyBusiness;;c1;; +164;1856;928;monkeyBusiness;3;oneWayBridge0;; +164;1984;816;shellsFound;1;chest;ruby20..shell_22.2;False +164;1984;816;shellsFound;;chest;shellChest..shell_22.2;False +164;2000;1616;hide_rabbit_3;;personNew;.animal_rabbit.rabbit_3..; +164;2016;1712;maria_state;4;maria;; +164;2064;1976;seq_rabit;1;personNew;.animal_rabbit.seqRabit.stand_3.; +164;2128;1728;hide_rabbit_1;;personNew;.animal_rabbit.rabbit_1..; +164;2144;1616;hide_rabbit_0;;personNew;.animal_rabbit.rabbit_0..; +164;2176;144;shellsFound;;chest;shellChest..shell_25.2; +164;2176;144;shellsFound;1;chest;ruby20..shell_25.2; +164;2192;64;mountain_beetle_hide;0;e_spinyBeetle;; +164;2256;1552;ow_quicksand_entry;1;dialogBox;desertLanmola_enter;False +164;2336;32;ghost_blockade;1;pushDialog;ghost_blockade; +164;2492;1744;desert_bones_powder;1;scriptOnTouch;32.32.desert_bones; +32;95;64;;; +32;1712;1824;;; +70;688;1616;;;;;; +70;688;1728;;;;;; +70;704;1712;;;;;; +70;720;1728;;;;;; +70;736;1728;;;;;; +70;800;1744;;;;;; +70;816;1744;;;;;; +70;880;1680;;;;;; +70;896;1488;;;;;; +70;928;1488;;;;;; +70;944;1504;;;;;; +70;944;1584;;;;;; +70;1008;1616;;;;;; +70;1008;1632;;;;;; +70;1008;1648;;;;;; +70;1008;1664;;;;;; +70;1008;1680;;;;;; +70;1008;1696;;;;;; +70;1008;1712;;;;;; +70;1056;1552;;;;;; +70;1072;1600;;;;;; +70;1072;1728;;;;;; +70;1088;1600;;;;;; +70;1104;1600;;;;;; +70;1104;1728;;;;;; +70;1120;1296;;;;;; +70;1120;1552;;;;;; +70;1120;1584;;;;;; +70;1120;1600;;;;;; +70;1120;1728;;;;;; +70;1120;1744;;;;;; +70;1136;1296;;;;;; +70;1136;1744;;;;;; +70;1152;1248;;;;;; +70;1152;1744;;;;;; +70;1168;1744;;;;;; +70;1200;1744;;;;;; +70;1216;1744;;;;;; +70;1232;1216;;;;;; +70;1232;1728;;;;;; +70;1248;1136;;;;;; +70;1248;1536;;;;;; +70;1248;1552;;;;;; +70;1248;1568;;;;;; +70;1248;1584;;;;;; +70;1248;1600;;;;;; +70;1248;1616;;;;;; +70;1248;1632;;;;;; +70;1248;1648;;;;;; +70;1248;1664;;;;;; +70;1248;1680;;;;;; +70;1248;1696;;;;;; +70;1248;1712;;;;;; +70;1392;1568;;;;;; +70;1408;1520;;;;;; +70;1408;1536;;;;;; +70;1408;1568;;;;;; +70;1440;1344;;;;;; +70;1440;1488;;;;;; +70;1440;1520;;;;;; +70;1440;1536;;;;;; +70;1456;1344;;;;;; +70;1456;1488;;;;;; +70;1456;1520;;;;;; +70;1456;1536;;;;;; +70;1472;1344;;;;;; +70;1472;1376;;;;;; +70;1472;1424;;;;;; +70;1472;1456;;;;;; +70;1472;1488;;;;;; +70;1488;1312;;;;;; +70;1488;1328;;;;;; +70;1488;1344;;;;;; +70;1488;1488;;;;;; +70;1488;1520;;;;;; +70;1488;1536;;;;;; +70;1504;1312;;;;;; +70;1504;1376;;;;;; +70;1504;1424;;;;;; +70;1520;1312;;;;;; +70;1520;1472;;;;;; +70;1520;1488;;;;;; +70;1536;1312;;;;;; +70;1536;1344;;;;;; +70;1536;1376;;;;;; +70;1536;1424;;;;;; +70;1536;1456;;;;;; +70;1552;1312;;;;;; +70;1552;1456;;;;;; +70;1568;1344;;;;;; +70;1568;1360;;;;;; +70;1568;1376;;;;;; +70;1568;1392;;;;;; +70;1568;1408;;;;;; +70;1568;1424;;;;;; +70;1568;1440;;;;;; +70;1568;1456;;;;;; +70;1792;1376;;;;;; +70;1904;1376;;;;;; +70;2240;1120;;;;;; +70;2240;1184;;;;;; +70;2240;1232;;;;;; +70;2256;1120;;;;;; +70;2256;1184;;;;;; +70;2256;1232;;;;;; +70;2272;336;;;;;; +70;2272;1136;;;;;; +70;2272;1152;;;;;; +70;2272;1184;;;;;; +70;2272;1200;;;;;; +70;2272;1232;;;;;; +70;2288;1184;;;;;; +70;2288;1232;;;;;; +70;2304;1136;;;;;; +70;2304;1152;;;;;; +70;2304;1184;;;;;; +70;2304;1232;;;;;; +70;2320;1184;;;;;; +70;2336;1184;;;;;; +70;2336;1216;;;;;; +70;2352;1136;;;;;; +70;2352;1152;;;;;; +70;2352;1168;;;;;; +70;2352;1184;;;;;; +70;2352;1216;;;;;; +70;2384;352;;;;;; +70;2384;1120;;;;;; +70;2384;1136;;;;;; +70;2384;1152;;;;;; +70;2400;1184;;;;;; +70;2400;1216;;;;;; +70;2416;1184;;;;;; +70;2416;1216;;;;;; +70;2432;1216;;;;;; +70;2448;1200;;;;;; +70;2448;1216;;;;;; +152;16;0 +237;272;64;2 +237;912;1216;0 +237;2032;320;1 +237;2032;1856;3 +365;112;1074;1_1;-16.0.48.32;;; +365;280;544;1_2;-48.24.48.32;;; +365;408;1952;0;;;; +365;424;1732;2_0;0.0.32.32;;; +365;688;835;5_0;;;; +365;728;520;2_1;-56.-30.112.80;;; +365;1048;16;9_0;0.16.16.48;;;1 +365;1048;456;2_1;-56.-40.112.80;;; +365;1056;176;owl_stairs;0.40.16.16;;;2 +365;1064;1424;3_0;-74.0.128.48;;; +365;1224;184;7_1;-16.16.32.32;;; +365;1360;36;8_0;-64.-16.32.32;;; +365;2008;1164;7_0;-32.0.32.32;;; +365;2040;1352;1;-32.-32.32.32;;owl_shrine; +365;2152;1182;6_0;-32.48.32.32;;; +365;2296;1816;3_1;-32.-24.64.32;;; +365;2344;1824;3_1;-16.-24.32.32;;; +76;192;208;;;;;; +76;864;464;;;;;; +76;1088;1552;;;;;; +76;1360;1344;;;;;; +76;1680;1712;;;;;; +76;2160;656;;;;;; +76;2272;192;;;;;; +76;2464;1552;;;;;; +76;2528;1088;;;;;; +359;448;1232;spawned_npc_boy_2;npc_green_boy;npc_boy_2;; +359;528;1488;;npc_green_boy;npc_boy_0;stand_3; +359;576;1056;;npc_green_boy;npc_boy_1;; +44;256;138;;;;;; +44;256;432;;;;;; +44;400;1456;;;;;; +44;688;1312;;;;;; +44;1328;1856;;;;;; +44;1360;1072;;;;;; +44;1824;512;;;;;; +44;1872;1712;;;;;; +378;330;1498;spawnMouseSeq2;mouseSeq2 +378;2048;59;spawnMouseMountain;mouseSeqMountain +101;560;688;;;;;; +101;576;688;;;;;; +166;752;96;ow_mountain_stone;1;ow_mountain_cave +166;784;1696;frogStairs;1;shieldGameStairs +166;1248;912;dc_spawn_entry;1;dc_entry +166;1744;1344;ow_village_tunnel;1;ow_village_tunnel_spawn +206;248;1352;start_BowWow_Seq;8;8 +206;263;1488;photo_sequence_2;2; +206;688;848;photo_sequence_grave;; +206;2272;64;ow_d7_keyhole;;14 +207;1024;848;ow_ghini_0;; +207;1040;912;ow_ghini_3;; +207;1040;944;ow_ghini_5;; +207;1072;912;ow_ghini_4;; +207;1088;816;ow_ghini_1;; +207;1088;848;ow_ghini_2;; +207;1184;816;ow_ghini_10;; +207;1184;848;ow_ghini_9;; +207;1184;912;ow_ghini_6;; +207;1216;944;ow_ghini_7;; +207;1248;848;ow_ghini_11;; +207;1248;912;ow_ghini_8;; +191;2272;1568;0.25;0.25; +191;2272;1584;0.25;0.25; +191;2272;1600;0.25;-0.25; +191;2272;1616;0.25;-0.25; +191;2272;1632;0.25;-0.25; +191;2288;1552;0.25;0.25; +191;2288;1568;0.25;0.25; +191;2288;1584;0.25;0.25; +191;2288;1600;0.25;-0.25; +191;2288;1616;0.25;-0.25; +191;2288;1632;0.25;-0.25; +191;2304;1552;0.25;0.25; +191;2304;1568;0.25;0.25; +191;2304;1584;0.25;0.25; +191;2304;1600;0.25;-0.25; +191;2304;1616;0.25;-0.25; +191;2304;1632;0.25;-0.25; +191;2320;1552;0.25;0.25; +191;2320;1568;0.25;0.25; +191;2320;1584;0.25;0.25; +191;2320;1600;0.25;-0.25; +191;2320;1616;0.25;-0.25; +191;2320;1632;0.25;-0.25; +191;2336;1552;-0.25;0.25; +191;2336;1568;-0.25;0.25; +191;2336;1584;-0.25;0.25; +191;2336;1600;-0.25;-0.25; +191;2336;1616;-0.25;-0.25; +191;2336;1632;-0.25;-0.25; +191;2352;1552;-0.25;0.25; +191;2352;1568;-0.25;0.25; +191;2352;1584;-0.25;0.25; +191;2352;1600;-0.25;-0.25; +191;2352;1616;-0.25;-0.25; +191;2352;1632;-0.25;-0.25; +191;2368;1552;-0.25;0.25; +191;2368;1568;-0.25;0.25; +191;2368;1584;-0.25;0.25; +191;2368;1600;-0.25;-0.25; +191;2368;1616;-0.25;-0.25; +191;2368;1632;-0.25;-0.25; +191;2384;1568;-0.25;0.25; +191;2384;1584;-0.25;0.25; +191;2384;1600;-0.25;-0.25; +191;2384;1616;-0.25;-0.25; +191;2384;1632;-0.25;-0.25; +368;288;688 +243;2480;448;raft_active +29;2016;704;;;; +29;2176;688;;;; +29;2208;1088;;;; +29;2368;1072;;;; +29;2480;448;;;; +84;544;1200;;;; +85;208;1296;;;; +86;560;1440;;;; +87;2432;384;;;; +88;2160;1680;;;; +89;1184;400;;;; +120;2336;1600;;;;;1; +120;2336;1616;;;;;1; +120;2336;1632;;;;;1; +120;2352;1600;;;;;1; +120;2352;1616;;;;;1; +120;2352;1632;;;;;1; +120;2368;1600;;;;;1; +120;2368;1616;;;;;1; +120;2368;1632;;;;;1; +120;2384;1600;;;;;1; +120;2384;1616;;;;;1; +120;2384;1632;;;;;1; +121;2272;1600;;;;;; +121;2272;1616;;;;;; +121;2272;1632;;;;;; +121;2288;1600;;;;;; +121;2288;1616;;;;;; +121;2288;1632;;;;;; +121;2304;1600;;;;;; +121;2304;1616;;;;;; +121;2304;1632;;;;;; +121;2320;1600;;;;;; +121;2320;1616;;;;;; +121;2320;1632;;;;;; +121;2336;1552;;;;;3; +121;2336;1568;;;;;3; +121;2336;1584;;;;;3; +121;2352;1552;;;;;3; +121;2352;1568;;;;;3; +121;2352;1584;;;;;3; +121;2368;1552;;;;;3; +121;2368;1568;;;;;3; +121;2368;1584;;;;;3; +121;2384;1568;;;;;3; +121;2384;1584;;;;;3; +122;2272;1568;;;;;2; +122;2272;1584;;;;;2; +122;2288;1552;;;;;2; +122;2288;1568;;;;;2; +122;2288;1584;;;;;2; +122;2304;1552;;;;;2; +122;2304;1568;;;;;2; +122;2304;1584;;;;;2; +122;2320;1552;;;;;2; +122;2320;1568;;;;;2; +122;2320;1584;;;;;2; +175;-64;1376;;;final_test_instrument +175;48;1996;;;check_cliff_sequence +175;408;1216;32;24;start_weather_bird_seq +175;676;836;40;40;ghost_grave_sequence +175;1072;1984;;;ghost_house_dialog +175;2170;64;;;mountain_mouse_seq +46;1680;1056;;;;;; +178;-48;96;; +209;208;1184;;bomb_1 +209;384;1728;shell_12; +209;448;1312;;fairy +209;752;1312;shell_10; +209;864;1184;;fairy +209;1648;784;;fairy +209;2512;1056;;fairy +290;-64;1808 +210;-16;32 +205;192;208;signHead2;;;1 +205;864;464;signHead1;;;1 +205;1088;1552;signHead9;;;1 +205;1360;1344;signHead6;;;1 +205;1656;1104;talking_tree;;;1 +205;1680;1712;signHead4;;; +205;1736;1104;talking_tree;;;1 +205;2160;656;signHead8;;;1 +205;2272;192;signHead7;;;1 +205;2464;1552;signHead3;;;1 +205;2528;1088;signHead5;;;1 +203;80;464;signpost15;;; +203;80;1552;signpost1;;; +203;96;1232;signpost2;;; +203;208;1804;signpost4;;; +203;384;432;signpost16;;; +203;672;1696;shieldGame15;;; +203;688;1568;shieldGame6;;; +203;688;1744;shieldGame5;;; +203;704;1168;signpost3;;; +203;720;1344;signpost19;;; +203;736;1472;shieldGame1;;; +203;736;1632;shieldGame2;;; +203;768;1584;shieldGame11;;; +203;768;1616;shieldGame12;;; +203;848;540;signpost13;;; +203;848;1568;shieldGame7;;; +203;848;1712;shieldGame8;;; +203;880;304;signpost12;;; +203;880;1632;shieldGame3;;; +203;880;1744;shieldGame4;;; +203;912;1616;shieldGame13;;; +203;912;1696;shieldGame14;;; +203;928;1584;shieldGame10;;; +203;928;1712;shieldGame9;;; +203;944;832;signpost14;;; +203;1024;444;signpost11;;; +203;1040;204;signpost20;;; +203;1088;1728;signpost17;;; +203;1184;1744;signpost6;;; +203;1408;1184;signpost7;;; +203;1568;1072;signpost8;;; +203;1664;1312;signpost9;;; +203;1712;1088;signpost10;;; +203;1888;1600;signpost23;;; +203;2128;1952;signpost22;;; +203;2464;416;signpost21;;; +204;424;828;signpost5;;; +160;96;48; +160;96;64; +160;112;1904; +160;112;1920; +160;144;1712; +160;144;1728; +160;224;272; +160;224;288; +160;272;80; +160;512;1136; +160;512;1152; +160;704;912; +160;720;176; +160;720;192; +160;768;880; +160;768;896; +160;880;112; +160;880;128; +160;880;144; +160;880;576; +160;896;1072; +160;896;1088; +160;896;1104; +160;912;1232; +160;912;1520; +160;912;1536; +160;992;1392; +160;992;1408; +160;1056;64; +160;1056;80; +160;1056;96; +160;1056;112; +160;1056;128; +160;1056;144; +160;1056;160; +160;1056;176; +160;1056;192; +160;1056;240; +160;1056;256; +160;1056;272; +160;1216;208; +160;1216;224; +160;1216;240; +160;1216;256; +160;1232;112; +160;1232;128; +160;1232;144; +160;1264;1216; +160;1264;1232; +160;1328;1200; +160;1328;1216; +160;1344;1936; +160;1344;2000; +160;1376;1728; +160;1376;1744; +160;1472;368; +160;1472;384; +160;1472;400; +160;1472;1584; +160;1488;192; +160;1680;64; +160;1680;80; +160;1696;1936; +160;1712;1504; +160;1728;1440; +160;1744;832; +160;1744;1680; +160;1792;464; +160;1840;432; +160;1856;1184; +160;1984;112; +160;1984;128; +160;1984;144; +160;1984;160; +160;1984;176; +160;1984;192; +160;1984;1136; +160;1984;1152; +160;2016;704; +160;2016;1392; +160;2016;1408; +160;2032;336; +160;2032;1872; +160;2128;1840; +160;2160;1200; +160;2176;336; +160;2176;688; +160;2176;1120; +160;2208;1088; +160;2288;416; +160;2304;160; +160;2304;176; +160;2304;192; +160;2336;48; +160;2336;64; +160;2368;1072; +160;2432;160; +160;2480;448; +65;864;1416;;;;;; +65;864;1436;;;;;; +65;864;1456;;;;;; +65;880;1472;;;;;; +65;944;1472;;;;;; +66;912;1472;;;;;; +228;80;336;;;;;; +228;128;336;;;;;; +228;512;1088;;;;;; +228;528;1104;;;;;; +228;544;1088;;;;;; +228;704;1744;;;;;; +228;720;448;;;;;; +228;720;464;;;;;; +228;736;1168;;heart;;;; +228;736;1184;;heart;;;; +228;752;288;;;;;; +228;752;544;;;;;; +228;768;288;;;;;; +228;768;336;;;;;; +228;768;352;;;;;; +228;768;863;;;;;; +228;832;80;;;;;; +228;832;592;;;;;; +228;848;944;;;;;; +228;848;960;;;;;; +228;864;64;;;;;; +228;864;288;;;;;; +228;864;304;;;;;; +228;864;560;;;;;; +228;864;928;;;;;; +228;864;976;;;;;; +228;880;80;;;;;; +228;880;672;;;;;; +228;880;944;;;;;; +228;880;960;;;;;; +228;896;96;;;;;; +228;896;304;;;;;; +228;896;688;;;;;; +228;896;1055;;;;;; +228;896;1616;;;;;; +228;912;64;;;;;; +228;912;1712;;;;;; +228;927;832;;;;;; +228;928;1840;;;;;; +228;928;1856;;;;;; +228;944;1824;;;;;; +228;992;576;;;;;; +228;1168;176;;;;;; +228;1184;192;;;;;; +228;1200;176;;;;;; +228;1376;336;;;;;; +228;1408;736;;;;;; +228;1520;1456;;shell;shell_15;;; +228;1632;1968;;;;;; +228;1744;1984;;;;;; +228;2048;32;;;;;; +228;2064;32;;shell;shell_24;;; +228;2272;80;;;;;; +228;2272;1120;;;;;; +228;2272;1168;;;;;; +228;2288;64;;;;;; +228;2288;1120;;;;;; +228;2288;1168;;;;;; +228;2304;1168;;;;;; +228;2304;1200;;;;;; +228;2304;1248;;;;;; +228;2320;1200;;;;;; +228;2320;1216;;;;;; +228;2320;1248;;;;;; +228;2336;1168;;;;;; +228;2336;1200;;;;;; +228;2352;1120;;;;;; +228;2352;1248;;;;;; +228;2368;1168;;;;;; +228;2368;1216;;;;;; +228;2384;1168;;;;;; +228;2384;1184;;;;;; +228;2384;1200;;;;;; +228;2384;1216;;;;;; +228;2384;1248;;;;;; +228;2432;1120;;;;;; +228;2480;1232;;;;;; +228;2496;1232;;;;;; +228;2496;1968;;;;;; +228;2496;1984;;shell;shell_16;;; +212;48;144 +212;48;192 +212;64;80 +212;64;96 +212;64;160 +212;64;208 +212;80;80 +212;80;96 +212;80;144 +212;80;160 +212;80;192 +212;80;208 +212;96;80 +212;96;96 +212;96;144 +212;96;160 +212;96;176 +212;96;192 +212;96;208 +212;112;80 +212;112;96 +212;112;144 +212;112;160 +212;112;192 +212;128;80 +212;128;96 +212;128;160 +212;144;144 +212;144;192 +212;160;112 +212;160;144 +212;160;160 +212;160;176 +212;176;112 +212;176;144 +212;176;160 +212;176;176 +212;192;112 +212;192;160 +212;192;176 +212;208;112 +212;208;240 +212;224;160 +212;224;176 +212;352;176 +212;400;144 +212;624;224 +212;656;192 +212;736;224 +212;832;64 +212;832;160 +212;832;704 +212;848;720 +212;864;96 +212;864;720 +212;880;656 +212;880;704 +212;896;656 +212;928;736 +212;944;144 +212;944;208 +212;944;736 +212;960;720 +212;976;720 +212;992;224 +212;992;592 +212;992;640 +212;992;720 +212;1008;576 +212;1008;704 +212;1008;800 +212;1008;880 +212;1024;560 +212;1024;576 +212;1024;736 +212;1024;800 +212;1024;880 +212;1024;912 +212;1040;560 +212;1040;736 +212;1040;800 +212;1040;896 +212;1056;560 +212;1056;800 +212;1056;832 +212;1056;896 +212;1072;720 +212;1072;800 +212;1072;864 +212;1088;208 +212;1088;288 +212;1088;608 +212;1088;720 +212;1088;864 +212;1088;928 +212;1104;608 +212;1104;640 +212;1104;848 +212;1104;928 +212;1120;656 +212;1120;960 +212;1136;656 +212;1152;656 +212;1152;720 +212;1152;896 +212;1168;192 +212;1168;704 +212;1168;736 +212;1168;864 +212;1168;928 +212;1168;1232 +212;1184;96 +212;1184;544 +212;1184;704 +212;1184;864 +212;1184;928 +212;1200;288 +212;1200;576 +212;1200;624 +212;1200;656 +212;1200;720 +212;1200;832 +212;1200;912 +212;1216;32 +212;1216;176 +212;1216;528 +212;1216;576 +212;1216;624 +212;1232;928 +212;1248;272 +212;1248;368 +212;1248;608 +212;1248;672 +212;1248;720 +212;1264;304 +212;1264;416 +212;1280;128 +212;1296;1568 +212;1312;112 +212;1312;1552 +212;1328;1568 +212;1344;1536 +212;1360;1536 +212;1360;1888 +212;1392;160 +212;1392;1840 +212;1424;144 +212;1488;176 +212;1536;160 +212;1552;96 +212;1584;128 +212;1648;16 +212;1664;32 +212;1712;16 +212;1744;48 +212;1840;112 +212;1856;112 +212;1872;96 +212;2256;1536 +212;2256;1856 +212;2256;1920 +212;2272;1792 +212;2304;96 +212;2304;1760 +212;2352;80 +212;2384;1056 +212;2400;80 +212;2400;1536 +212;2432;64 +212;2432;144 +212;2512;1968 +212;2528;64 +212;2528;1280 +212;2544;1440 +212;2544;1504 +212;2544;1536 +267;576;128;;ow_mountain_wall_0;;; +267;672;1936;;ow_sw_1;;; +267;992;1072;;ow_sw_2;;; +267;1168;1024;;ow_sw_3;;; +267;2144;1040;;ow_sw_cf2;;; +267;2224;1552;;village_cave_entry;;; +267;2464;192;;ow_mountain_wall_1;;; +229;208;944;;;;;; +229;368;576;;;;;; +229;384;592;;;;;; +229;400;576;;;;;; +47;112;1984;;;;;; +47;224;1968;;;;;; +47;272;1984;;;;;; +47;448;1984;;;;;; +47;544;1984;;;;;; +47;720;1968;;;;;; +47;848;1872;;;;;; +47;864;1824;;;;;; +47;864;1984;;;;;; +47;912;1840;;;;;; +48;128;1952;;;; +48;272;1888;;;; +48;272;1936;;;; +48;304;1968;;;; +48;368;1872;;;; +48;400;1888;;;; +48;464;1968;;;; +48;544;1952;;;; +48;624;1968;;;; +48;672;1984;;;; +48;720;1888;;;; +48;736;1936;;;; +48;784;1840;;;; +48;784;1968;;;; +48;832;1840;;;; +48;896;1808;;;; +48;896;1936;;;; +43;2256;1680;;;;;; +43;2400;1808;;;;;; +43;2400;1904;;;;;; +43;2400;1968;;;;;; +43;2416;1808;;;;;; +43;2416;1904;;;;;; +43;2416;1968;;;;;; +43;2480;1904;;;;;; +43;2496;1904;;;;;; +43;2512;1904;;;;;; +35;48;1152;;;;;; +35;48;1184;;;;;; +35;48;1216;;;;;; +35;48;1248;;;;;; +35;48;1280;;;;;; +35;48;1520;;;;;; +35;64;1168;;;;;; +35;80;1152;;;;;; +35;128;240;;;;;; +35;128;1152;;;;;; +35;128;1520;;;;;; +35;144;1168;;;;;; +35;144;1200;;;;;; +35;144;1232;;;;;; +35;144;1264;;;;;; +35;144;1504;;;;;; +35;160;240;;;;;; +35;160;1152;;;;;; +35;160;1184;;;;;; +35;160;1216;;;;;; +35;160;1248;;;;;; +35;160;1392;;;;;; +35;160;1424;;;;;; +35;160;1456;;;;;; +35;160;1488;;;;;; +35;160;1520;;;;;; +35;176;1136;;;;;; +35;176;1264;;;;;; +35;176;1504;;;;;; +35;192;1520;;;;;; +35;208;1184;;;;;; +35;208;1264;;;;;; +35;224;416;;;;;; +35;224;1520;;;;;; +35;256;1216;;;;;; +35;256;1520;;;;;; +35;288;416;;;;;; +35;288;1264;;;;;; +35;288;1520;;;;;; +35;304;480;;;;;; +35;304;1056;;;;;; +35;304;1088;;;;;; +35;304;1120;;;;;; +35;304;1152;;;;;; +35;320;1040;;;;;; +35;320;1072;;;;;; +35;320;1104;;;;;; +35;320;1136;;;;;; +35;320;1168;;;;;; +35;320;1200;;;;;; +35;320;1232;;;;;; +35;320;1264;;;;;; +35;320;1520;;;;;; +35;320;1584;;;;;; +35;320;1616;;;;;; +35;320;1648;;;;;; +35;320;1680;;;;;; +35;320;1712;;;;;; +35;320;1744;;;;;; +35;336;480;;;;;; +35;336;1024;;;;;; +35;352;1520;;;;;; +35;352;1600;;;;;; +35;368;480;;;;;; +35;368;1024;;;;;; +35;384;1520;;;;;; +35;384;1728;;;;;; +35;400;480;;;;;; +35;400;1024;;;;;; +35;416;1520;;;;;; +35;416;1584;;;;;; +35;432;480;;;;;; +35;432;1024;;;;;; +35;448;1312;;;;;; +35;448;1520;;;;;; +35;448;1584;;;;;; +35;464;1024;;;;;; +35;464;1648;;;;;; +35;464;1712;;;;;; +35;480;1520;;;;;; +35;480;1584;;;;;; +35;480;1632;;;;;; +35;480;1664;;;;;; +35;480;1696;;;;;; +35;480;1728;;;;;; +35;496;1024;;;;;; +35;496;1648;;;;;; +35;512;1520;;;;;; +35;512;1584;;;;;; +35;528;1024;;;;;; +35;528;1648;;;;;; +35;544;1520;;;;;; +35;560;1024;;;;;; +35;576;1520;;;;;; +35;592;1024;;;;;; +35;592;1504;;;;;; +35;592;1536;;;;;; +35;624;1024;;;;;; +35;624;1536;;;;;; +35;640;496;;;;;; +35;640;1088;;;;;; +35;640;1120;;;;;; +35;640;1152;;;;;; +35;640;1200;;;;;; +35;640;1232;;;;;; +35;640;1264;;;;;; +35;640;1296;;;;;; +35;640;1328;;;;;; +35;640;1360;;;;;; +35;640;1392;;;;;; +35;640;1552;;;;;; +35;640;1584;;;;;; +35;640;1616;;;;;; +35;640;1648;;;;;; +35;640;1680;;;;;; +35;640;1712;;;;;; +35;640;1744;;;;;; +35;656;512;;;;;; +35;656;544;;;;;; +35;656;1024;;;;;; +35;656;1248;;;;;; +35;656;1536;;;;;; +35;656;1600;;;;;; +35;656;1728;;;;;; +35;672;496;;;;;; +35;672;528;;;;;; +35;672;752;;;;;; +35;672;784;;;;;; +35;672;1232;;;;;; +35;672;1264;;;;;; +35;672;1488;;;;;; +35;672;1520;;;;;; +35;688;480;;;;;; +35;688;512;;;;;; +35;688;768;;;;;; +35;688;800;;;;;; +35;688;1024;;;;;; +35;688;1248;;;;;; +35;688;1504;;;;;; +35;688;1536;;;;;; +35;704;752;;;;;; +35;704;816;;;;;; +35;704;1232;;;;;; +35;704;1264;;;;;; +35;704;1472;;;;;; +35;720;832;;;;;; +35;720;1024;;;;;; +35;720;1216;;;;;; +35;736;432;;;;;; +35;736;848;;;;;; +35;736;1040;;;;;; +35;736;1104;;;;;; +35;736;1136;;;;;; +35;736;1200;;;;;; +35;752;480;;;;;; +35;752;512;;;;;; +35;752;1024;;;;;; +35;752;1072;;;;;; +35;752;1312;;;;;; +35;768;304;;;;;; +35;768;368;;;;;; +35;768;416;;;;;; +35;768;496;;;;;; +35;784;480;;;;;; +35;784;512;;;;;; +35;784;1024;;;;;; +35;784;1360;;;;;; +35;784;1392;;;;;; +35;784;1424;;;;;; +35;784;1456;;;;;; +35;784;1488;;;;;; +35;784;1520;;;;;; +35;800;288;;;;;; +35;800;368;;;;;; +35;800;400;;;;;; +35;800;464;;;;;; +35;800;496;;;;;; +35;800;592;;;;;; +35;800;624;;;;;; +35;800;656;;;;;; +35;800;688;;;;;; +35;800;720;;;;;; +35;800;752;;;;;; +35;800;1600;;;;;; +35;816;480;;;;;; +35;816;512;;;;;; +35;816;736;;;;;; +35;816;1024;;;;;; +35;832;288;;;;;; +35;832;496;;;;;; +35;832;656;;;;;; +35;832;752;;;;;; +35;848;512;;;;;; +35;848;688;;;;;; +35;848;1024;;;;;; +35;864;496;;;;;; +35;864;528;;;;;; +35;864;752;;;;;; +35;864;1184;;;;;; +35;880;512;;;;;; +35;880;1024;;;;;; +35;880;1552;;;;;; +35;896;496;;;;;; +35;896;752;;;;;; +35;896;1568;;;;;; +35;912;512;;;;;; +35;912;672;;;;;; +35;928;496;;;;;; +35;944;480;;;;;; +35;944;512;;;;;; +35;944;688;;;;;; +35;944;800;;;;;; +35;944;976;;;;;; +35;944;1008;;;;;; +35;944;1264;;;;;; +35;944;1744;;;;;; +35;960;496;;;;;; +35;960;592;;;;;; +35;960;624;;;;;; +35;960;656;;;;;; +35;960;752;;;;;; +35;960;784;;;;;; +35;960;816;;;;;; +35;960;880;;;;;; +35;960;912;;;;;; +35;960;944;;;;;; +35;960;992;;;;;; +35;960;1088;;;;;; +35;960;1120;;;;;; +35;960;1152;;;;;; +35;960;1584;;;;;; +35;960;1616;;;;;; +35;960;1648;;;;;; +35;960;1680;;;;;; +35;960;1712;;;;;; +35;976;480;;;;;; +35;976;512;;;;;; +35;976;544;;;;;; +35;976;976;;;;;; +35;976;1008;;;;;; +35;976;1264;;;;;; +35;976;1744;;;;;; +35;976;1776;;;;;; +35;992;752;;;;;; +35;1008;1264;;;;;; +35;1008;1776;;;;;; +35;1008;1840;;;;;; +35;1024;752;;;;;; +35;1040;1264;;;;;; +35;1040;1776;;;;;; +35;1040;1856;;;;;; +35;1056;752;;;;;; +35;1072;1264;;;;;; +35;1072;1760;;;;;; +35;1072;1856;;;;;; +35;1088;496;;;;;; +35;1088;752;;;;;; +35;1104;480;;;;;; +35;1104;1200;;;;;; +35;1104;1264;;;;;; +35;1104;1776;;;;;; +35;1104;1840;;;;;; +35;1120;464;;;;;; +35;1120;496;;;;;; +35;1120;752;;;;;; +35;1120;1120;;;;;; +35;1120;1152;;;;;; +35;1120;1184;;;;;; +35;1120;1216;;;;;; +35;1120;1248;;;;;; +35;1120;1856;;;;;; +35;1120;1888;;;;;; +35;1120;1920;;;;;; +35;1136;1200;;;;;; +35;1136;1264;;;;;; +35;1136;1776;;;;;; +35;1136;1840;;;;;; +35;1152;496;;;;;; +35;1152;752;;;;;; +35;1152;1904;;;;;; +35;1152;1936;;;;;; +35;1168;1264;;;;;; +35;1168;1776;;;;;; +35;1168;1840;;;;;; +35;1168;1920;;;;;; +35;1168;1984;;;;;; +35;1184;496;;;;;; +35;1184;1248;;;;;; +35;1184;1856;;;;;; +35;1184;1904;;;;;; +35;1184;1936;;;;;; +35;1200;1056;;;;;; +35;1200;1264;;;;;; +35;1200;1776;;;;;; +35;1200;1920;;;;;; +35;1200;1984;;;;;; +35;1216;496;;;;;; +35;1216;752;;;;;; +35;1216;1280;;;;;; +35;1216;1344;;;;;; +35;1216;1376;;;;;; +35;1216;1408;;;;;; +35;1216;1840;;;;;; +35;1216;1904;;;;;; +35;1216;1936;;;;;; +35;1232;512;;;;;; +35;1232;1008;;;;;; +35;1232;1264;;;;;; +35;1232;1440;;;;;; +35;1232;1472;;;;;; +35;1232;1504;;;;;; +35;1232;1776;;;;;; +35;1232;1824;;;;;; +35;1232;1984;;;;;; +35;1248;496;;;;;; +35;1248;528;;;;;; +35;1248;752;;;;;; +35;1248;1760;;;;;; +35;1248;1792;;;;;; +35;1264;512;;;;;; +35;1264;544;;;;;; +35;1264;576;;;;;; +35;1264;608;;;;;; +35;1264;640;;;;;; +35;1264;672;;;;;; +35;1264;704;;;;;; +35;1264;736;;;;;; +35;1264;768;;;;;; +35;1264;992;;;;;; +35;1264;1024;;;;;; +35;1264;1120;;;;;; +35;1264;1264;;;;;; +35;1264;1776;;;;;; +35;1264;1936;;;;;; +35;1280;496;;;;;; +35;1280;1056;;;;;; +35;1280;1088;;;;;; +35;1280;1248;;;;;; +35;1280;1280;;;;;; +35;1296;240;;;;;; +35;1296;992;;;;;; +35;1296;1024;;;;;; +35;1296;1120;;;;;; +35;1296;1264;;;;;; +35;1296;1376;;;;;; +35;1296;1408;;;;;; +35;1296;1440;;;;;; +35;1296;1472;;;;;; +35;1296;1504;;;;;; +35;1296;1776;;;;;; +35;1312;1488;;;;;; +35;1312;1520;;;;;; +35;1328;1008;;;;;; +35;1328;1120;;;;;; +35;1328;1264;;;;;; +35;1344;624;;;;;; +35;1344;656;;;;;; +35;1360;1008;;;;;; +35;1376;1264;;;;;; +35;1392;752;;;;;; +35;1392;784;;;;;; +35;1392;1008;;;;;; +35;1392;1296;;;;;; +35;1408;1136;;;;;; +35;1408;1264;;;;;; +35;1424;1008;;;;;; +35;1440;1136;;;;;; +35;1440;1168;;;;;; +35;1440;1200;;;;;; +35;1440;1232;;;;;; +35;1440;1264;;;;;; +35;1456;1008;;;;;; +35;1472;1136;;;;;; +35;1472;1264;;;;;; +35;1488;576;;;;;; +35;1520;576;;;;;; +35;1536;1136;;;;;; +35;1552;400;;;;;; +35;1568;1136;;;;;; +35;1584;1264;;;;;; +35;1600;1008;;;;;; +35;1600;1040;;;;;; +35;1600;1072;;;;;; +35;1600;1104;;;;;; +35;1600;1136;;;;;; +35;1600;1168;;;;;; +35;1600;1296;;;;;; +35;1600;1392;;;;;; +35;1616;1264;;;;;; +35;1632;1008;;;;;; +35;1632;1392;;;;;; +35;1648;752;;;;;; +35;1648;784;;;;;; +35;1648;1264;;;;;; +35;1648;1344;;;;;; +35;1648;1872;;;;;; +35;1664;1008;;;;;; +35;1664;1392;;;;;; +35;1664;1904;;;;;; +35;1680;1264;;;;;; +35;1680;1296;;;;;; +35;1680;1344;;;;;; +35;1696;1008;;;;;; +35;1696;1280;;;;;; +35;1696;1392;;;;;; +35;1712;1264;;;;;; +35;1712;1296;;;;;; +35;1712;1344;;;;;; +35;1728;512;;;;;; +35;1728;1008;;;;;; +35;1728;1392;;;;;; +35;1744;1264;;;;;; +35;1760;480;;;;;; +35;1760;512;;;;;; +35;1760;1008;;;;;; +35;1760;1392;;;;;; +35;1760;1520;;;;;; +35;1760;1552;;;;;; +35;1760;1584;;;;;; +35;1760;1616;;;;;; +35;1760;1648;;;;;; +35;1760;1904;;;;;; +35;1760;1936;;;;;; +35;1776;576;;;;;; +35;1776;608;;;;;; +35;1776;640;;;;;; +35;1776;672;;;;;; +35;1776;704;;;;;; +35;1776;736;;;;;; +35;1776;768;;;;;; +35;1776;1168;;;;;; +35;1776;1264;;;;;; +35;1792;1008;;;;;; +35;1792;1392;;;;;; +35;1792;1904;;;;;; +35;1808;880;;;;;; +35;1808;1872;;;;;; +35;1840;752;;;;;; +35;1856;848;;;;;; +35;1856;880;;;;;; +35;1888;1568;;;;;; +35;1904;1584;;;;;; +35;1904;1632;;;;;; +35;1904;1664;;;;;; +35;1904;1696;;;;;; +35;1904;1728;;;;;; +35;2000;1776;;;;;; +35;2000;1920;;;;;; +35;2016;1936;;;;;; +35;2032;1776;;;;;; +35;2032;1920;;;;;; +35;2032;1968;;;;;; +35;2064;1776;;;;;; +35;2064;1920;;;;;; +35;2096;1776;;;;;; +35;2096;1920;;;;;; +35;2128;1920;;;;;; +35;2144;1776;;;;;; +35;2144;1808;;;;;; +35;2192;1776;;;;;; +35;2224;1744;;;;;; +35;2224;1776;;;;;; +35;2400;352;;;;;; +35;2400;384;;;;;; +35;2400;416;;;;;; +35;2416;368;;;;;; +35;2448;368;;;;;; +35;2512;1056;;;;;; +38;1952;752;;;;;; +38;1984;752;;;;;; +38;2016;752;;;;;; +38;2048;752;;;;;; +38;2064;736;;;;;; +38;2064;832;;;;;; +38;2080;752;;;;;; +38;2096;736;;;;;; +38;2096;832;;;;;; +38;2112;752;;;;;; +38;2128;608;;;;;; +38;2144;752;;;;;; +38;2160;608;;;;;; +38;2160;816;;;;;; +38;2176;752;;;;;; +38;2176;800;;;;;; +38;2192;544;;;;;; +38;2192;608;;;;;; +38;2208;560;;;;;; +38;2208;752;;;;;; +38;2208;800;;;;;; +38;2208;880;;;;;; +38;2224;544;;;;;; +38;2224;624;;;;;; +38;2240;752;;;;;; +38;2240;880;;;;;; +38;2256;544;;;;;; +38;2256;624;;;;;; +38;2272;768;;;;;; +38;2272;880;;;;;; +38;2288;624;;;;;; +38;2304;768;;;;;; +38;2304;880;;;;;; +38;2336;576;;;;;; +38;2336;624;;;;;; +38;2336;752;;;;;; +38;2336;880;;;;;; +38;2368;576;;;;;; +38;2368;624;;;;;; +38;2368;752;;;;;; +38;2368;880;;;;;; +38;2400;576;;;;;; +38;2400;624;;;;;; +38;2400;752;;;;;; +38;2400;880;;;;;; +38;2432;576;;;;;; +38;2432;880;;;;;; +38;2464;656;;;;;; +38;2464;720;;;;;; +38;2464;880;;;;;; +38;2480;672;;;;;; +38;2480;704;;;;;; +38;2480;736;;;;;; +38;2496;656;;;;;; +38;2496;720;;;;;; +38;2496;880;;;;;; +38;2528;880;;;;;; +39;80;1840;;;;;; +39;112;1840;;;;;; +39;160;1840;;;;;; +39;160;1872;;;;;; +39;304;1808;;;;;; +39;336;1808;;;;;; +39;464;1808;;;;;; +39;464;1872;;;;;; +39;624;1808;;;;;; +39;624;1872;;;;;; +39;656;1808;;;;;; +39;656;1872;;;;;; +39;688;1808;;;;;; +39;720;1808;;;;;; +39;848;1952;;;;;; +39;928;1952;;;;;; +40;496;1808;;;;;; +40;496;1872;;;;;; +40;592;1808;;;;;; +40;592;1872;;;;;; +41;976;688;;;;;; +41;1008;672;;;;;; +41;1024;592;;;;;; +41;1040;528;;;;;; +41;1040;688;;;;;; +41;1056;624;;;;;; +41;1072;560;;;;;; +41;1072;656;;;;;; +41;1104;528;;;;;; +41;1120;576;;;;;; +41;1120;624;;;;;; +41;1120;720;;;;;; +41;1120;800;;;;;; +41;1120;832;;;;;; +41;1120;864;;;;;; +41;1120;896;;;;;; +41;1136;528;;;;;; +41;1168;592;;;;;; +41;1168;672;;;;;; +41;1216;544;;;;;; +41;1216;704;;;;;; +42;848;816;;;;;; +42;896;816;;;;;; +45;1648;1088;;;;;; +45;1728;1088;;;;;; +36;16;1008;;;;;; +36;32;1024;;;;;; +36;32;1056;;;;;; +36;48;1008;;;;;; +36;48;1088;;;;;; +36;48;1120;;;;;; +36;64;1072;;;;;; +36;64;1104;;;;;; +36;64;1136;;;;;; +36;80;1088;;;;;; +36;80;1120;;;;;; +36;128;1088;;;;;; +36;128;1120;;;;;; +36;144;944;;;;;; +36;144;976;;;;;; +36;144;1008;;;;;; +36;144;1040;;;;;; +36;144;1072;;;;;; +36;144;1104;;;;;; +36;144;1136;;;;;; +36;160;960;;;;;; +36;160;992;;;;;; +36;160;1024;;;;;; +36;160;1056;;;;;; +36;160;1088;;;;;; +36;160;1120;;;;;; +36;176;480;;;;;; +36;176;944;;;;;; +36;176;976;;;;;; +36;176;1008;;;;;; +36;192;992;;;;;; +36;208;1008;;;;;; +36;224;688;;;;;; +36;224;928;;;;;; +36;240;1008;;;;;; +36;256;928;;;;;; +36;272;960;;;;;; +36;272;1008;;;;;; +36;288;976;;;;;; +36;304;992;;;;;; +36;304;1024;;;;;; +36;320;1008;;;;;; +36;544;816;;;;;; +36;656;736;;;;;; +36;656;768;;;;;; +36;656;800;;;;;; +37;16;976;;;;;; +37;32;464;;;;;; +37;32;496;;;;;; +37;32;528;;;;;; +37;32;736;;;;;; +37;32;768;;;;;; +37;32;800;;;;;; +37;32;848;;;;;; +37;32;880;;;;;; +37;32;912;;;;;; +37;32;944;;;;;; +37;48;480;;;;;; +37;48;784;;;;;; +37;48;816;;;;;; +37;144;480;;;;;; +37;160;496;;;;;; +37;160;832;;;;;; +37;192;496;;;;;; +37;192;832;;;;;; +37;224;496;;;;;; +37;256;496;;;;;; +37;288;496;;;;;; +37;304;608;;;;;; +37;304;768;;;;;; +37;304;800;;;;;; +37;304;896;;;;;; +37;304;928;;;;;; +37;304;960;;;;;; +37;320;496;;;;;; +37;320;624;;;;;; +37;320;656;;;;;; +37;320;688;;;;;; +37;320;720;;;;;; +37;320;752;;;;;; +37;320;784;;;;;; +37;320;880;;;;;; +37;320;912;;;;;; +37;320;944;;;;;; +37;336;992;;;;;; +37;352;496;;;;;; +37;352;1008;;;;;; +37;384;496;;;;;; +37;384;1008;;;;;; +37;400;896;;;;;; +37;416;496;;;;;; +37;416;1008;;;;;; +37;448;496;;;;;; +37;448;624;;;;;; +37;448;1008;;;;;; +37;480;496;;;;;; +37;480;592;;;;;; +37;480;624;;;;;; +37;480;656;;;;;; +37;480;688;;;;;; +37;480;944;;;;;; +37;480;976;;;;;; +37;480;1008;;;;;; +37;512;496;;;;;; +37;512;624;;;;;; +37;512;1008;;;;;; +37;544;496;;;;;; +37;544;624;;;;;; +37;544;1008;;;;;; +37;576;496;;;;;; +37;576;624;;;;;; +37;576;1008;;;;;; +37;608;496;;;;;; +37;608;624;;;;;; +37;608;1008;;;;;; +37;624;512;;;;;; +37;624;544;;;;;; +37;640;528;;;;;; +37;640;624;;;;;; +37;640;656;;;;;; +37;640;688;;;;;; +37;640;720;;;;;; +37;640;752;;;;;; +37;640;784;;;;;; +37;640;816;;;;;; +37;640;848;;;;;; +37;640;880;;;;;; +37;640;912;;;;;; +37;640;944;;;;;; +37;640;976;;;;;; +37;640;1008;;;;;; +246;64;1616; +246;64;1632; +246;80;1200; +246;80;1216; +246;80;1232; +246;80;1248; +246;80;1264; +246;80;1280; +246;80;1296; +246;80;1312; +246;80;1616; +246;80;1632; +246;80;1648; +246;80;1680; +246;80;1696; +246;96;1184; +246;96;1200; +246;96;1216; +246;96;1232; +246;96;1248; +246;96;1264; +246;96;1280; +246;96;1296; +246;96;1312; +246;96;1328; +246;96;1408; +246;96;1424; +246;96;1440; +246;96;1456; +246;96;1472; +246;96;1488; +246;96;1504; +246;96;1520; +246;96;1536; +246;96;1552; +246;96;1568; +246;96;1616; +246;96;1632; +246;96;1680; +246;96;1696; +246;96;1712; +246;96;1744; +246;96;1760; +246;112;1168; +246;112;1184; +246;112;1200; +246;112;1216; +246;112;1232; +246;112;1248; +246;112;1264; +246;112;1280; +246;112;1296; +246;112;1312; +246;112;1408; +246;112;1424; +246;112;1440; +246;112;1456; +246;112;1472; +246;112;1488; +246;112;1504; +246;112;1520; +246;112;1536; +246;112;1552; +246;112;1568; +246;112;1584; +246;112;1680; +246;112;1696; +246;112;1744; +246;112;1760; +246;112;1776; +246;128;1552; +246;128;1568; +246;128;1744; +246;128;1760; +246;224;144; +246;224;160; +246;224;176; +246;224;192; +246;224;1552; +246;224;1584; +246;224;1600; +246;224;1616; +246;224;1632; +246;224;1648; +246;224;1664; +246;224;1680; +246;240;144; +246;240;160; +246;240;176; +246;240;192; +246;240;208; +246;240;1552; +246;240;1568; +246;240;1584; +246;240;1600; +246;240;1616; +246;240;1632; +246;240;1648; +246;240;1664; +246;240;1680; +246;240;1696; +246;240;1728; +246;240;1744; +246;240;1760; +246;256;176; +246;256;192; +246;256;1552; +246;256;1568; +246;256;1584; +246;256;1600; +246;256;1616; +246;256;1632; +246;256;1648; +246;256;1664; +246;256;1680; +246;256;1728; +246;256;1744; +246;256;1760; +246;256;1776; +246;272;1728; +246;272;1744; +246;272;1760; +246;288;224; +246;288;240; +246;304;224; +246;448;1104; +246;448;1120; +246;464;1104; +246;464;1120; +246;464;1136; +246;480;1056; +246;480;1072; +246;480;1088; +246;480;1104; +246;480;1120; +246;528;96; +246;528;1808; +246;528;1824; +246;528;1840; +246;528;1856; +246;528;1872; +246;528;1888; +246;544;96; +246;544;112; +246;544;1840; +246;544;1856; +246;544;1872; +246;544;1888; +246;544;1904; +246;560;64; +246;560;80; +246;560;96; +246;560;1824; +246;560;1840; +246;560;1856; +246;560;1872; +246;560;1888; +246;560;1904; +246;576;1840; +246;576;1856; +246;576;1872; +246;576;1888; +246;576;1904; +246;592;1840; +246;592;1856; +246;592;1872; +246;608;96; +246;608;112; +246;624;96; +246;752;64; +246;752;80; +246;752;96; +246;768;64; +246;768;80; +246;768;96; +246;768;112; +246;784;64; +246;784;80; +246;784;96; +246;864;1344; +246;880;1328; +246;880;1344; +246;880;1360; +246;880;1376; +246;896;1328; +246;896;1344; +246;896;1360; +246;896;1376; +246;912;352; +246;912;368; +246;912;384; +246;912;400; +246;912;416; +246;912;1328; +246;912;1344; +246;912;1360; +246;912;1376; +246;928;352; +246;928;368; +246;928;384; +246;928;400; +246;928;416; +246;928;432; +246;928;1328; +246;928;1344; +246;928;1360; +246;928;1376; +246;944;352; +246;944;368; +246;944;384; +246;944;400; +246;944;416; +246;944;432; +246;944;1328; +246;944;1344; +246;944;1360; +246;944;1376; +246;960;352; +246;960;368; +246;960;384; +246;960;400; +246;960;416; +246;960;432; +246;960;1312; +246;960;1328; +246;960;1344; +246;960;1360; +246;960;1376; +246;976;1312; +246;976;1328; +246;976;1344; +246;976;1360; +246;976;1376; +246;992;1312; +246;992;1328; +246;992;1344; +246;992;1360; +246;992;1376; +246;1008;352; +246;1008;368; +246;1008;384; +246;1008;400; +246;1008;1312; +246;1008;1328; +246;1008;1344; +246;1008;1360; +246;1008;1376; +246;1024;336; +246;1024;352; +246;1024;368; +246;1024;384; +246;1024;400; +246;1040;336; +246;1040;352; +246;1040;368; +246;1040;384; +246;1040;400; +246;1232;32; +246;1232;48; +246;1248;32; +246;1248;48; +246;1248;64; +246;1248;1184; +246;1264;32; +246;1264;48; +246;1264;1168; +246;1264;1184; +246;1264;1200; +246;1280;1168; +246;1280;1184; +246;1280;1200; +246;1296;1168; +246;1296;1184; +246;1296;1200; +246;1312;1168; +246;1312;1184; +246;1328;1168; +246;1328;1184; +246;1456;96; +246;1472;96; +246;1472;112; +246;1488;96; +246;1632;1968; +246;1648;1968; +246;1648;1984; +246;1648;2000; +246;1664;1968; +246;1664;1984; +246;1712;1968; +246;1712;1984; +246;1728;1968; +246;1728;1984; +246;1728;2000; +246;1744;1968; +246;1744;1984; +246;1744;2000; +246;1760;1968; +246;1760;1984; +246;1760;2000; +246;1776;1968; +246;1776;1984; +246;1776;2000; +246;1792;1056; +246;1792;1072; +246;1792;1088; +246;1792;1104; +246;1792;1120; +246;1792;1968; +246;1792;1984; +246;1792;2000; +246;1808;192; +246;1808;208; +246;1808;1088; +246;1808;1104; +246;1808;1120; +246;1808;1136; +246;1808;1376; +246;1808;1392; +246;1808;1968; +246;1808;1984; +246;1808;2000; +246;1824;208; +246;1824;224; +246;1824;1088; +246;1824;1104; +246;1824;1120; +246;1824;1136; +246;1824;1376; +246;1824;1968; +246;1824;1984; +246;1824;2000; +246;1840;208; +246;1840;224; +246;1840;1088; +246;1840;1104; +246;1840;1120; +246;1840;1968; +246;1840;1984; +246;1856;208; +246;1856;224; +246;1856;1968; +246;1872;208; +246;1872;1376; +246;1872;1968; +246;1888;1376; +246;1888;1392; +246;2000;1168; +246;2000;1184; +246;2016;1088; +246;2016;1104; +246;2032;1088; +246;2048;1104; +246;2048;1120; +246;2064;1104; +246;2208;352; +246;2208;368; +246;2208;1872; +246;2208;1888; +246;2208;1904; +246;2208;1920; +246;2224;352; +246;2224;368; +246;2224;1840; +246;2224;1856; +246;2224;1872; +246;2224;1888; +246;2224;1904; +246;2224;1920; +246;2224;1936; +246;2240;352; +246;2240;368; +246;2240;1824; +246;2240;1840; +246;2240;1856; +246;2240;1872; +246;2240;1888; +246;2240;1904; +246;2240;1920; +246;2256;352; +246;2256;368; +246;2272;352; +246;2272;368; +246;2288;336; +246;2288;352; +246;2288;368; +246;2304;336; +246;2304;352; +246;2320;80; +246;2320;96; +246;2336;32; +246;2336;48; +246;2336;64; +246;2336;80; +246;2336;96; +246;2336;112; +246;2352;80; +246;2352;96; +246;2352;336; +246;2352;352; +246;2368;80; +246;2368;96; +246;2368;336; +246;2368;352; +246;2368;368; +246;2384;64; +246;2384;80; +246;2384;96; +246;2384;112; +246;2384;336; +246;2384;368; +246;2400;64; +246;2400;80; +246;2400;96; +246;2400;336; +246;2416;336; +246;2432;336; +246;2448;336; +246;2448;352; +246;2464;336; +246;2464;352; +246;2480;336; +246;2480;352; +247;928;272; +247;928;288; +247;928;304; +247;944;272; +247;944;288; +247;944;304; +247;944;320; +247;960;288; +247;960;304; +247;1040;288; +247;1056;288; +247;1056;304; +247;1072;288; +247;1168;288; +247;1184;272; +247;1184;288; +247;1184;304; +247;1200;272; +247;1200;288; +373;2224;1968;walrus_despawn +374;2215;2008;walrus_despawn +157;16;2000; +157;16;2016; +157;16;2032; +157;32;2032; +157;48;2032; +157;64;2032; +157;80;2000; +157;80;2016; +157;80;2032; +157;96;2000; +157;96;2016; +157;96;2032; +157;112;2000; +157;112;2016; +157;112;2032; +157;128;2000; +157;128;2016; +157;128;2032; +157;144;2000; +157;144;2016; +157;144;2032; +157;160;2000; +157;160;2016; +157;160;2032; +157;176;2000; +157;176;2016; +157;176;2032; +157;192;2000; +157;192;2016; +157;192;2032; +157;208;2000; +157;208;2016; +157;208;2032; +157;224;2000; +157;224;2016; +157;224;2032; +157;240;2000; +157;240;2016; +157;240;2032; +157;256;2000; +157;256;2016; +157;256;2032; +157;272;2000; +157;272;2016; +157;272;2032; +157;288;2000; +157;288;2016; +157;288;2032; +157;304;2000; +157;304;2016; +157;304;2032; +157;368;2000; +157;368;2016; +157;368;2032; +157;384;320; +157;384;336; +157;384;352; +157;384;368; +157;384;384; +157;384;400; +157;384;416; +157;384;2000; +157;384;2016; +157;384;2032; +157;400;288; +157;400;304; +157;400;320; +157;400;336; +157;400;352; +157;400;368; +157;400;384; +157;400;400; +157;400;416; +157;400;2000; +157;400;2016; +157;400;2032; +157;416;336; +157;416;352; +157;416;416; +157;416;432; +157;416;448; +157;416;2000; +157;416;2016; +157;416;2032; +157;432;288; +157;432;304; +157;432;320; +157;432;336; +157;432;352; +157;432;368; +157;432;384; +157;432;400; +157;432;432; +157;432;448; +157;432;2000; +157;432;2016; +157;432;2032; +157;448;288; +157;448;304; +157;448;320; +157;448;352; +157;448;368; +157;448;384; +157;448;400; +157;448;416; +157;448;448; +157;448;464; +157;448;2000; +157;448;2016; +157;448;2032; +157;464;288; +157;464;304; +157;464;320; +157;464;352; +157;464;400; +157;464;416; +157;464;432; +157;464;2000; +157;464;2016; +157;464;2032; +157;480;304; +157;480;336; +157;480;352; +157;480;416; +157;480;432; +157;480;464; +157;480;480; +157;480;2000; +157;480;2016; +157;480;2032; +157;496;304; +157;496;336; +157;496;352; +157;496;416; +157;496;432; +157;496;464; +157;496;480; +157;496;2000; +157;496;2016; +157;496;2032; +157;512;288; +157;512;304; +157;512;336; +157;512;352; +157;512;368; +157;512;384; +157;512;400; +157;512;416; +157;512;432; +157;512;464; +157;512;480; +157;512;2000; +157;512;2016; +157;512;2032; +157;528;288; +157;528;304; +157;528;336; +157;528;352; +157;528;368; +157;528;384; +157;528;400; +157;528;416; +157;528;432; +157;528;464; +157;528;480; +157;528;2000; +157;528;2016; +157;528;2032; +157;544;288; +157;544;304; +157;544;320; +157;544;352; +157;544;368; +157;544;384; +157;544;400; +157;544;416; +157;544;448; +157;544;480; +157;544;2000; +157;544;2016; +157;544;2032; +157;560;288; +157;560;320; +157;560;336; +157;560;352; +157;560;432; +157;560;448; +157;560;464; +157;560;480; +157;560;2000; +157;560;2016; +157;560;2032; +157;576;288; +157;576;304; +157;576;320; +157;576;336; +157;576;352; +157;576;368; +157;576;384; +157;576;400; +157;576;416; +157;576;432; +157;576;448; +157;576;464; +157;576;2000; +157;576;2016; +157;576;2032; +157;592;288; +157;592;304; +157;592;320; +157;592;336; +157;592;448; +157;592;464; +157;592;480; +157;592;2000; +157;592;2016; +157;592;2032; +157;608;304; +157;608;320; +157;608;336; +157;608;352; +157;608;368; +157;608;384; +157;608;400; +157;608;416; +157;608;432; +157;608;464; +157;608;480; +157;608;2000; +157;608;2016; +157;608;2032; +157;624;288; +157;624;304; +157;624;336; +157;624;352; +157;624;368; +157;624;384; +157;624;400; +157;624;416; +157;624;432; +157;624;464; +157;624;480; +157;624;2000; +157;624;2016; +157;624;2032; +157;640;288; +157;640;416; +157;640;432; +157;640;464; +157;640;480; +157;640;2000; +157;640;2016; +157;640;2032; +157;656;288; +157;656;416; +157;656;432; +157;656;464; +157;656;480; +157;656;2000; +157;656;2016; +157;656;2032; +157;672;288; +157;672;304; +157;672;320; +157;672;336; +157;672;352; +157;672;416; +157;672;464; +157;672;480; +157;672;2000; +157;672;2016; +157;672;2032; +157;688;288; +157;688;304; +157;688;320; +157;688;336; +157;688;352; +157;688;432; +157;688;448; +157;688;464; +157;688;2000; +157;688;2016; +157;688;2032; +157;704;288; +157;704;304; +157;704;320; +157;704;336; +157;704;352; +157;704;368; +157;704;384; +157;704;400; +157;704;416; +157;704;2000; +157;704;2016; +157;704;2032; +157;720;288; +157;720;304; +157;720;320; +157;720;336; +157;720;352; +157;720;368; +157;720;384; +157;720;400; +157;720;2000; +157;720;2016; +157;720;2032; +157;736;320; +157;736;336; +157;736;352; +157;736;400; +157;736;2000; +157;736;2016; +157;736;2032; +157;752;2000; +157;752;2016; +157;752;2032; +157;768;1616; +157;768;1632; +157;768;2000; +157;768;2016; +157;768;2032; +157;784;1616; +157;784;1632; +157;784;1680; +157;784;2000; +157;784;2016; +157;784;2032; +157;800;1632; +157;800;2032; +157;816;1632; +157;816;2032; +157;832;1616; +157;832;1632; +157;832;1648; +157;832;1664; +157;832;1680; +157;832;2000; +157;832;2016; +157;832;2032; +157;848;1632; +157;848;1648; +157;848;1664; +157;848;2000; +157;848;2016; +157;848;2032; +157;864;400; +157;864;416; +157;864;592; +157;864;2000; +157;864;2016; +157;864;2032; +157;880;400; +157;880;416; +157;880;592; +157;880;2000; +157;880;2016; +157;880;2032; +157;896;400; +157;896;1440; +157;896;2000; +157;896;2016; +157;896;2032; +157;912;1440; +157;912;2000; +157;912;2016; +157;912;2032; +157;928;1440; +157;928;2000; +157;928;2016; +157;928;2032; +157;944;2000; +157;944;2016; +157;944;2032; +157;960;1424; +157;1344;208; +157;1360;208; +157;1376;208; +157;1392;208; +157;1408;208; +157;1424;208; +157;1440;208; +157;1440;224; +157;1456;208; +157;1456;224; +157;1472;208; +157;1488;208; +157;1504;208; +157;1520;208; +157;1536;208; +157;1552;208; +157;1568;208; +157;1584;192; +157;1584;208; +157;1600;192; +157;1600;208; +157;1616;192; +157;1616;208; +157;1632;192; +157;1632;208; +157;1648;208; +157;1664;208; +157;1680;208; +157;1680;224; +157;1696;208; +157;1696;224; +157;1712;208; +157;1712;224; +157;1728;208; +157;1728;224; +157;1744;208; +157;1744;224; +157;1760;208; +157;1760;224; +157;1776;208; +157;1776;224; +157;1808;304; +157;1824;304; +157;1824;320; +157;1840;320; +157;1856;320; +157;1872;320; +157;1904;144; +157;1920;144; +157;1920;160; +157;1920;208; +157;1936;144; +157;1936;160; +157;1936;176; +157;1936;192; +157;1936;208; +157;1936;224; +157;1952;208; +157;2016;1824; +157;2016;1888; +157;2032;1824; +157;2032;1888; +157;2048;1824; +157;2048;1888; +157;2064;192; +157;2064;1824; +157;2064;1840; +157;2064;1856; +157;2064;1872; +157;2064;1888; +157;2080;176; +157;2080;192; +157;2080;208; +157;2080;1824; +157;2080;1840; +157;2080;1856; +157;2080;1872; +157;2080;1888; +157;2096;176; +157;2096;192; +157;2096;208; +157;2096;1824; +157;2096;1840; +157;2096;1856; +157;2096;1872; +157;2096;1888; +157;2112;176; +157;2112;192; +157;2112;208; +157;2112;1856; +157;2112;1872; +157;2112;1888; +157;2128;1856; +157;2128;1872; +157;2128;1888; +102;208;1056;;;;;; +102;208;1072;;;;;; +102;208;1088;;;;;; +102;224;1056;;;;;; +102;224;1072;;;;;; +102;224;1088;;;;;; +102;240;1088;;;;;; +102;640;1440;;;;;; +102;640;1456;;;;;; +102;640;1472;;;;;; +102;640;1488;;;;;; +102;640;1504;;;;;; +102;688;688;;;;;; +102;688;704;;;;;; +102;704;688;;;;;; +102;704;704;;;;;; +102;704;720;;;;;; +102;720;688;;;;;; +102;720;704;;;;;; +102;720;720;;;;;; +102;992;1920;;;;;; +102;992;1936;;;;;; +102;992;1952;;;;;; +102;992;1968;;;;;; +102;992;1984;;;;;; +102;992;2000;;;;;; +102;992;2016;;;;;; +102;992;2032;;;;;; +102;1008;1472;;;;;; +102;1008;1488;;;;;; +102;1008;1504;;;;;; +102;1008;1936;;;;;; +102;1008;1952;;;;;; +102;1008;1968;;;;;; +102;1008;1984;;;;;; +102;1008;2000;;;;;; +102;1008;2016;;;;;; +102;1008;2032;;;;;; +102;1024;1472;;;;;; +102;1024;2016;;;;;; +102;1024;2032;;;;;; +102;1040;1312;;;;;; +102;1040;1328;;;;;; +102;1040;1344;;;;;; +102;1040;1360;;;;;; +102;1040;1376;;;;;; +102;1040;1392;;;;;; +102;1040;1408;;;;;; +102;1040;1424;;;;;; +102;1040;1440;;;;;; +102;1040;1456;;;;;; +102;1040;1472;;;;;; +102;1040;2032;;;;;; +102;1056;1312;;;;;; +102;1056;1392;;;;;; +102;1056;1408;;;;;; +102;1056;1456;;;;;; +102;1056;1472;;;;;; +102;1056;1488;;;;;; +102;1056;1504;;;;;; +102;1056;2032;;;;;; +102;1072;1312;;;;;; +102;1072;1392;;;;;; +102;1072;1408;;;;;; +102;1072;1456;;;;;; +102;1072;1504;;;;;; +102;1088;1312;;;;;; +102;1088;1392;;;;;; +102;1088;1408;;;;;; +102;1088;1424;;;;;; +102;1088;1440;;;;;; +102;1088;1456;;;;;; +102;1088;1504;;;;;; +102;1104;1312;;;;;; +102;1104;1328;;;;;; +102;1104;1344;;;;;; +102;1104;1360;;;;;; +102;1104;1376;;;;;; +102;1104;1392;;;;;; +102;1104;1408;;;;;; +102;1104;1456;;;;;; +102;1104;1472;;;;;; +102;1104;1488;;;;;; +102;1104;1504;;;;;; +102;1120;1312;;;;;; +102;1120;1328;;;;;; +102;1120;1344;;;;;; +102;1120;1360;;;;;; +102;1120;1376;;;;;; +102;1120;1392;;;;;; +102;1120;1408;;;;;; +102;1120;1456;;;;;; +102;1120;1472;;;;;; +102;1120;1488;;;;;; +102;1120;1504;;;;;; +102;1136;1312;;;;;; +102;1136;1328;;;;;; +102;1136;1344;;;;;; +102;1136;1360;;;;;; +102;1136;1376;;;;;; +102;1136;1392;;;;;; +102;1136;1408;;;;;; +102;1136;1456;;;;;; +102;1136;1472;;;;;; +102;1136;1488;;;;;; +102;1136;1504;;;;;; +102;1152;1312;;;;;; +102;1152;1328;;;;;; +102;1152;1344;;;;;; +102;1152;1360;;;;;; +102;1152;1376;;;;;; +102;1152;1392;;;;;; +102;1152;1408;;;;;; +102;1152;1456;;;;;; +102;1152;1472;;;;;; +102;1152;1488;;;;;; +102;1152;1504;;;;;; +102;1168;1312;;;;;; +102;1168;1328;;;;;; +102;1168;1344;;;;;; +102;1168;1360;;;;;; +102;1168;1376;;;;;; +102;1168;1392;;;;;; +102;1168;1408;;;;;; +102;1168;1424;;;;;; +102;1168;1440;;;;;; +102;1168;1456;;;;;; +102;1168;1472;;;;;; +102;1168;1488;;;;;; +102;1168;1504;;;;;; +102;1184;1456;;;;;; +102;1184;1472;;;;;; +102;1280;1984;;;;;; +102;1280;2000;;;;;; +102;1280;2016;;;;;; +102;1280;2032;;;;;; +102;1296;2032;;;;;; +102;1312;560;;;;;; +102;1312;576;;;;;; +102;1312;592;;;;;; +102;1312;608;;;;;; +102;1312;624;;;;;; +102;1312;640;;;;;; +102;1312;656;;;;;; +102;1312;672;;;;;; +102;1312;688;;;;;; +102;1312;704;;;;;; +102;1312;720;;;;;; +102;1312;736;;;;;; +102;1312;752;;;;;; +102;1312;768;;;;;; +102;1312;784;;;;;; +102;1312;800;;;;;; +102;1312;816;;;;;; +102;1312;832;;;;;; +102;1312;848;;;;;; +102;1312;864;;;;;; +102;1312;880;;;;;; +102;1312;896;;;;;; +102;1312;912;;;;;; +102;1312;928;;;;;; +102;1312;944;;;;;; +102;1312;960;;;;;; +102;1312;1952;;;;;; +102;1312;1968;;;;;; +102;1312;1984;;;;;; +102;1312;2000;;;;;; +102;1312;2016;;;;;; +102;1328;560;;;;;; +102;1328;736;;;;;; +102;1328;752;;;;;; +102;1328;768;;;;;; +102;1328;784;;;;;; +102;1328;800;;;;;; +102;1328;816;;;;;; +102;1328;832;;;;;; +102;1328;848;;;;;; +102;1328;944;;;;;; +102;1328;960;;;;;; +102;1328;1952;;;;;; +102;1328;2016;;;;;; +102;1344;528;;;;;; +102;1344;544;;;;;; +102;1344;560;;;;;; +102;1344;944;;;;;; +102;1344;960;;;;;; +102;1344;1952;;;;;; +102;1344;2016;;;;;; +102;1360;464;;;;;; +102;1360;480;;;;;; +102;1360;496;;;;;; +102;1360;512;;;;;; +102;1360;528;;;;;; +102;1360;544;;;;;; +102;1360;560;;;;;; +102;1360;928;;;;;; +102;1360;944;;;;;; +102;1360;960;;;;;; +102;1360;1760;;;;;; +102;1360;1776;;;;;; +102;1360;1792;;;;;; +102;1360;1808;;;;;; +102;1360;1952;;;;;; +102;1360;2032;;;;;; +102;1376;288;;;;;; +102;1376;304;;;;;; +102;1376;416;;;;;; +102;1376;432;;;;;; +102;1376;448;;;;;; +102;1376;464;;;;;; +102;1376;480;;;;;; +102;1376;928;;;;;; +102;1376;944;;;;;; +102;1376;960;;;;;; +102;1376;1760;;;;;; +102;1376;1776;;;;;; +102;1376;1792;;;;;; +102;1376;1808;;;;;; +102;1376;2016;;;;;; +102;1376;2032;;;;;; +102;1392;288;;;;;; +102;1392;304;;;;;; +102;1392;464;;;;;; +102;1392;480;;;;;; +102;1392;928;;;;;; +102;1392;944;;;;;; +102;1392;960;;;;;; +102;1392;1760;;;;;; +102;1392;1776;;;;;; +102;1392;1792;;;;;; +102;1392;1808;;;;;; +102;1392;1968;;;;;; +102;1392;1984;;;;;; +102;1392;2000;;;;;; +102;1392;2016;;;;;; +102;1392;2032;;;;;; +102;1408;288;;;;;; +102;1408;304;;;;;; +102;1408;480;;;;;; +102;1408;928;;;;;; +102;1408;944;;;;;; +102;1408;960;;;;;; +102;1408;1760;;;;;; +102;1408;1776;;;;;; +102;1408;1792;;;;;; +102;1408;1808;;;;;; +102;1424;304;;;;;; +102;1424;480;;;;;; +102;1424;928;;;;;; +102;1424;944;;;;;; +102;1424;960;;;;;; +102;1424;1680;;;;;; +102;1424;1696;;;;;; +102;1424;1712;;;;;; +102;1424;1728;;;;;; +102;1424;1744;;;;;; +102;1424;1760;;;;;; +102;1424;1776;;;;;; +102;1424;1792;;;;;; +102;1424;1808;;;;;; +102;1424;1824;;;;;; +102;1424;1840;;;;;; +102;1424;1856;;;;;; +102;1440;304;;;;;; +102;1440;480;;;;;; +102;1440;928;;;;;; +102;1440;944;;;;;; +102;1440;960;;;;;; +102;1440;1600;;;;;; +102;1440;1616;;;;;; +102;1440;1632;;;;;; +102;1440;1648;;;;;; +102;1440;1664;;;;;; +102;1440;1680;;;;;; +102;1440;1696;;;;;; +102;1440;1712;;;;;; +102;1440;1728;;;;;; +102;1440;1744;;;;;; +102;1440;1760;;;;;; +102;1440;1776;;;;;; +102;1440;1792;;;;;; +102;1440;1808;;;;;; +102;1440;1824;;;;;; +102;1440;1840;;;;;; +102;1440;1856;;;;;; +102;1456;304;;;;;; +102;1456;480;;;;;; +102;1456;928;;;;;; +102;1456;944;;;;;; +102;1456;960;;;;;; +102;1456;1600;;;;;; +102;1456;1616;;;;;; +102;1456;1632;;;;;; +102;1456;1648;;;;;; +102;1456;1664;;;;;; +102;1456;1680;;;;;; +102;1456;1696;;;;;; +102;1456;1712;;;;;; +102;1456;1728;;;;;; +102;1456;1744;;;;;; +102;1456;1760;;;;;; +102;1456;1776;;;;;; +102;1456;1792;;;;;; +102;1456;1808;;;;;; +102;1456;1824;;;;;; +102;1456;1840;;;;;; +102;1456;1856;;;;;; +102;1472;304;;;;;; +102;1472;480;;;;;; +102;1472;928;;;;;; +102;1472;944;;;;;; +102;1472;960;;;;;; +102;1472;1600;;;;;; +102;1472;1616;;;;;; +102;1472;1632;;;;;; +102;1472;1648;;;;;; +102;1472;1664;;;;;; +102;1472;1680;;;;;; +102;1472;1696;;;;;; +102;1472;1712;;;;;; +102;1472;1744;;;;;; +102;1472;1776;;;;;; +102;1472;1792;;;;;; +102;1472;1808;;;;;; +102;1472;1824;;;;;; +102;1472;1840;;;;;; +102;1472;1856;;;;;; +102;1488;288;;;;;; +102;1488;304;;;;;; +102;1488;480;;;;;; +102;1488;944;;;;;; +102;1488;960;;;;;; +102;1488;1600;;;;;; +102;1488;1616;;;;;; +102;1488;1648;;;;;; +102;1488;1664;;;;;; +102;1488;1680;;;;;; +102;1488;1744;;;;;; +102;1488;1776;;;;;; +102;1488;1792;;;;;; +102;1488;1808;;;;;; +102;1488;1824;;;;;; +102;1488;1840;;;;;; +102;1504;288;;;;;; +102;1504;304;;;;;; +102;1504;320;;;;;; +102;1504;480;;;;;; +102;1504;1600;;;;;; +102;1504;1616;;;;;; +102;1504;1632;;;;;; +102;1504;1648;;;;;; +102;1504;1664;;;;;; +102;1504;1696;;;;;; +102;1504;1712;;;;;; +102;1504;1728;;;;;; +102;1504;1776;;;;;; +102;1504;1792;;;;;; +102;1504;1808;;;;;; +102;1504;1840;;;;;; +102;1504;1856;;;;;; +102;1520;288;;;;;; +102;1520;304;;;;;; +102;1520;480;;;;;; +102;1520;1568;;;;;; +102;1520;1584;;;;;; +102;1520;1600;;;;;; +102;1520;1616;;;;;; +102;1520;1632;;;;;; +102;1520;1648;;;;;; +102;1520;1664;;;;;; +102;1520;1696;;;;;; +102;1520;1712;;;;;; +102;1520;1728;;;;;; +102;1520;1744;;;;;; +102;1520;1776;;;;;; +102;1520;1792;;;;;; +102;1520;1856;;;;;; +102;1520;1872;;;;;; +102;1520;1888;;;;;; +102;1520;1904;;;;;; +102;1520;1920;;;;;; +102;1536;288;;;;;; +102;1536;304;;;;;; +102;1536;480;;;;;; +102;1536;1568;;;;;; +102;1536;1584;;;;;; +102;1536;1600;;;;;; +102;1536;1616;;;;;; +102;1536;1648;;;;;; +102;1536;1664;;;;;; +102;1536;1696;;;;;; +102;1536;1712;;;;;; +102;1536;1728;;;;;; +102;1536;1744;;;;;; +102;1536;1776;;;;;; +102;1536;1792;;;;;; +102;1536;1888;;;;;; +102;1536;1904;;;;;; +102;1536;1920;;;;;; +102;1552;288;;;;;; +102;1552;304;;;;;; +102;1552;480;;;;;; +102;1552;1568;;;;;; +102;1552;1584;;;;;; +102;1552;1600;;;;;; +102;1552;1616;;;;;; +102;1552;1632;;;;;; +102;1552;1648;;;;;; +102;1552;1664;;;;;; +102;1552;1696;;;;;; +102;1552;1712;;;;;; +102;1552;1728;;;;;; +102;1552;1744;;;;;; +102;1552;1776;;;;;; +102;1552;1792;;;;;; +102;1552;1888;;;;;; +102;1552;1904;;;;;; +102;1552;1920;;;;;; +102;1568;288;;;;;; +102;1568;304;;;;;; +102;1568;480;;;;;; +102;1568;1504;;;;;; +102;1568;1520;;;;;; +102;1568;1536;;;;;; +102;1568;1568;;;;;; +102;1568;1584;;;;;; +102;1568;1600;;;;;; +102;1568;1616;;;;;; +102;1568;1632;;;;;; +102;1568;1648;;;;;; +102;1568;1664;;;;;; +102;1568;1696;;;;;; +102;1568;1712;;;;;; +102;1568;1728;;;;;; +102;1568;1776;;;;;; +102;1568;1792;;;;;; +102;1584;288;;;;;; +102;1584;304;;;;;; +102;1584;480;;;;;; +102;1584;944;;;;;; +102;1584;960;;;;;; +102;1584;1504;;;;;; +102;1584;1520;;;;;; +102;1584;1536;;;;;; +102;1584;1552;;;;;; +102;1584;1568;;;;;; +102;1584;1584;;;;;; +102;1584;1600;;;;;; +102;1584;1616;;;;;; +102;1584;1632;;;;;; +102;1584;1648;;;;;; +102;1584;1664;;;;;; +102;1584;1680;;;;;; +102;1584;1760;;;;;; +102;1584;1776;;;;;; +102;1584;1792;;;;;; +102;1600;288;;;;;; +102;1600;304;;;;;; +102;1600;480;;;;;; +102;1600;928;;;;;; +102;1600;944;;;;;; +102;1600;960;;;;;; +102;1600;1504;;;;;; +102;1600;1520;;;;;; +102;1600;1536;;;;;; +102;1600;1552;;;;;; +102;1600;1568;;;;;; +102;1600;1584;;;;;; +102;1600;1600;;;;;; +102;1600;1616;;;;;; +102;1600;1632;;;;;; +102;1600;1648;;;;;; +102;1600;1664;;;;;; +102;1600;1680;;;;;; +102;1600;1696;;;;;; +102;1600;1712;;;;;; +102;1600;1728;;;;;; +102;1600;1744;;;;;; +102;1600;1760;;;;;; +102;1600;1776;;;;;; +102;1600;1792;;;;;; +102;1600;2032;;;;;; +102;1616;288;;;;;; +102;1616;304;;;;;; +102;1616;480;;;;;; +102;1616;928;;;;;; +102;1616;944;;;;;; +102;1616;960;;;;;; +102;1616;1504;;;;;; +102;1616;1520;;;;;; +102;1616;1536;;;;;; +102;1616;1552;;;;;; +102;1616;1568;;;;;; +102;1616;1584;;;;;; +102;1616;1600;;;;;; +102;1616;1616;;;;;; +102;1616;1632;;;;;; +102;1616;1648;;;;;; +102;1616;1664;;;;;; +102;1616;1680;;;;;; +102;1616;1696;;;;;; +102;1616;1712;;;;;; +102;1616;1728;;;;;; +102;1616;1744;;;;;; +102;1616;1760;;;;;; +102;1616;1776;;;;;; +102;1616;1792;;;;;; +102;1616;2000;;;;;; +102;1616;2016;;;;;; +102;1616;2032;;;;;; +102;1632;288;;;;;; +102;1632;304;;;;;; +102;1632;480;;;;;; +102;1632;928;;;;;; +102;1632;944;;;;;; +102;1632;960;;;;;; +102;1632;1504;;;;;; +102;1632;1520;;;;;; +102;1632;1536;;;;;; +102;1632;1552;;;;;; +102;1632;1568;;;;;; +102;1632;1584;;;;;; +102;1632;1600;;;;;; +102;1632;1616;;;;;; +102;1632;1632;;;;;; +102;1632;1648;;;;;; +102;1632;1664;;;;;; +102;1632;1680;;;;;; +102;1632;1696;;;;;; +102;1632;1712;;;;;; +102;1632;1728;;;;;; +102;1632;1744;;;;;; +102;1632;1760;;;;;; +102;1632;1776;;;;;; +102;1632;1792;;;;;; +102;1632;2032;;;;;; +102;1648;288;;;;;; +102;1648;304;;;;;; +102;1648;320;;;;;; +102;1648;480;;;;;; +102;1648;928;;;;;; +102;1648;944;;;;;; +102;1648;960;;;;;; +102;1648;1504;;;;;; +102;1648;1520;;;;;; +102;1648;1536;;;;;; +102;1648;1552;;;;;; +102;1648;1568;;;;;; +102;1648;1584;;;;;; +102;1648;1600;;;;;; +102;1648;1616;;;;;; +102;1648;1632;;;;;; +102;1648;1648;;;;;; +102;1648;1664;;;;;; +102;1648;1680;;;;;; +102;1648;1760;;;;;; +102;1648;1776;;;;;; +102;1648;1792;;;;;; +102;1648;2032;;;;;; +102;1664;304;;;;;; +102;1664;320;;;;;; +102;1664;480;;;;;; +102;1664;928;;;;;; +102;1664;944;;;;;; +102;1664;960;;;;;; +102;1664;1488;;;;;; +102;1664;1504;;;;;; +102;1664;1520;;;;;; +102;1664;1536;;;;;; +102;1664;1552;;;;;; +102;1664;1568;;;;;; +102;1664;1584;;;;;; +102;1664;1600;;;;;; +102;1664;1616;;;;;; +102;1664;1632;;;;;; +102;1664;1648;;;;;; +102;1664;1664;;;;;; +102;1664;1680;;;;;; +102;1664;1824;;;;;; +102;1680;304;;;;;; +102;1680;320;;;;;; +102;1680;480;;;;;; +102;1680;928;;;;;; +102;1680;944;;;;;; +102;1680;960;;;;;; +102;1680;1456;;;;;; +102;1680;1472;;;;;; +102;1680;1488;;;;;; +102;1680;1504;;;;;; +102;1680;1520;;;;;; +102;1680;1536;;;;;; +102;1680;1552;;;;;; +102;1680;1568;;;;;; +102;1680;1584;;;;;; +102;1680;1600;;;;;; +102;1680;1616;;;;;; +102;1680;1632;;;;;; +102;1680;1648;;;;;; +102;1680;1664;;;;;; +102;1680;1680;;;;;; +102;1680;1952;;;;;; +102;1680;1968;;;;;; +102;1680;1984;;;;;; +102;1680;2000;;;;;; +102;1680;2016;;;;;; +102;1696;304;;;;;; +102;1696;320;;;;;; +102;1696;480;;;;;; +102;1696;928;;;;;; +102;1696;944;;;;;; +102;1696;960;;;;;; +102;1696;1456;;;;;; +102;1696;1520;;;;;; +102;1696;1536;;;;;; +102;1696;1552;;;;;; +102;1696;1568;;;;;; +102;1696;1584;;;;;; +102;1696;1600;;;;;; +102;1696;1616;;;;;; +102;1696;1632;;;;;; +102;1696;1648;;;;;; +102;1696;1664;;;;;; +102;1696;1680;;;;;; +102;1696;1952;;;;;; +102;1696;1968;;;;;; +102;1696;1984;;;;;; +102;1696;2000;;;;;; +102;1696;2032;;;;;; +102;1712;304;;;;;; +102;1712;320;;;;;; +102;1712;448;;;;;; +102;1712;464;;;;;; +102;1712;480;;;;;; +102;1712;928;;;;;; +102;1712;944;;;;;; +102;1712;960;;;;;; +102;1712;1456;;;;;; +102;1712;1520;;;;;; +102;1712;1536;;;;;; +102;1712;1552;;;;;; +102;1712;1568;;;;;; +102;1712;1584;;;;;; +102;1712;1600;;;;;; +102;1712;1616;;;;;; +102;1712;1632;;;;;; +102;1712;1648;;;;;; +102;1712;1664;;;;;; +102;1712;1680;;;;;; +102;1712;1696;;;;;; +102;1712;1824;;;;;; +102;1712;2032;;;;;; +102;1728;304;;;;;; +102;1728;320;;;;;; +102;1728;448;;;;;; +102;1728;464;;;;;; +102;1728;480;;;;;; +102;1728;944;;;;;; +102;1728;960;;;;;; +102;1728;1456;;;;;; +102;1728;1696;;;;;; +102;1728;1824;;;;;; +102;1728;1840;;;;;; +102;1728;2032;;;;;; +102;1744;304;;;;;; +102;1744;320;;;;;; +102;1744;448;;;;;; +102;1744;848;;;;;; +102;1744;944;;;;;; +102;1744;960;;;;;; +102;1744;1456;;;;;; +102;1744;1696;;;;;; +102;1744;1712;;;;;; +102;1744;1728;;;;;; +102;1744;1744;;;;;; +102;1744;1760;;;;;; +102;1744;1776;;;;;; +102;1744;1792;;;;;; +102;1744;1808;;;;;; +102;1744;1824;;;;;; +102;1744;2032;;;;;; +102;1760;304;;;;;; +102;1760;320;;;;;; +102;1760;448;;;;;; +102;1760;848;;;;;; +102;1760;864;;;;;; +102;1760;880;;;;;; +102;1760;896;;;;;; +102;1760;912;;;;;; +102;1760;928;;;;;; +102;1760;944;;;;;; +102;1760;960;;;;;; +102;1760;1456;;;;;; +102;1760;1696;;;;;; +102;1760;1712;;;;;; +102;1760;1728;;;;;; +102;1760;1744;;;;;; +102;1760;1760;;;;;; +102;1760;1776;;;;;; +102;1760;1792;;;;;; +102;1760;1808;;;;;; +102;1760;1824;;;;;; +102;1760;2032;;;;;; +102;1776;304;;;;;; +102;1776;320;;;;;; +102;1776;448;;;;;; +102;1776;848;;;;;; +102;1776;864;;;;;; +102;1776;880;;;;;; +102;1776;896;;;;;; +102;1776;912;;;;;; +102;1776;928;;;;;; +102;1776;944;;;;;; +102;1776;960;;;;;; +102;1776;1456;;;;;; +102;1776;1696;;;;;; +102;1776;1712;;;;;; +102;1776;1728;;;;;; +102;1776;1744;;;;;; +102;1776;1760;;;;;; +102;1776;1776;;;;;; +102;1776;1792;;;;;; +102;1776;1808;;;;;; +102;1776;1824;;;;;; +102;1776;2032;;;;;; +102;1792;304;;;;;; +102;1792;320;;;;;; +102;1792;448;;;;;; +102;1792;928;;;;;; +102;1792;944;;;;;; +102;1792;960;;;;;; +102;1792;1456;;;;;; +102;1792;2032;;;;;; +102;1808;320;;;;;; +102;1808;448;;;;;; +102;1808;928;;;;;; +102;1808;1456;;;;;; +102;1808;2032;;;;;; +102;1824;448;;;;;; +102;1824;928;;;;;; +102;1824;1232;;;;;; +102;1824;1248;;;;;; +102;1824;1264;;;;;; +102;1824;1280;;;;;; +102;1824;1296;;;;;; +102;1824;1312;;;;;; +102;1824;1456;;;;;; +102;1824;2032;;;;;; +102;1840;448;;;;;; +102;1840;464;;;;;; +102;1840;480;;;;;; +102;1840;928;;;;;; +102;1840;1200;;;;;; +102;1840;1216;;;;;; +102;1840;1232;;;;;; +102;1840;1248;;;;;; +102;1840;1264;;;;;; +102;1840;1280;;;;;; +102;1840;1296;;;;;; +102;1840;1312;;;;;; +102;1840;1328;;;;;; +102;1840;1344;;;;;; +102;1840;1360;;;;;; +102;1840;1376;;;;;; +102;1840;1392;;;;;; +102;1840;1408;;;;;; +102;1840;1424;;;;;; +102;1840;1440;;;;;; +102;1840;1456;;;;;; +102;1840;2032;;;;;; +102;1856;448;;;;;; +102;1856;464;;;;;; +102;1856;480;;;;;; +102;1856;688;;;;;; +102;1856;704;;;;;; +102;1856;720;;;;;; +102;1856;928;;;;;; +102;1856;1200;;;;;; +102;1856;1216;;;;;; +102;1856;1328;;;;;; +102;1856;1344;;;;;; +102;1856;1360;;;;;; +102;1856;1376;;;;;; +102;1856;1392;;;;;; +102;1856;1408;;;;;; +102;1856;1424;;;;;; +102;1856;1440;;;;;; +102;1856;2016;;;;;; +102;1856;2032;;;;;; +102;1872;464;;;;;; +102;1872;480;;;;;; +102;1872;688;;;;;; +102;1872;704;;;;;; +102;1872;720;;;;;; +102;1872;928;;;;;; +102;1872;1200;;;;;; +102;1872;1216;;;;;; +102;1872;2000;;;;;; +102;1872;2016;;;;;; +102;1872;2032;;;;;; +102;1888;304;;;;;; +102;1888;320;;;;;; +102;1888;464;;;;;; +102;1888;480;;;;;; +102;1888;496;;;;;; +102;1888;512;;;;;; +102;1888;528;;;;;; +102;1888;544;;;;;; +102;1888;560;;;;;; +102;1888;576;;;;;; +102;1888;592;;;;;; +102;1888;608;;;;;; +102;1888;624;;;;;; +102;1888;640;;;;;; +102;1888;656;;;;;; +102;1888;672;;;;;; +102;1888;688;;;;;; +102;1888;704;;;;;; +102;1888;720;;;;;; +102;1888;736;;;;;; +102;1888;752;;;;;; +102;1888;768;;;;;; +102;1888;784;;;;;; +102;1888;928;;;;;; +102;1888;944;;;;;; +102;1888;960;;;;;; +102;1888;1200;;;;;; +102;1888;1216;;;;;; +102;1888;2016;;;;;; +102;1888;2032;;;;;; +102;1904;304;;;;;; +102;1904;320;;;;;; +102;1904;528;;;;;; +102;1904;544;;;;;; +102;1904;560;;;;;; +102;1904;576;;;;;; +102;1904;592;;;;;; +102;1904;608;;;;;; +102;1904;624;;;;;; +102;1904;640;;;;;; +102;1904;656;;;;;; +102;1904;672;;;;;; +102;1904;688;;;;;; +102;1904;704;;;;;; +102;1904;720;;;;;; +102;1904;736;;;;;; +102;1904;752;;;;;; +102;1904;768;;;;;; +102;1904;784;;;;;; +102;1904;800;;;;;; +102;1904;816;;;;;; +102;1904;832;;;;;; +102;1904;848;;;;;; +102;1904;864;;;;;; +102;1904;880;;;;;; +102;1904;896;;;;;; +102;1904;912;;;;;; +102;1904;928;;;;;; +102;1904;944;;;;;; +102;1904;960;;;;;; +102;1904;976;;;;;; +102;1904;992;;;;;; +102;1904;1008;;;;;; +102;1904;1024;;;;;; +102;1904;1040;;;;;; +102;1904;1056;;;;;; +102;1904;1072;;;;;; +102;1904;1088;;;;;; +102;1904;1104;;;;;; +102;1904;1120;;;;;; +102;1904;1136;;;;;; +102;1904;1152;;;;;; +102;1904;1168;;;;;; +102;1904;1184;;;;;; +102;1904;1200;;;;;; +102;1904;1216;;;;;; +102;1904;1920;;;;;; +102;1904;1936;;;;;; +102;1904;1952;;;;;; +102;1904;1968;;;;;; +102;1904;2000;;;;;; +102;1904;2016;;;;;; +102;1904;2032;;;;;; +102;1920;304;;;;;; +102;1920;320;;;;;; +102;1920;1216;;;;;; +102;1920;1776;;;;;; +102;1920;1792;;;;;; +102;1920;1808;;;;;; +102;1920;1824;;;;;; +102;1920;1840;;;;;; +102;1920;1856;;;;;; +102;1920;1872;;;;;; +102;1920;1888;;;;;; +102;1920;1904;;;;;; +102;1920;1920;;;;;; +102;1920;1936;;;;;; +102;1920;2000;;;;;; +102;1920;2016;;;;;; +102;1920;2032;;;;;; +102;1936;304;;;;;; +102;1936;320;;;;;; +102;1936;1216;;;;;; +102;1936;1776;;;;;; +102;1936;1792;;;;;; +102;1936;1808;;;;;; +102;1936;1824;;;;;; +102;1936;1840;;;;;; +102;1936;1856;;;;;; +102;1936;1872;;;;;; +102;1936;1888;;;;;; +102;1936;1904;;;;;; +102;1936;1920;;;;;; +102;1936;1936;;;;;; +102;1936;2016;;;;;; +102;1936;2032;;;;;; +102;1952;304;;;;;; +102;1952;320;;;;;; +102;1952;1184;;;;;; +102;1952;1200;;;;;; +102;1952;1216;;;;;; +102;1952;1776;;;;;; +102;1952;1792;;;;;; +102;1952;1808;;;;;; +102;1952;1824;;;;;; +102;1952;2032;;;;;; +102;1968;208;;;;;; +102;1968;288;;;;;; +102;1968;304;;;;;; +102;1968;320;;;;;; +102;1968;464;;;;;; +102;1968;1216;;;;;; +102;1984;208;;;;;; +102;1984;288;;;;;; +102;1984;304;;;;;; +102;1984;464;;;;;; +102;1984;1216;;;;;; +102;2000;208;;;;;; +102;2000;288;;;;;; +102;2000;304;;;;;; +102;2000;464;;;;;; +102;2000;1216;;;;;; +102;2016;192;;;;;; +102;2016;208;;;;;; +102;2016;288;;;;;; +102;2016;464;;;;;; +102;2016;1216;;;;;; +102;2032;192;;;;;; +102;2032;208;;;;;; +102;2032;288;;;;;; +102;2032;464;;;;;; +102;2032;1216;;;;;; +102;2048;192;;;;;; +102;2048;208;;;;;; +102;2048;288;;;;;; +102;2048;464;;;;;; +102;2048;480;;;;;; +102;2048;1216;;;;;; +102;2064;208;;;;;; +102;2064;288;;;;;; +102;2064;304;;;;;; +102;2064;464;;;;;; +102;2064;480;;;;;; +102;2064;1216;;;;;; +102;2080;288;;;;;; +102;2080;464;;;;;; +102;2080;480;;;;;; +102;2080;1072;;;;;; +102;2080;1088;;;;;; +102;2080;1104;;;;;; +102;2080;1120;;;;;; +102;2080;1136;;;;;; +102;2080;1152;;;;;; +102;2080;1168;;;;;; +102;2080;1184;;;;;; +102;2080;1200;;;;;; +102;2080;1216;;;;;; +102;2096;288;;;;;; +102;2096;464;;;;;; +102;2096;480;;;;;; +102;2096;1072;;;;;; +102;2096;1088;;;;;; +102;2096;1104;;;;;; +102;2096;1120;;;;;; +102;2096;1136;;;;;; +102;2096;1152;;;;;; +102;2096;1168;;;;;; +102;2096;1184;;;;;; +102;2096;1200;;;;;; +102;2096;1216;;;;;; +102;2112;288;;;;;; +102;2112;464;;;;;; +102;2112;1072;;;;;; +102;2112;1088;;;;;; +102;2112;1104;;;;;; +102;2112;1120;;;;;; +102;2112;1136;;;;;; +102;2112;1152;;;;;; +102;2112;1216;;;;;; +102;2128;288;;;;;; +102;2128;304;;;;;; +102;2128;464;;;;;; +102;2128;1136;;;;;; +102;2128;1152;;;;;; +102;2128;1216;;;;;; +102;2144;288;;;;;; +102;2144;304;;;;;; +102;2144;464;;;;;; +102;2144;1136;;;;;; +102;2144;1152;;;;;; +102;2144;1216;;;;;; +102;2160;288;;;;;; +102;2160;464;;;;;; +102;2160;1136;;;;;; +102;2160;1152;;;;;; +102;2160;1216;;;;;; +102;2176;288;;;;;; +102;2176;464;;;;;; +102;2176;1136;;;;;; +102;2176;1152;;;;;; +102;2176;1216;;;;;; +102;2176;2032;;;;;; +102;2192;288;;;;;; +102;2192;464;;;;;; +102;2192;1072;;;;;; +102;2192;1136;;;;;; +102;2192;1152;;;;;; +102;2192;1216;;;;;; +102;2192;2016;;;;;; +102;2192;2032;;;;;; +102;2208;288;;;;;; +102;2208;304;;;;;; +102;2208;464;;;;;; +102;2208;1072;;;;;; +102;2208;1136;;;;;; +102;2208;1152;;;;;; +102;2208;1168;;;;;; +102;2208;1184;;;;;; +102;2208;1200;;;;;; +102;2208;1216;;;;;; +102;2208;2016;;;;;; +102;2208;2032;;;;;; +102;2224;288;;;;;; +102;2224;464;;;;;; +102;2224;1072;;;;;; +102;2224;2016;;;;;; +102;2224;2032;;;;;; +102;2240;288;;;;;; +102;2240;464;;;;;; +102;2240;1072;;;;;; +102;2240;2016;;;;;; +102;2240;2032;;;;;; +102;2256;288;;;;;; +102;2256;464;;;;;; +102;2256;1072;;;;;; +102;2256;2016;;;;;; +102;2256;2032;;;;;; +102;2272;288;;;;;; +102;2272;464;;;;;; +102;2272;1072;;;;;; +102;2272;2016;;;;;; +102;2272;2032;;;;;; +102;2288;288;;;;;; +102;2288;432;;;;;; +102;2288;464;;;;;; +102;2288;1072;;;;;; +102;2288;2016;;;;;; +102;2288;2032;;;;;; +102;2304;288;;;;;; +102;2304;432;;;;;; +102;2304;464;;;;;; +102;2304;1072;;;;;; +102;2304;1088;;;;;; +102;2304;2016;;;;;; +102;2304;2032;;;;;; +102;2320;288;;;;;; +102;2320;304;;;;;; +102;2320;320;;;;;; +102;2320;336;;;;;; +102;2320;352;;;;;; +102;2320;368;;;;;; +102;2320;384;;;;;; +102;2320;400;;;;;; +102;2320;416;;;;;; +102;2320;432;;;;;; +102;2320;464;;;;;; +102;2320;1088;;;;;; +102;2320;2016;;;;;; +102;2320;2032;;;;;; +102;2336;288;;;;;; +102;2336;304;;;;;; +102;2336;320;;;;;; +102;2336;336;;;;;; +102;2336;352;;;;;; +102;2336;464;;;;;; +102;2336;1088;;;;;; +102;2336;2016;;;;;; +102;2336;2032;;;;;; +102;2352;288;;;;;; +102;2352;464;;;;;; +102;2352;1088;;;;;; +102;2352;2016;;;;;; +102;2352;2032;;;;;; +102;2368;288;;;;;; +102;2368;464;;;;;; +102;2368;1088;;;;;; +102;2368;2016;;;;;; +102;2368;2032;;;;;; +102;2384;288;;;;;; +102;2384;464;;;;;; +102;2384;1088;;;;;; +102;2384;2016;;;;;; +102;2384;2032;;;;;; +102;2400;288;;;;;; +102;2400;464;;;;;; +102;2400;1088;;;;;; +102;2400;2016;;;;;; +102;2400;2032;;;;;; +102;2416;288;;;;;; +102;2416;464;;;;;; +102;2416;1088;;;;;; +102;2416;2016;;;;;; +102;2416;2032;;;;;; +102;2432;288;;;;;; +102;2432;464;;;;;; +102;2432;1088;;;;;; +102;2432;2016;;;;;; +102;2432;2032;;;;;; +102;2448;288;;;;;; +102;2448;464;;;;;; +102;2448;1056;;;;;; +102;2448;1072;;;;;; +102;2448;1088;;;;;; +102;2448;2016;;;;;; +102;2448;2032;;;;;; +102;2464;288;;;;;; +102;2464;464;;;;;; +102;2464;1056;;;;;; +102;2464;1072;;;;;; +102;2464;1088;;;;;; +102;2464;1104;;;;;; +102;2464;1120;;;;;; +102;2464;1136;;;;;; +102;2464;1152;;;;;; +102;2464;1168;;;;;; +102;2464;2016;;;;;; +102;2464;2032;;;;;; +102;2480;288;;;;;; +102;2480;464;;;;;; +102;2480;1056;;;;;; +102;2480;1072;;;;;; +102;2480;1088;;;;;; +102;2480;1104;;;;;; +102;2480;1120;;;;;; +102;2480;1136;;;;;; +102;2480;1152;;;;;; +102;2480;1168;;;;;; +102;2480;2032;;;;;; +102;2496;288;;;;;; +102;2496;464;;;;;; +102;2496;2032;;;;;; +102;2512;288;;;;;; +102;2512;304;;;;;; +102;2512;320;;;;;; +102;2512;432;;;;;; +102;2512;448;;;;;; +102;2512;464;;;;;; +102;2512;2032;;;;;; +102;2528;288;;;;;; +102;2528;304;;;;;; +102;2528;320;;;;;; +102;2528;352;;;;;; +102;2528;368;;;;;; +102;2528;384;;;;;; +102;2528;400;;;;;; +102;2528;416;;;;;; +102;2528;432;;;;;; +102;2528;448;;;;;; +102;2528;464;;;;;; +102;2528;2032;;;;;; +102;2544;288;;;;;; +102;2544;304;;;;;; +102;2544;320;;;;;; +102;2544;336;;;;;; +102;2544;368;;;;;; +102;2544;384;;;;;; +102;2544;400;;;;;; +102;2544;416;;;;;; +102;2544;432;;;;;; +102;2544;448;;;;;; +102;2544;464;;;;;; +102;2544;2016;;;;;; +102;2544;2032;;;;;; +102;2560;2016;;;;;; +102;2560;2032;;;;;; +106;768;1616;;;;;; +106;768;1632;;;;;; +106;784;1616;;;;;; +106;784;1632;;;;;; +106;784;1680;;;;;; +106;800;1616;;;;;; +106;800;1632;;;;;; +106;816;1616;;;;;; +106;816;1632;;;;;; +106;832;1616;;;;;; +106;832;1632;;;;;; +106;832;1648;;;;;; +106;832;1664;;;;;; +106;832;1680;;;;;; +106;848;1632;;;;;; +106;848;1648;;;;;; +106;848;1664;;;;;; +106;864;592;;;;;; +106;880;592;;;;;; +106;896;1440;;;;;; +106;912;1440;;;;;; +106;928;1440;;;;;; +106;960;1424;;;;;; +106;1344;208;;;;;; +106;1360;208;;;;;; +106;1376;208;;;;;; +106;1392;208;;;;;; +106;1408;208;;;;;; +106;1424;208;;;;;; +106;1440;208;;;;;; +106;1440;224;;;;;; +106;1456;208;;;;;; +106;1456;224;;;;;; +106;1472;208;;;;;; +106;1488;208;;;;;; +106;1504;208;;;;;; +106;1520;208;;;;;; +106;1536;208;;;;;; +106;1552;208;;;;;; +106;1568;208;;;;;; +106;1584;192;;;;;; +106;1584;208;;;;;; +106;1600;192;;;;;; +106;1600;208;;;;;; +106;1616;192;;;;;; +106;1616;208;;;;;; +106;1632;192;;;;;; +106;1632;208;;;;;; +106;1648;208;;;;;; +106;1664;208;;;;;; +106;1680;208;;;;;; +106;1680;224;;;;;; +106;1696;208;;;;;; +106;1696;224;;;;;; +106;1712;208;;;;;; +106;1712;224;;;;;; +106;1728;208;;;;;; +106;1728;224;;;;;; +106;1744;208;;;;;; +106;1744;224;;;;;; +106;1760;208;;;;;; +106;1760;224;;;;;; +106;1776;208;;;;;; +106;1776;224;;;;;; +106;1808;304;;;;;; +106;1824;304;;;;;; +106;1824;320;;;;;; +106;1840;320;;;;;; +106;1856;320;;;;;; +106;1872;320;;;;;; +106;1904;144;;;;;; +106;1920;144;;;;;; +106;1920;160;;;;;; +106;1920;208;;;;;; +106;1936;144;;;;;; +106;1936;160;;;;;; +106;1936;176;;;;;; +106;1936;192;;;;;; +106;1936;208;;;;;; +106;1936;224;;;;;; +106;1952;208;;;;;; +106;2016;1824;;;;;; +106;2016;1888;;;;;; +106;2032;1824;;;;;; +106;2032;1888;;;;;; +106;2048;1824;;;;;; +106;2048;1888;;;;;; +106;2064;192;;;;;; +106;2064;1824;;;;;; +106;2064;1840;;;;;; +106;2064;1856;;;;;; +106;2064;1872;;;;;; +106;2064;1888;;;;;; +106;2080;176;;;;;; +106;2080;192;;;;;; +106;2080;208;;;;;; +106;2080;1824;;;;;; +106;2080;1840;;;;;; +106;2080;1856;;;;;; +106;2080;1872;;;;;; +106;2080;1888;;;;;; +106;2096;176;;;;;; +106;2096;192;;;;;; +106;2096;208;;;;;; +106;2096;1824;;;;;; +106;2096;1840;;;;;; +106;2096;1856;;;;;; +106;2096;1872;;;;;; +106;2096;1888;;;;;; +106;2112;176;;;;;; +106;2112;192;;;;;; +106;2112;208;;;;;; +106;2112;1856;;;;;; +106;2112;1872;;;;;; +106;2112;1888;;;;;; +106;2128;1856;;;;;; +106;2128;1872;;;;;; +106;2128;1888;;;;;; +107;384;352;;;;;; +107;384;368;;;;;; +107;384;384;;;;;; +107;400;336;;;;;; +107;400;352;;;;;; +107;400;368;;;;;; +107;400;384;;;;;; +107;400;400;;;;;; +107;416;336;;;;;; +107;416;352;;;;;; +107;416;416;;;;;; +107;416;432;;;;;; +107;432;304;;;;;; +107;432;320;;;;;; +107;432;336;;;;;; +107;432;352;;;;;; +107;432;368;;;;;; +107;432;384;;;;;; +107;432;400;;;;;; +107;432;432;;;;;; +107;448;288;;;;;; +107;448;304;;;;;; +107;448;320;;;;;; +107;448;352;;;;;; +107;448;368;;;;;; +107;448;384;;;;;; +107;448;400;;;;;; +107;448;416;;;;;; +107;448;448;;;;;; +107;464;288;;;;;; +107;464;304;;;;;; +107;464;320;;;;;; +107;464;352;;;;;; +107;464;400;;;;;; +107;464;416;;;;;; +107;464;432;;;;;; +107;480;304;;;;;; +107;480;336;;;;;; +107;480;352;;;;;; +107;480;416;;;;;; +107;480;432;;;;;; +107;480;464;;;;;; +107;480;480;;;;;; +107;496;304;;;;;; +107;496;336;;;;;; +107;496;352;;;;;; +107;496;416;;;;;; +107;496;432;;;;;; +107;496;464;;;;;; +107;496;480;;;;;; +107;512;336;;;;;; +107;512;352;;;;;; +107;512;368;;;;;; +107;512;384;;;;;; +107;512;400;;;;;; +107;512;416;;;;;; +107;512;432;;;;;; +107;512;464;;;;;; +107;528;304;;;;;; +107;528;336;;;;;; +107;528;352;;;;;; +107;528;368;;;;;; +107;528;384;;;;;; +107;528;400;;;;;; +107;528;416;;;;;; +107;528;432;;;;;; +107;528;464;;;;;; +107;544;288;;;;;; +107;544;304;;;;;; +107;544;320;;;;;; +107;544;352;;;;;; +107;544;368;;;;;; +107;544;384;;;;;; +107;544;400;;;;;; +107;544;416;;;;;; +107;544;448;;;;;; +107;544;480;;;;;; +107;560;288;;;;;; +107;560;320;;;;;; +107;560;336;;;;;; +107;560;352;;;;;; +107;560;432;;;;;; +107;560;448;;;;;; +107;560;464;;;;;; +107;560;480;;;;;; +107;576;288;;;;;; +107;576;304;;;;;; +107;576;320;;;;;; +107;576;336;;;;;; +107;576;352;;;;;; +107;576;368;;;;;; +107;576;384;;;;;; +107;576;400;;;;;; +107;576;416;;;;;; +107;576;432;;;;;; +107;576;448;;;;;; +107;576;464;;;;;; +107;592;288;;;;;; +107;592;304;;;;;; +107;592;320;;;;;; +107;592;336;;;;;; +107;592;448;;;;;; +107;592;464;;;;;; +107;592;480;;;;;; +107;608;304;;;;;; +107;608;320;;;;;; +107;608;336;;;;;; +107;608;352;;;;;; +107;608;368;;;;;; +107;608;384;;;;;; +107;608;400;;;;;; +107;608;416;;;;;; +107;608;432;;;;;; +107;608;464;;;;;; +107;624;288;;;;;; +107;624;304;;;;;; +107;624;336;;;;;; +107;624;352;;;;;; +107;624;368;;;;;; +107;624;384;;;;;; +107;624;400;;;;;; +107;624;416;;;;;; +107;624;432;;;;;; +107;624;464;;;;;; +107;640;288;;;;;; +107;640;416;;;;;; +107;640;432;;;;;; +107;640;464;;;;;; +107;640;480;;;;;; +107;656;288;;;;;; +107;656;416;;;;;; +107;656;432;;;;;; +107;656;464;;;;;; +107;656;480;;;;;; +107;672;288;;;;;; +107;672;304;;;;;; +107;672;320;;;;;; +107;672;336;;;;;; +107;672;352;;;;;; +107;672;416;;;;;; +107;672;464;;;;;; +107;688;288;;;;;; +107;688;304;;;;;; +107;688;320;;;;;; +107;688;336;;;;;; +107;688;352;;;;;; +107;688;432;;;;;; +107;688;448;;;;;; +107;704;288;;;;;; +107;704;304;;;;;; +107;704;320;;;;;; +107;704;336;;;;;; +107;704;352;;;;;; +107;704;368;;;;;; +107;704;384;;;;;; +107;704;400;;;;;; +107;704;416;;;;;; +107;720;288;;;;;; +107;720;304;;;;;; +107;720;320;;;;;; +107;720;336;;;;;; +107;720;352;;;;;; +107;720;368;;;;;; +107;720;384;;;;;; +107;720;400;;;;;; +107;736;320;;;;;; +107;736;336;;;;;; +107;736;352;;;;;; +107;864;400;;;;;; +107;864;416;;;;;; +107;880;400;;;;;; +107;880;416;;;;;; +107;896;400;;;;;; +183;1968;464;-0.75;0.2; +183;1984;464;-0.75;0.2; +183;2000;464;-0.75;0.1; +183;2016;464;-0.75;; +183;2032;464;-0.75;; +183;2048;464;-0.75;; +183;2048;480;-0.75;; +183;2064;464;-0.75;; +183;2064;480;-0.75;; +183;2080;464;-0.65;; +183;2080;480;-0.65;; +183;2096;464;-0.6;; +183;2096;480;-0.6;; +183;2112;464;-0.55;; +183;2128;464;-0.55;; +183;2144;464;-0.55;0.1; +183;2160;464;-0.55;0.1; +183;2176;464;-0.55;; +183;2192;464;-0.55;; +183;2208;464;-0.55;; +183;2224;464;-0.55;; +183;2240;464;;; +183;2256;464;-0.45;; +183;2272;464;-0.4;; +183;2288;464;-0.4;; +183;2304;464;-0.4;; +183;2320;464;-0.4;; +183;2336;464;-0.4;; +183;2352;464;-0.4;; +183;2368;464;-0.4;; +183;2384;464;-0.4;; +183;2400;464;-0.35;; +183;2416;464;-0.3;; +183;2432;464;-0.25;; +183;2448;464;-0.25;; +183;2464;464;-0.25;; +183;2480;464;-0.25;; +183;2496;464;-0.25;; +183;2512;464;-0.25;; +183;2528;464;-0.25;; +183;2544;464;-0.25;; +186;2512;432;;0.25; +186;2512;448;;0.25; +186;2528;352;;0.25; +186;2528;368;;0.25; +186;2528;384;;0.25; +186;2528;400;;0.25; +186;2528;416;;0.25; +186;2528;432;;0.25; +186;2528;448;;0.25; +186;2544;368;;0.25; +186;2544;384;;0.25; +186;2544;400;;0.25; +186;2544;416;;0.25; +186;2544;432;;0.25; +186;2544;448;;0.25; +187;1968;784;;; +187;1984;784;;; +187;2000;784;;; +187;2016;784;;; +187;2032;784;;; +187;2048;784;;; +187;2064;784;;; +187;2064;800;;; +187;2064;816;;; +187;2080;784;;; +187;2080;800;;; +187;2080;816;;; +187;2096;784;;; +187;2096;800;;; +187;2096;816;;; +187;2112;784;;; +187;2112;800;;; +187;2112;816;;; +187;2128;784;;; +187;2128;800;;; +187;2128;816;;; +187;2144;784;;; +187;2144;800;;; +187;2144;816;;; +187;2144;832;;; +187;2160;784;;; +187;2160;800;;; +187;2176;784;;; +187;2192;784;;; +187;2208;784;;; +187;2208;832;;; +187;2208;848;;; +187;2208;864;;; +187;2224;784;;; +187;2224;832;;; +187;2224;848;;; +187;2224;864;;; +187;2240;784;;; +187;2240;832;;; +187;2240;848;;; +187;2240;864;;; +187;2256;784;;; +187;2256;800;;; +187;2256;832;;; +187;2256;848;;; +187;2256;864;;; +187;2272;800;;; +187;2288;800;;; +187;2288;864;;; +187;2304;800;;; +187;2304;864;;; +187;2320;800;;; +187;2320;864;;; +187;2336;864;;; +187;2352;784;;; +187;2352;816;;; +187;2368;784;;; +187;2368;816;;; +187;2368;832;;; +187;2368;848;;; +187;2384;784;;; +187;2384;816;;; +187;2384;832;;; +187;2384;848;;; +187;2400;784;;; +187;2400;800;;; +187;2400;832;;; +187;2400;848;;; +187;2416;784;;; +187;2416;800;;; +187;2416;832;;; +187;2416;848;;; +187;2416;864;;; +187;2432;784;;; +187;2432;800;;; +187;2432;864;;; +187;2448;784;;; +187;2448;800;;; +187;2448;864;;; +187;2464;640;;; +187;2464;704;;; +187;2464;800;;; +187;2464;832;;; +187;2464;864;;; +187;2480;640;;; +187;2480;784;;; +187;2480;816;;; +187;2496;576;;; +187;2496;640;;; +187;2496;816;;; +187;2496;832;;; +187;2496;864;;; +187;2512;576;;; +187;2512;832;;; +187;2512;864;;; +187;2528;592;;; +187;2528;688;;; +187;2528;768;;; +187;2528;864;;; +187;2544;592;;; +187;2544;688;;; +187;2544;848;;; +187;2544;864;;; +188;1968;912;;; +188;1968;928;;; +188;1984;912;;; +188;1984;928;;; +188;2000;912;;; +188;2000;928;;; +188;2016;912;;; +188;2016;928;;; +188;2032;800;;; +188;2032;816;;; +188;2032;912;;; +188;2032;928;;; +188;2048;800;;; +188;2048;816;;; +188;2240;800;;; +188;2256;704;;; +188;2256;720;;; +188;2256;736;;; +188;2272;688;;; +188;2272;848;;; +188;2272;864;;; +188;2320;816;;; +188;2336;736;;; +188;2352;688;;; +188;2368;672;;; +188;2368;720;;; +188;2400;864;;; +188;2464;784;;; +188;2464;816;;; +188;2480;800;;; +188;2480;832;;; +188;2480;848;;; +188;2480;864;;; +188;2512;592;;; +189;1952;736;;; +189;1952;944;;; +189;1952;960;;; +189;1968;576;;; +189;1968;736;;; +189;1968;864;;; +189;1968;880;;; +189;1968;896;;; +189;1968;944;;; +189;1968;960;;; +189;1984;544;;; +189;1984;560;;; +189;1984;576;;; +189;1984;592;;; +189;1984;720;;; +189;1984;736;;; +189;1984;864;;; +189;1984;880;;; +189;1984;896;;; +189;1984;944;;; +189;1984;960;;; +189;2000;560;;; +189;2000;576;;; +189;2000;592;;; +189;2000;720;;; +189;2000;736;;; +189;2000;864;;; +189;2000;880;;; +189;2000;896;;; +189;2000;944;;; +189;2000;960;;; +189;2016;560;;; +189;2016;576;;; +189;2016;592;;; +189;2016;720;;; +189;2016;736;;; +189;2016;864;;; +189;2016;880;;; +189;2016;896;;; +189;2016;944;;; +189;2016;960;;; +189;2032;560;;; +189;2032;592;;; +189;2032;736;;; +189;2032;864;;; +189;2032;880;;; +189;2032;896;;; +189;2032;944;;; +189;2032;960;;; +189;2048;560;;; +189;2048;592;;0.1; +189;2048;720;;; +189;2048;736;;; +189;2048;864;;; +189;2048;880;;; +189;2048;896;;; +189;2048;928;;; +189;2048;944;;; +189;2048;960;;; +189;2064;560;;; +189;2064;576;;; +189;2064;592;;0.1; +189;2064;656;;; +189;2064;672;;; +189;2064;688;;; +189;2064;704;;; +189;2064;720;;; +189;2064;864;;; +189;2064;880;;; +189;2064;896;;; +189;2064;928;;; +189;2064;944;;; +189;2064;960;;; +189;2080;560;;; +189;2080;576;;; +189;2080;592;;; +189;2080;656;;; +189;2080;672;;; +189;2080;688;;; +189;2080;704;;; +189;2080;720;;; +189;2080;864;;; +189;2080;880;;; +189;2080;896;;; +189;2080;928;;; +189;2080;944;;; +189;2080;960;;; +189;2096;560;;; +189;2096;576;;; +189;2096;592;;; +189;2096;656;;; +189;2096;672;;; +189;2096;688;;; +189;2096;704;;; +189;2096;720;;; +189;2096;864;;; +189;2096;880;;; +189;2096;896;;; +189;2096;944;;; +189;2096;960;;; +189;2112;576;;; +189;2112;592;;; +189;2112;688;;; +189;2112;704;;; +189;2112;720;;; +189;2112;864;;; +189;2112;880;;; +189;2112;896;;; +189;2112;912;;; +189;2112;944;;; +189;2112;960;;; +189;2128;544;;; +189;2128;576;;; +189;2128;592;;; +189;2128;704;;; +189;2128;720;;; +189;2128;736;;; +189;2128;864;;; +189;2128;880;;; +189;2128;896;;; +189;2128;912;;; +189;2128;944;;; +189;2128;960;;; +189;2144;544;;; +189;2144;560;;; +189;2144;576;;; +189;2144;592;;; +189;2144;720;;; +189;2144;736;;; +189;2144;864;;; +189;2144;880;;; +189;2144;896;;; +189;2144;912;;; +189;2144;944;;; +189;2144;960;;; +189;2160;544;;; +189;2160;560;;; +189;2160;576;;; +189;2160;592;;; +189;2160;704;;; +189;2160;720;;; +189;2160;736;;; +189;2160;944;;; +189;2160;960;;; +189;2176;576;;; +189;2176;592;;; +189;2176;704;;; +189;2176;720;;; +189;2176;736;;; +189;2176;848;;; +189;2176;944;;; +189;2176;960;;; +189;2192;592;;; +189;2192;720;;; +189;2192;736;;; +189;2192;912;;; +189;2192;944;;; +189;2192;960;;; +189;2208;592;;; +189;2208;704;;; +189;2208;720;;; +189;2208;736;;; +189;2208;912;;; +189;2208;960;;; +189;2224;608;;; +189;2224;656;;; +189;2224;672;;; +189;2224;688;;; +189;2224;704;;; +189;2224;720;;; +189;2224;736;;; +189;2224;912;;; +189;2224;928;;; +189;2224;960;;; +189;2240;576;;; +189;2240;592;;; +189;2240;608;;; +189;2240;656;;; +189;2240;672;;; +189;2240;688;;; +189;2240;704;;; +189;2240;720;;; +189;2240;736;;; +189;2240;912;;; +189;2240;928;;; +189;2240;960;;; +189;2256;576;;; +189;2256;592;;; +189;2256;608;;; +189;2256;656;;; +189;2256;672;;; +189;2256;688;;; +189;2256;912;;; +189;2256;928;;; +189;2256;960;;; +189;2272;576;;; +189;2272;592;;; +189;2272;608;;; +189;2272;656;;; +189;2272;672;;; +189;2272;832;;; +189;2272;912;;; +189;2272;928;;; +189;2272;960;;; +189;2288;544;;; +189;2288;560;;; +189;2288;576;;; +189;2288;592;;; +189;2288;608;;; +189;2288;656;;; +189;2288;672;;; +189;2288;688;;; +189;2288;832;;; +189;2288;912;;; +189;2288;960;;; +189;2304;544;;; +189;2304;560;;; +189;2304;576;;; +189;2304;592;;; +189;2304;608;;; +189;2304;656;;; +189;2304;672;;; +189;2304;688;;; +189;2304;832;;; +189;2304;912;;; +189;2304;944;;; +189;2304;960;;; +189;2320;544;;; +189;2320;560;;; +189;2320;608;;; +189;2320;656;;; +189;2320;672;;; +189;2320;688;;; +189;2320;832;;; +189;2320;912;;; +189;2320;944;;; +189;2320;960;;; +189;2336;544;;; +189;2336;560;;; +189;2336;608;;; +189;2336;656;;; +189;2336;672;;; +189;2336;688;;; +189;2336;704;;; +189;2336;720;;; +189;2336;912;;; +189;2336;944;;; +189;2352;544;;; +189;2352;560;;; +189;2352;608;;; +189;2352;656;;; +189;2352;672;;; +189;2352;704;;; +189;2352;720;;; +189;2352;912;;; +189;2352;944;;; +189;2368;544;;; +189;2368;560;;; +189;2368;608;;; +189;2368;656;;; +189;2368;704;;; +189;2368;736;;; +189;2368;912;;; +189;2368;944;;; +189;2384;544;;; +189;2384;560;;; +189;2384;608;;; +189;2384;656;;; +189;2384;688;;; +189;2384;704;;; +189;2384;736;;; +189;2384;912;;; +189;2384;944;;; +189;2384;960;;; +189;2400;544;;; +189;2400;560;;; +189;2400;608;;; +189;2400;656;;; +189;2400;672;;; +189;2400;688;;; +189;2400;704;;; +189;2400;720;;; +189;2400;736;;; +189;2400;912;;; +189;2400;944;;; +189;2400;960;;; +189;2416;544;;; +189;2416;560;;; +189;2416;608;;; +189;2416;656;;; +189;2416;672;;; +189;2416;688;;; +189;2416;704;;; +189;2416;720;;; +189;2416;736;;; +189;2416;912;;; +189;2416;944;;; +189;2416;960;;; +189;2432;544;;; +189;2432;560;;; +189;2432;688;;; +189;2432;912;;; +189;2432;944;;; +189;2432;960;;; +189;2448;544;;; +189;2448;560;;; +189;2448;688;;; +189;2448;912;;; +189;2464;544;;; +189;2464;560;;; +189;2464;912;;; +189;2480;544;;; +189;2480;560;;; +189;2496;544;;; +189;2512;544;;; +189;2512;640;;; +189;2512;704;;; +189;2528;560;;; +189;2528;640;;; +189;2528;704;;; +190;1952;544;;; +190;1952;560;;; +190;1952;576;;; +190;1952;592;;; +190;1952;656;;; +190;1952;672;;; +190;1952;688;;; +190;1952;704;;; +190;1952;720;;; +190;1952;784;;; +190;1952;800;;; +190;1952;816;;; +190;1952;832;;; +190;1952;848;;; +190;1952;864;;; +190;1952;880;;; +190;1952;896;;; +190;1952;912;;; +190;1952;928;;; +190;1968;544;;; +190;1968;560;;; +190;1968;592;;; +190;1968;656;;; +190;1968;672;;; +190;1968;688;;; +190;1968;704;;; +190;1968;720;;; +190;2000;544;;; +190;2016;544;;; +190;2032;576;;; +190;2032;832;;; +190;2032;848;;; +190;2048;656;;; +190;2048;672;;; +190;2048;688;;; +190;2048;832;;; +190;2048;848;;; +190;2096;928;;; +190;2112;560;;; +190;2112;656;;; +190;2112;672;;; +190;2128;688;;; +190;2128;832;;; +190;2128;848;;; +190;2144;704;;; +190;2160;864;;; +190;2160;880;;; +190;2160;896;;; +190;2160;912;;; +190;2160;928;;; +190;2176;544;;; +190;2176;560;;; +190;2192;576;;; +190;2192;832;;; +190;2192;848;;; +190;2192;864;;; +190;2192;880;;; +190;2192;896;;; +190;2208;928;;; +190;2208;944;;; +190;2224;592;;; +190;2304;816;;; +190;2320;576;;; +190;2320;592;;; +190;2336;784;;; +190;2336;800;;; +190;2336;816;;; +190;2336;832;;; +190;2336;848;;; +190;2352;832;;; +190;2352;848;;; +190;2352;864;;; +190;2384;800;;; +190;2432;608;;; +190;2432;624;;; +190;2432;640;;; +190;2432;656;;; +190;2432;672;;; +190;2432;704;;; +190;2432;720;;; +190;2432;736;;; +190;2432;752;;; +190;2432;768;;; +190;2432;832;;; +190;2432;848;;; +190;2432;928;;; +190;2448;608;;; +190;2448;624;;; +190;2448;640;;; +190;2448;656;;; +190;2448;672;;; +190;2448;704;;; +190;2448;720;;; +190;2448;736;;; +190;2448;752;;; +190;2448;768;;; +190;2448;832;;; +190;2448;848;;; +190;2448;928;;; +190;2448;944;;; +190;2448;960;;; +190;2448;976;;; +190;2464;576;;; +190;2464;592;;; +190;2464;608;;; +190;2464;624;;; +190;2464;688;;; +190;2464;752;;; +190;2464;768;;; +190;2464;928;;; +190;2464;944;;; +190;2464;960;;; +190;2464;976;;; +190;2480;576;;; +190;2480;592;;; +190;2480;608;;; +190;2480;624;;; +190;2480;912;;; +190;2480;928;;; +190;2480;944;;; +190;2480;960;;; +190;2480;976;;; +190;2496;560;;; +190;2496;608;;; +190;2496;624;;; +190;2496;912;;; +190;2496;928;;; +190;2496;944;;; +190;2496;960;;; +190;2512;624;;; +190;2512;688;;; +190;2512;752;;; +190;2512;768;;; +190;2512;784;;; +190;2512;800;;; +190;2512;816;;; +190;2512;928;;; +190;2512;944;;; +190;2512;960;;; +190;2528;544;;; +190;2528;608;;; +190;2528;624;;; +190;2528;752;;; +190;2528;848;;; +190;2528;928;;; +190;2528;944;;; +190;2528;960;;; +190;2544;544;;; +190;2544;560;;; +190;2544;576;;; +190;2544;608;;; +190;2544;624;;; +190;2544;640;;; +190;2544;656;;; +190;2544;672;;; +190;2544;704;;; +190;2544;720;;; +190;2544;736;;; +190;2544;752;;; +190;2544;768;;; +190;2544;784;;; +190;2544;800;;; +190;2544;816;;; +190;2544;832;;; +190;2544;944;;; +190;2544;960;;; +158;688;688 +158;688;704 +158;704;688 +158;704;704 +158;704;720 +158;720;688 +158;720;704 +158;720;720 +158;1008;1472 +158;1008;1488 +158;1008;1504 +158;1024;1472 +158;1040;1312 +158;1040;1328 +158;1040;1344 +158;1040;1360 +158;1040;1376 +158;1040;1392 +158;1040;1408 +158;1040;1424 +158;1040;1440 +158;1040;1456 +158;1040;1472 +158;1056;1312 +158;1056;1392 +158;1056;1408 +158;1056;1456 +158;1056;1472 +158;1056;1488 +158;1056;1504 +158;1072;1312 +158;1072;1392 +158;1072;1408 +158;1072;1456 +158;1072;1504 +158;1088;1312 +158;1088;1392 +158;1088;1408 +158;1088;1424 +158;1088;1440 +158;1088;1456 +158;1088;1504 +158;1104;1312 +158;1104;1328 +158;1104;1344 +158;1104;1360 +158;1104;1376 +158;1104;1392 +158;1104;1408 +158;1104;1456 +158;1104;1472 +158;1104;1488 +158;1104;1504 +158;1120;1312 +158;1120;1328 +158;1120;1344 +158;1120;1360 +158;1120;1376 +158;1120;1392 +158;1120;1408 +158;1120;1456 +158;1120;1472 +158;1120;1488 +158;1120;1504 +158;1136;1312 +158;1136;1328 +158;1136;1344 +158;1136;1360 +158;1136;1376 +158;1136;1392 +158;1136;1408 +158;1136;1456 +158;1136;1472 +158;1136;1488 +158;1136;1504 +158;1152;1312 +158;1152;1328 +158;1152;1344 +158;1152;1360 +158;1152;1376 +158;1152;1392 +158;1152;1408 +158;1152;1456 +158;1152;1472 +158;1152;1488 +158;1152;1504 +158;1168;1312 +158;1168;1328 +158;1168;1344 +158;1168;1360 +158;1168;1376 +158;1168;1392 +158;1168;1408 +158;1168;1424 +158;1168;1440 +158;1168;1456 +158;1168;1472 +158;1168;1488 +158;1168;1504 +158;1184;1456 +158;1184;1472 +158;1312;560 +158;1312;576 +158;1312;592 +158;1312;608 +158;1312;624 +158;1312;640 +158;1312;656 +158;1312;672 +158;1312;688 +158;1312;704 +158;1312;720 +158;1312;736 +158;1312;752 +158;1312;768 +158;1312;784 +158;1312;800 +158;1312;816 +158;1312;832 +158;1312;848 +158;1312;864 +158;1312;880 +158;1312;896 +158;1312;912 +158;1312;928 +158;1312;944 +158;1312;960 +158;1312;1952 +158;1312;1968 +158;1312;1984 +158;1312;2000 +158;1312;2016 +158;1328;560 +158;1328;736 +158;1328;752 +158;1328;768 +158;1328;784 +158;1328;800 +158;1328;816 +158;1328;832 +158;1328;848 +158;1328;944 +158;1328;960 +158;1328;1952 +158;1328;2016 +158;1344;528 +158;1344;544 +158;1344;560 +158;1344;944 +158;1344;960 +158;1344;1952 +158;1344;2016 +158;1360;464 +158;1360;480 +158;1360;496 +158;1360;512 +158;1360;528 +158;1360;544 +158;1360;560 +158;1360;928 +158;1360;944 +158;1360;960 +158;1360;1760 +158;1360;1776 +158;1360;1792 +158;1360;1808 +158;1360;1952 +158;1376;288 +158;1376;304 +158;1376;416 +158;1376;432 +158;1376;448 +158;1376;464 +158;1376;480 +158;1376;928 +158;1376;944 +158;1376;960 +158;1376;1760 +158;1376;1776 +158;1376;1792 +158;1376;1808 +158;1392;288 +158;1392;304 +158;1392;464 +158;1392;480 +158;1392;928 +158;1392;944 +158;1392;960 +158;1392;1760 +158;1392;1776 +158;1392;1792 +158;1392;1808 +158;1408;288 +158;1408;304 +158;1408;480 +158;1408;928 +158;1408;944 +158;1408;960 +158;1408;1760 +158;1408;1776 +158;1408;1792 +158;1408;1808 +158;1424;304 +158;1424;480 +158;1424;928 +158;1424;944 +158;1424;960 +158;1424;1680 +158;1424;1696 +158;1424;1712 +158;1424;1728 +158;1424;1744 +158;1424;1760 +158;1424;1776 +158;1424;1792 +158;1424;1808 +158;1424;1824 +158;1424;1840 +158;1424;1856 +158;1440;304 +158;1440;480 +158;1440;928 +158;1440;944 +158;1440;960 +158;1440;1600 +158;1440;1616 +158;1440;1632 +158;1440;1648 +158;1440;1664 +158;1440;1680 +158;1440;1696 +158;1440;1712 +158;1440;1728 +158;1440;1744 +158;1440;1760 +158;1440;1776 +158;1440;1792 +158;1440;1808 +158;1440;1824 +158;1440;1840 +158;1440;1856 +158;1456;304 +158;1456;480 +158;1456;928 +158;1456;944 +158;1456;960 +158;1456;1600 +158;1456;1616 +158;1456;1632 +158;1456;1648 +158;1456;1664 +158;1456;1680 +158;1456;1696 +158;1456;1712 +158;1456;1728 +158;1456;1744 +158;1456;1760 +158;1456;1776 +158;1456;1792 +158;1456;1808 +158;1456;1824 +158;1456;1840 +158;1456;1856 +158;1472;304 +158;1472;480 +158;1472;928 +158;1472;944 +158;1472;960 +158;1472;1600 +158;1472;1616 +158;1472;1632 +158;1472;1648 +158;1472;1664 +158;1472;1680 +158;1472;1696 +158;1472;1712 +158;1472;1744 +158;1472;1776 +158;1472;1792 +158;1472;1808 +158;1472;1824 +158;1472;1840 +158;1472;1856 +158;1488;288 +158;1488;304 +158;1488;480 +158;1488;944 +158;1488;960 +158;1488;1600 +158;1488;1616 +158;1488;1648 +158;1488;1664 +158;1488;1680 +158;1488;1744 +158;1488;1776 +158;1488;1792 +158;1488;1808 +158;1488;1824 +158;1488;1840 +158;1504;288 +158;1504;304 +158;1504;320 +158;1504;480 +158;1504;1600 +158;1504;1616 +158;1504;1632 +158;1504;1648 +158;1504;1664 +158;1504;1696 +158;1504;1712 +158;1504;1728 +158;1504;1776 +158;1504;1792 +158;1504;1808 +158;1504;1840 +158;1504;1856 +158;1520;288 +158;1520;304 +158;1520;480 +158;1520;1568 +158;1520;1584 +158;1520;1600 +158;1520;1616 +158;1520;1632 +158;1520;1648 +158;1520;1664 +158;1520;1728 +158;1520;1744 +158;1520;1776 +158;1520;1792 +158;1520;1856 +158;1520;1872 +158;1520;1888 +158;1520;1904 +158;1520;1920 +158;1536;288 +158;1536;304 +158;1536;480 +158;1536;1568 +158;1536;1584 +158;1536;1600 +158;1536;1616 +158;1536;1648 +158;1536;1664 +158;1536;1728 +158;1536;1744 +158;1536;1776 +158;1536;1792 +158;1536;1888 +158;1536;1904 +158;1536;1920 +158;1552;288 +158;1552;304 +158;1552;480 +158;1552;1568 +158;1552;1584 +158;1552;1600 +158;1552;1616 +158;1552;1632 +158;1552;1648 +158;1552;1664 +158;1552;1728 +158;1552;1744 +158;1552;1776 +158;1552;1792 +158;1552;1888 +158;1552;1904 +158;1552;1920 +158;1568;288 +158;1568;304 +158;1568;480 +158;1568;1504 +158;1568;1520 +158;1568;1536 +158;1568;1568 +158;1568;1584 +158;1568;1600 +158;1568;1616 +158;1568;1632 +158;1568;1648 +158;1568;1664 +158;1568;1696 +158;1568;1712 +158;1568;1728 +158;1568;1776 +158;1568;1792 +158;1584;288 +158;1584;304 +158;1584;480 +158;1584;944 +158;1584;960 +158;1584;1504 +158;1584;1520 +158;1584;1536 +158;1584;1552 +158;1584;1568 +158;1584;1584 +158;1584;1600 +158;1584;1616 +158;1584;1632 +158;1584;1648 +158;1584;1664 +158;1584;1680 +158;1584;1760 +158;1584;1776 +158;1584;1792 +158;1600;288 +158;1600;304 +158;1600;480 +158;1600;928 +158;1600;944 +158;1600;960 +158;1600;1504 +158;1600;1520 +158;1600;1536 +158;1600;1552 +158;1600;1568 +158;1600;1584 +158;1600;1600 +158;1600;1616 +158;1600;1632 +158;1600;1648 +158;1600;1664 +158;1600;1680 +158;1600;1696 +158;1600;1712 +158;1600;1728 +158;1600;1744 +158;1600;1760 +158;1600;1776 +158;1600;1792 +158;1616;288 +158;1616;304 +158;1616;480 +158;1616;928 +158;1616;944 +158;1616;960 +158;1616;1504 +158;1616;1520 +158;1616;1536 +158;1616;1552 +158;1616;1568 +158;1616;1584 +158;1616;1600 +158;1616;1616 +158;1616;1632 +158;1616;1648 +158;1616;1664 +158;1616;1680 +158;1616;1696 +158;1616;1712 +158;1616;1728 +158;1616;1744 +158;1616;1760 +158;1616;1776 +158;1616;1792 +158;1632;288 +158;1632;304 +158;1632;480 +158;1632;928 +158;1632;944 +158;1632;960 +158;1632;1504 +158;1632;1520 +158;1632;1536 +158;1632;1552 +158;1632;1568 +158;1632;1584 +158;1632;1600 +158;1632;1616 +158;1632;1632 +158;1632;1648 +158;1632;1664 +158;1632;1680 +158;1632;1696 +158;1632;1712 +158;1632;1728 +158;1632;1744 +158;1632;1760 +158;1632;1776 +158;1632;1792 +158;1648;288 +158;1648;304 +158;1648;320 +158;1648;480 +158;1648;928 +158;1648;944 +158;1648;960 +158;1648;1504 +158;1648;1520 +158;1648;1536 +158;1648;1552 +158;1648;1568 +158;1648;1584 +158;1648;1600 +158;1648;1616 +158;1648;1632 +158;1648;1648 +158;1648;1664 +158;1648;1680 +158;1648;1760 +158;1648;1776 +158;1648;1792 +158;1664;304 +158;1664;320 +158;1664;480 +158;1664;928 +158;1664;944 +158;1664;960 +158;1664;1488 +158;1664;1504 +158;1664;1520 +158;1664;1536 +158;1664;1552 +158;1664;1568 +158;1664;1584 +158;1664;1600 +158;1664;1616 +158;1664;1632 +158;1664;1648 +158;1664;1664 +158;1664;1680 +158;1664;1824 +158;1680;304 +158;1680;320 +158;1680;480 +158;1680;928 +158;1680;944 +158;1680;960 +158;1680;1456 +158;1680;1472 +158;1680;1488 +158;1680;1504 +158;1680;1520 +158;1680;1536 +158;1680;1552 +158;1680;1568 +158;1680;1584 +158;1680;1600 +158;1680;1616 +158;1680;1632 +158;1680;1648 +158;1680;1664 +158;1680;1680 +158;1680;1952 +158;1680;1968 +158;1680;1984 +158;1680;2000 +158;1680;2016 +158;1696;304 +158;1696;320 +158;1696;480 +158;1696;928 +158;1696;944 +158;1696;960 +158;1696;1456 +158;1696;1520 +158;1696;1536 +158;1696;1552 +158;1696;1568 +158;1696;1584 +158;1696;1600 +158;1696;1616 +158;1696;1632 +158;1696;1648 +158;1696;1664 +158;1696;1680 +158;1696;1952 +158;1696;1968 +158;1696;1984 +158;1696;2000 +158;1696;2032 +158;1712;288 +158;1712;304 +158;1712;320 +158;1712;448 +158;1712;464 +158;1712;480 +158;1712;928 +158;1712;944 +158;1712;960 +158;1712;1456 +158;1712;1520 +158;1712;1536 +158;1712;1552 +158;1712;1568 +158;1712;1584 +158;1712;1600 +158;1712;1616 +158;1712;1632 +158;1712;1648 +158;1712;1664 +158;1712;1680 +158;1712;1696 +158;1712;1824 +158;1712;2032 +158;1728;304 +158;1728;320 +158;1728;448 +158;1728;464 +158;1728;480 +158;1728;944 +158;1728;960 +158;1728;1456 +158;1728;1696 +158;1728;1824 +158;1728;1840 +158;1728;2032 +158;1744;304 +158;1744;320 +158;1744;448 +158;1744;848 +158;1744;944 +158;1744;960 +158;1744;1456 +158;1744;1696 +158;1744;1712 +158;1744;1728 +158;1744;1744 +158;1744;1760 +158;1744;1776 +158;1744;1792 +158;1744;1808 +158;1744;1824 +158;1744;2032 +158;1760;304 +158;1760;320 +158;1760;448 +158;1760;848 +158;1760;864 +158;1760;880 +158;1760;896 +158;1760;912 +158;1760;928 +158;1760;944 +158;1760;960 +158;1760;1456 +158;1760;1696 +158;1760;1712 +158;1760;1728 +158;1760;1744 +158;1760;1760 +158;1760;1776 +158;1760;1792 +158;1760;1808 +158;1760;1824 +158;1760;2032 +158;1776;304 +158;1776;320 +158;1776;448 +158;1776;848 +158;1776;864 +158;1776;880 +158;1776;896 +158;1776;912 +158;1776;928 +158;1776;944 +158;1776;960 +158;1776;1456 +158;1776;1696 +158;1776;1712 +158;1776;1728 +158;1776;1744 +158;1776;1760 +158;1776;1776 +158;1776;1792 +158;1776;1808 +158;1776;1824 +158;1792;304 +158;1792;320 +158;1792;448 +158;1792;928 +158;1792;944 +158;1792;960 +158;1792;1456 +158;1808;320 +158;1808;448 +158;1808;928 +158;1808;1456 +158;1824;448 +158;1824;928 +158;1824;1232 +158;1824;1248 +158;1824;1264 +158;1824;1280 +158;1824;1296 +158;1824;1312 +158;1824;1456 +158;1840;448 +158;1840;464 +158;1840;480 +158;1840;1200 +158;1840;1216 +158;1840;1232 +158;1840;1248 +158;1840;1264 +158;1840;1280 +158;1840;1296 +158;1840;1312 +158;1840;1328 +158;1840;1344 +158;1840;1360 +158;1840;1376 +158;1840;1392 +158;1840;1408 +158;1840;1424 +158;1840;1440 +158;1840;1456 +158;1856;448 +158;1856;464 +158;1856;480 +158;1856;688 +158;1856;704 +158;1856;720 +158;1856;928 +158;1856;1200 +158;1856;1216 +158;1856;1328 +158;1856;1344 +158;1856;1360 +158;1856;1376 +158;1856;1392 +158;1856;1408 +158;1856;1424 +158;1856;1440 +158;1872;464 +158;1872;480 +158;1872;688 +158;1872;704 +158;1872;720 +158;1872;928 +158;1872;1200 +158;1872;1216 +158;1888;304 +158;1888;320 +158;1888;464 +158;1888;480 +158;1888;496 +158;1888;512 +158;1888;528 +158;1888;544 +158;1888;560 +158;1888;576 +158;1888;592 +158;1888;608 +158;1888;624 +158;1888;640 +158;1888;656 +158;1888;672 +158;1888;688 +158;1888;704 +158;1888;720 +158;1888;736 +158;1888;752 +158;1888;768 +158;1888;784 +158;1888;928 +158;1888;944 +158;1888;960 +158;1888;1200 +158;1888;1216 +158;1904;304 +158;1904;320 +158;1904;528 +158;1904;544 +158;1904;560 +158;1904;576 +158;1904;592 +158;1904;608 +158;1904;624 +158;1904;640 +158;1904;656 +158;1904;672 +158;1904;688 +158;1904;704 +158;1904;720 +158;1904;736 +158;1904;752 +158;1904;768 +158;1904;784 +158;1904;800 +158;1904;816 +158;1904;832 +158;1904;848 +158;1904;864 +158;1904;880 +158;1904;896 +158;1904;912 +158;1904;928 +158;1904;944 +158;1904;960 +158;1904;976 +158;1904;992 +158;1904;1008 +158;1904;1024 +158;1904;1040 +158;1904;1056 +158;1904;1072 +158;1904;1088 +158;1904;1104 +158;1904;1120 +158;1904;1136 +158;1904;1152 +158;1904;1168 +158;1904;1184 +158;1904;1200 +158;1904;1216 +158;1920;304 +158;1920;320 +158;1920;1216 +158;1936;304 +158;1936;320 +158;1936;1216 +158;1952;304 +158;1952;320 +158;1952;544 +158;1952;560 +158;1952;576 +158;1952;592 +158;1952;656 +158;1952;672 +158;1952;688 +158;1952;704 +158;1952;720 +158;1952;736 +158;1952;784 +158;1952;800 +158;1952;816 +158;1952;832 +158;1952;848 +158;1952;864 +158;1952;880 +158;1952;896 +158;1952;912 +158;1952;928 +158;1952;944 +158;1952;960 +158;1952;1184 +158;1952;1200 +158;1952;1216 +158;1968;208 +158;1968;288 +158;1968;304 +158;1968;320 +158;1968;464 +158;1968;544 +158;1968;560 +158;1968;576 +158;1968;592 +158;1968;656 +158;1968;672 +158;1968;688 +158;1968;704 +158;1968;720 +158;1968;736 +158;1968;784 +158;1968;864 +158;1968;880 +158;1968;896 +158;1968;912 +158;1968;928 +158;1968;944 +158;1968;960 +158;1968;1216 +158;1984;208 +158;1984;288 +158;1984;304 +158;1984;464 +158;1984;544 +158;1984;560 +158;1984;576 +158;1984;592 +158;1984;720 +158;1984;736 +158;1984;784 +158;1984;864 +158;1984;880 +158;1984;896 +158;1984;912 +158;1984;928 +158;1984;944 +158;1984;960 +158;1984;1216 +158;2000;208 +158;2000;288 +158;2000;304 +158;2000;464 +158;2000;544 +158;2000;560 +158;2000;576 +158;2000;592 +158;2000;720 +158;2000;736 +158;2000;784 +158;2000;864 +158;2000;880 +158;2000;896 +158;2000;912 +158;2000;928 +158;2000;944 +158;2000;960 +158;2000;1216 +158;2016;192 +158;2016;208 +158;2016;288 +158;2016;464 +158;2016;544 +158;2016;560 +158;2016;576 +158;2016;592 +158;2016;720 +158;2016;736 +158;2016;784 +158;2016;864 +158;2016;880 +158;2016;896 +158;2016;912 +158;2016;928 +158;2016;944 +158;2016;960 +158;2016;1216 +158;2032;192 +158;2032;208 +158;2032;288 +158;2032;464 +158;2032;560 +158;2032;576 +158;2032;592 +158;2032;736 +158;2032;784 +158;2032;800 +158;2032;816 +158;2032;832 +158;2032;848 +158;2032;864 +158;2032;880 +158;2032;896 +158;2032;912 +158;2032;928 +158;2032;944 +158;2032;960 +158;2032;1216 +158;2048;192 +158;2048;208 +158;2048;288 +158;2048;464 +158;2048;480 +158;2048;560 +158;2048;592 +158;2048;656 +158;2048;672 +158;2048;688 +158;2048;720 +158;2048;736 +158;2048;784 +158;2048;800 +158;2048;816 +158;2048;832 +158;2048;848 +158;2048;864 +158;2048;880 +158;2048;896 +158;2048;928 +158;2048;944 +158;2048;960 +158;2048;1216 +158;2064;208 +158;2064;288 +158;2064;304 +158;2064;464 +158;2064;480 +158;2064;560 +158;2064;576 +158;2064;592 +158;2064;656 +158;2064;672 +158;2064;688 +158;2064;704 +158;2064;720 +158;2064;784 +158;2064;800 +158;2064;816 +158;2064;864 +158;2064;880 +158;2064;896 +158;2064;928 +158;2064;944 +158;2064;960 +158;2064;1216 +158;2080;288 +158;2080;464 +158;2080;480 +158;2080;560 +158;2080;576 +158;2080;592 +158;2080;656 +158;2080;672 +158;2080;688 +158;2080;704 +158;2080;720 +158;2080;784 +158;2080;800 +158;2080;816 +158;2080;864 +158;2080;880 +158;2080;896 +158;2080;928 +158;2080;944 +158;2080;960 +158;2080;1072 +158;2080;1088 +158;2080;1104 +158;2080;1120 +158;2080;1136 +158;2080;1152 +158;2080;1168 +158;2080;1184 +158;2080;1200 +158;2080;1216 +158;2096;288 +158;2096;464 +158;2096;480 +158;2096;560 +158;2096;576 +158;2096;592 +158;2096;656 +158;2096;672 +158;2096;688 +158;2096;704 +158;2096;720 +158;2096;784 +158;2096;800 +158;2096;816 +158;2096;864 +158;2096;880 +158;2096;896 +158;2096;928 +158;2096;944 +158;2096;960 +158;2096;1072 +158;2096;1088 +158;2096;1104 +158;2096;1120 +158;2096;1136 +158;2096;1152 +158;2096;1168 +158;2096;1184 +158;2096;1200 +158;2096;1216 +158;2112;288 +158;2112;464 +158;2112;560 +158;2112;576 +158;2112;592 +158;2112;656 +158;2112;672 +158;2112;688 +158;2112;704 +158;2112;720 +158;2112;784 +158;2112;800 +158;2112;816 +158;2112;864 +158;2112;880 +158;2112;896 +158;2112;912 +158;2112;944 +158;2112;960 +158;2112;1072 +158;2112;1088 +158;2112;1104 +158;2112;1120 +158;2112;1136 +158;2112;1152 +158;2112;1216 +158;2128;288 +158;2128;304 +158;2128;464 +158;2128;544 +158;2128;576 +158;2128;592 +158;2128;688 +158;2128;704 +158;2128;720 +158;2128;736 +158;2128;784 +158;2128;800 +158;2128;816 +158;2128;832 +158;2128;848 +158;2128;864 +158;2128;880 +158;2128;896 +158;2128;912 +158;2128;944 +158;2128;960 +158;2128;1136 +158;2128;1152 +158;2128;1216 +158;2144;288 +158;2144;304 +158;2144;464 +158;2144;544 +158;2144;560 +158;2144;576 +158;2144;592 +158;2144;704 +158;2144;720 +158;2144;736 +158;2144;784 +158;2144;800 +158;2144;816 +158;2144;832 +158;2144;864 +158;2144;880 +158;2144;896 +158;2144;912 +158;2144;944 +158;2144;960 +158;2144;1136 +158;2144;1152 +158;2144;1216 +158;2160;288 +158;2160;464 +158;2160;544 +158;2160;560 +158;2160;576 +158;2160;592 +158;2160;704 +158;2160;720 +158;2160;736 +158;2160;784 +158;2160;800 +158;2160;864 +158;2160;880 +158;2160;896 +158;2160;912 +158;2160;928 +158;2160;944 +158;2160;960 +158;2160;1136 +158;2160;1152 +158;2160;1216 +158;2176;288 +158;2176;464 +158;2176;544 +158;2176;560 +158;2176;576 +158;2176;592 +158;2176;704 +158;2176;720 +158;2176;736 +158;2176;784 +158;2176;848 +158;2176;944 +158;2176;960 +158;2176;1136 +158;2176;1152 +158;2176;1216 +158;2192;288 +158;2192;464 +158;2192;576 +158;2192;592 +158;2192;720 +158;2192;736 +158;2192;784 +158;2192;832 +158;2192;848 +158;2192;864 +158;2192;880 +158;2192;896 +158;2192;912 +158;2192;944 +158;2192;960 +158;2192;1072 +158;2192;1136 +158;2192;1152 +158;2192;1216 +158;2208;288 +158;2208;304 +158;2208;464 +158;2208;592 +158;2208;704 +158;2208;720 +158;2208;736 +158;2208;784 +158;2208;832 +158;2208;848 +158;2208;864 +158;2208;912 +158;2208;928 +158;2208;944 +158;2208;960 +158;2208;1072 +158;2208;1136 +158;2208;1152 +158;2208;1168 +158;2208;1184 +158;2208;1200 +158;2208;1216 +158;2224;288 +158;2224;464 +158;2224;592 +158;2224;608 +158;2224;656 +158;2224;672 +158;2224;688 +158;2224;704 +158;2224;720 +158;2224;736 +158;2224;784 +158;2224;832 +158;2224;848 +158;2224;864 +158;2224;912 +158;2224;928 +158;2224;960 +158;2224;1072 +158;2240;288 +158;2240;464 +158;2240;576 +158;2240;592 +158;2240;608 +158;2240;656 +158;2240;672 +158;2240;688 +158;2240;704 +158;2240;720 +158;2240;736 +158;2240;784 +158;2240;800 +158;2240;832 +158;2240;848 +158;2240;864 +158;2240;912 +158;2240;928 +158;2240;960 +158;2240;1072 +158;2256;288 +158;2256;464 +158;2256;576 +158;2256;592 +158;2256;608 +158;2256;656 +158;2256;672 +158;2256;688 +158;2256;704 +158;2256;720 +158;2256;736 +158;2256;784 +158;2256;800 +158;2256;832 +158;2256;848 +158;2256;864 +158;2256;912 +158;2256;928 +158;2256;960 +158;2256;1072 +158;2272;288 +158;2272;464 +158;2272;576 +158;2272;592 +158;2272;608 +158;2272;656 +158;2272;672 +158;2272;688 +158;2272;800 +158;2272;832 +158;2272;848 +158;2272;864 +158;2272;912 +158;2272;928 +158;2272;960 +158;2272;1072 +158;2288;288 +158;2288;432 +158;2288;464 +158;2288;544 +158;2288;560 +158;2288;576 +158;2288;592 +158;2288;608 +158;2288;656 +158;2288;672 +158;2288;688 +158;2288;800 +158;2288;832 +158;2288;864 +158;2288;912 +158;2288;960 +158;2288;1072 +158;2304;288 +158;2304;432 +158;2304;464 +158;2304;544 +158;2304;560 +158;2304;576 +158;2304;592 +158;2304;608 +158;2304;656 +158;2304;672 +158;2304;688 +158;2304;800 +158;2304;816 +158;2304;832 +158;2304;864 +158;2304;912 +158;2304;944 +158;2304;960 +158;2304;1072 +158;2304;1088 +158;2320;288 +158;2320;304 +158;2320;320 +158;2320;336 +158;2320;352 +158;2320;368 +158;2320;384 +158;2320;400 +158;2320;416 +158;2320;432 +158;2320;464 +158;2320;544 +158;2320;560 +158;2320;576 +158;2320;592 +158;2320;608 +158;2320;656 +158;2320;672 +158;2320;688 +158;2320;800 +158;2320;816 +158;2320;832 +158;2320;864 +158;2320;912 +158;2320;944 +158;2320;960 +158;2320;1088 +158;2336;272 +158;2336;288 +158;2336;304 +158;2336;320 +158;2336;336 +158;2336;352 +158;2336;464 +158;2336;544 +158;2336;560 +158;2336;608 +158;2336;656 +158;2336;672 +158;2336;688 +158;2336;704 +158;2336;720 +158;2336;736 +158;2336;784 +158;2336;800 +158;2336;816 +158;2336;832 +158;2336;848 +158;2336;864 +158;2336;912 +158;2336;944 +158;2336;1088 +158;2352;288 +158;2352;464 +158;2352;544 +158;2352;560 +158;2352;608 +158;2352;656 +158;2352;672 +158;2352;688 +158;2352;704 +158;2352;720 +158;2352;784 +158;2352;816 +158;2352;832 +158;2352;848 +158;2352;864 +158;2352;912 +158;2352;944 +158;2352;1088 +158;2368;288 +158;2368;464 +158;2368;544 +158;2368;560 +158;2368;608 +158;2368;656 +158;2368;672 +158;2368;704 +158;2368;720 +158;2368;736 +158;2368;784 +158;2368;816 +158;2368;832 +158;2368;848 +158;2368;912 +158;2368;944 +158;2368;1088 +158;2384;288 +158;2384;464 +158;2384;544 +158;2384;560 +158;2384;608 +158;2384;656 +158;2384;688 +158;2384;704 +158;2384;736 +158;2384;784 +158;2384;800 +158;2384;816 +158;2384;832 +158;2384;848 +158;2384;912 +158;2384;944 +158;2384;960 +158;2384;1088 +158;2400;288 +158;2400;464 +158;2400;544 +158;2400;560 +158;2400;608 +158;2400;656 +158;2400;672 +158;2400;688 +158;2400;704 +158;2400;720 +158;2400;736 +158;2400;784 +158;2400;800 +158;2400;832 +158;2400;848 +158;2400;864 +158;2400;912 +158;2400;944 +158;2400;960 +158;2400;1088 +158;2416;288 +158;2416;464 +158;2416;544 +158;2416;560 +158;2416;608 +158;2416;656 +158;2416;672 +158;2416;688 +158;2416;704 +158;2416;720 +158;2416;736 +158;2416;784 +158;2416;800 +158;2416;832 +158;2416;848 +158;2416;864 +158;2416;912 +158;2416;944 +158;2416;960 +158;2416;1088 +158;2432;288 +158;2432;464 +158;2432;544 +158;2432;560 +158;2432;608 +158;2432;624 +158;2432;640 +158;2432;656 +158;2432;672 +158;2432;688 +158;2432;704 +158;2432;720 +158;2432;736 +158;2432;752 +158;2432;768 +158;2432;784 +158;2432;800 +158;2432;832 +158;2432;848 +158;2432;864 +158;2432;912 +158;2432;928 +158;2432;944 +158;2432;960 +158;2432;1088 +158;2448;288 +158;2448;464 +158;2448;544 +158;2448;560 +158;2448;608 +158;2448;624 +158;2448;640 +158;2448;656 +158;2448;672 +158;2448;688 +158;2448;704 +158;2448;720 +158;2448;736 +158;2448;752 +158;2448;768 +158;2448;784 +158;2448;800 +158;2448;832 +158;2448;848 +158;2448;864 +158;2448;912 +158;2448;928 +158;2448;944 +158;2448;960 +158;2448;1056 +158;2448;1072 +158;2448;1088 +158;2464;288 +158;2464;464 +158;2464;544 +158;2464;560 +158;2464;576 +158;2464;592 +158;2464;608 +158;2464;624 +158;2464;640 +158;2464;688 +158;2464;704 +158;2464;752 +158;2464;768 +158;2464;784 +158;2464;800 +158;2464;816 +158;2464;832 +158;2464;864 +158;2464;912 +158;2464;928 +158;2464;944 +158;2464;960 +158;2464;1056 +158;2464;1072 +158;2464;1088 +158;2464;1104 +158;2464;1120 +158;2464;1136 +158;2464;1152 +158;2464;1168 +158;2480;288 +158;2480;464 +158;2480;544 +158;2480;560 +158;2480;576 +158;2480;592 +158;2480;608 +158;2480;624 +158;2480;640 +158;2480;784 +158;2480;800 +158;2480;816 +158;2480;832 +158;2480;848 +158;2480;864 +158;2480;912 +158;2480;928 +158;2480;944 +158;2480;960 +158;2480;1056 +158;2480;1072 +158;2480;1088 +158;2480;1104 +158;2480;1120 +158;2480;1136 +158;2480;1152 +158;2480;1168 +158;2496;288 +158;2496;464 +158;2496;544 +158;2496;560 +158;2496;576 +158;2496;608 +158;2496;624 +158;2496;640 +158;2496;816 +158;2496;832 +158;2496;864 +158;2496;912 +158;2496;928 +158;2496;944 +158;2496;960 +158;2512;288 +158;2512;304 +158;2512;320 +158;2512;432 +158;2512;448 +158;2512;464 +158;2512;544 +158;2512;576 +158;2512;592 +158;2512;624 +158;2512;640 +158;2512;688 +158;2512;704 +158;2512;752 +158;2512;768 +158;2512;784 +158;2512;800 +158;2512;816 +158;2512;832 +158;2512;864 +158;2512;928 +158;2512;944 +158;2512;960 +158;2528;288 +158;2528;304 +158;2528;320 +158;2528;352 +158;2528;368 +158;2528;384 +158;2528;400 +158;2528;416 +158;2528;432 +158;2528;448 +158;2528;464 +158;2528;544 +158;2528;560 +158;2528;592 +158;2528;608 +158;2528;624 +158;2528;640 +158;2528;688 +158;2528;704 +158;2528;752 +158;2528;768 +158;2528;848 +158;2528;864 +158;2528;928 +158;2528;944 +158;2528;960 +158;2544;288 +158;2544;304 +158;2544;320 +158;2544;336 +158;2544;368 +158;2544;384 +158;2544;400 +158;2544;416 +158;2544;432 +158;2544;448 +158;2544;464 +158;2544;544 +158;2544;560 +158;2544;576 +158;2544;592 +158;2544;608 +158;2544;624 +158;2544;640 +158;2544;656 +158;2544;672 +158;2544;688 +158;2544;704 +158;2544;720 +158;2544;736 +158;2544;752 +158;2544;768 +158;2544;784 +158;2544;800 +158;2544;816 +158;2544;832 +158;2544;848 +158;2544;864 +158;2544;944 +158;2544;960 +114;1952;544;;;;;; +114;1952;560;;;;;; +114;1952;576;;;;;; +114;1952;592;;;;;; +114;1952;656;;;;;; +114;1952;672;;;;;; +114;1952;688;;;;;; +114;1952;704;;;;;; +114;1952;720;;;;;; +114;1952;784;;;;;; +114;1952;800;;;;;; +114;1952;816;;;;;; +114;1952;832;;;;;; +114;1952;848;;;;;; +114;1952;864;;;;;; +114;1952;880;;;;;; +114;1952;896;;;;;; +114;1952;912;;;;;; +114;1952;928;;;;;; +114;1968;544;;;;;; +114;1968;560;;;;;; +114;1968;592;;;;;; +114;1968;656;;;;;; +114;1968;672;;;;;; +114;1968;688;;;;;; +114;1968;704;;;;;; +114;1968;720;;;;;; +114;2000;544;;;;;; +114;2016;544;;;;;; +114;2032;576;;;;;; +114;2032;832;;;;;; +114;2032;848;;;;;; +114;2048;656;;;;;; +114;2048;672;;;;;; +114;2048;688;;;;;; +114;2048;832;;;;;; +114;2048;848;;;;;; +114;2096;928;;;;;; +114;2112;560;;;;;; +114;2112;656;;;;;; +114;2112;672;;;;;; +114;2128;688;;;;;; +114;2128;832;;;;;; +114;2128;848;;;;;; +114;2144;704;;;;;; +114;2160;864;;;;;; +114;2160;880;;;;;; +114;2160;896;;;;;; +114;2160;912;;;;;; +114;2160;928;;;;;; +114;2176;544;;;;;; +114;2176;560;;;;;; +114;2192;576;;;;;; +114;2192;832;;;;;; +114;2192;848;;;;;; +114;2192;864;;;;;; +114;2192;880;;;;;; +114;2192;896;;;;;; +114;2208;928;;;;;; +114;2208;944;;;;;; +114;2224;592;;;;;; +114;2304;816;;;;;; +114;2320;576;;;;;; +114;2320;592;;;;;; +114;2336;784;;;;;; +114;2336;800;;;;;; +114;2336;816;;;;;; +114;2336;832;;;;;; +114;2336;848;;;;;; +114;2352;832;;;;;; +114;2352;848;;;;;; +114;2352;864;;;;;; +114;2384;800;;;;;; +114;2432;608;;;;;; +114;2432;624;;;;;; +114;2432;640;;;;;; +114;2432;656;;;;;; +114;2432;672;;;;;; +114;2432;704;;;;;; +114;2432;720;;;;;; +114;2432;736;;;;;; +114;2432;752;;;;;; +114;2432;768;;;;;; +114;2432;832;;;;;; +114;2432;848;;;;;; +114;2432;928;;;;;; +114;2448;608;;;;;; +114;2448;624;;;;;; +114;2448;640;;;;;; +114;2448;656;;;;;; +114;2448;672;;;;;; +114;2448;704;;;;;; +114;2448;720;;;;;; +114;2448;736;;;;;; +114;2448;752;;;;;; +114;2448;768;;;;;; +114;2448;832;;;;;; +114;2448;848;;;;;; +114;2448;928;;;;;; +114;2448;944;;;;;; +114;2448;960;;;;;; +114;2448;976;;;;;; +114;2464;576;;;;;; +114;2464;592;;;;;; +114;2464;608;;;;;; +114;2464;624;;;;;; +114;2464;688;;;;;; +114;2464;752;;;;;; +114;2464;768;;;;;; +114;2464;928;;;;;; +114;2464;944;;;;;; +114;2464;960;;;;;; +114;2464;976;;;;;; +114;2480;576;;;;;; +114;2480;592;;;;;; +114;2480;608;;;;;; +114;2480;624;;;;;; +114;2480;912;;;;;; +114;2480;928;;;;;; +114;2480;944;;;;;; +114;2480;960;;;;;; +114;2480;976;;;;;; +114;2496;560;;;;;; +114;2496;608;;;;;; +114;2496;624;;;;;; +114;2496;912;;;;;; +114;2496;928;;;;;; +114;2496;944;;;;;; +114;2496;960;;;;;; +114;2512;624;;;;;; +114;2512;688;;;;;; +114;2512;752;;;;;; +114;2512;768;;;;;; +114;2512;784;;;;;; +114;2512;800;;;;;; +114;2512;816;;;;;; +114;2512;928;;;;;; +114;2512;944;;;;;; +114;2512;960;;;;;; +114;2528;544;;;;;; +114;2528;608;;;;;; +114;2528;624;;;;;; +114;2528;752;;;;;; +114;2528;848;;;;;; +114;2528;928;;;;;; +114;2528;944;;;;;; +114;2528;960;;;;;; +114;2544;544;;;;;; +114;2544;560;;;;;; +114;2544;576;;;;;; +114;2544;608;;;;;; +114;2544;624;;;;;; +114;2544;640;;;;;; +114;2544;656;;;;;; +114;2544;672;;;;;; +114;2544;704;;;;;; +114;2544;720;;;;;; +114;2544;736;;;;;; +114;2544;752;;;;;; +114;2544;768;;;;;; +114;2544;784;;;;;; +114;2544;800;;;;;; +114;2544;816;;;;;; +114;2544;832;;;;;; +114;2544;944;;;;;; +114;2544;960;;;;;; +110;1696;176;;;;;; +110;1696;192;;;;;; +110;1712;176;;;;;; +110;1712;192;;;;;; +110;1728;176;;;;;; +110;1728;192;;;;;; +110;1952;608;;;;;; +110;1952;624;;;;;; +110;1952;640;;;;;; +110;1968;480;;;;;; +110;1968;496;;;;;; +110;1968;512;;;;;; +110;1968;528;;;;;; +110;1968;608;;;;;; +110;1968;624;;;;;; +110;1968;640;;;;;; +110;1984;224;;;;;; +110;1984;240;;;;;; +110;1984;256;;;;;; +110;1984;272;;;;;; +110;1984;480;;;;;; +110;1984;496;;;;;; +110;1984;512;;;;;; +110;1984;528;;;;;; +110;2000;480;;;;;; +110;2000;496;;;;;; +110;2000;512;;;;;; +110;2000;528;;;;;; +110;2016;224;;;;;; +110;2016;240;;;;;; +110;2016;256;;;;;; +110;2016;272;;;;;; +110;2032;128;;;;;; +110;2032;144;;;;;; +110;2032;160;;;;;; +110;2032;176;;;;;; +110;2048;224;;;;;; +110;2048;240;;;;;; +110;2048;256;;;;;; +110;2048;272;;;;;; +110;2048;608;;;;;; +110;2048;624;;;;;; +110;2048;640;;;;;; +110;2064;608;;;;;; +110;2064;624;;;;;; +110;2064;640;;;;;; +110;2144;480;;;;;; +110;2144;496;;;;;; +110;2144;512;;;;;; +110;2144;528;;;;;; +110;2160;480;;;;;; +110;2160;496;;;;;; +110;2160;512;;;;;; +110;2160;528;;;;;; +110;2448;992;;;;;; +110;2448;1008;;;;;; +110;2448;1024;;;;;; +110;2448;1040;;;;;; +110;2464;992;;;;;; +110;2464;1008;;;;;; +110;2464;1024;;;;;; +110;2464;1040;;;;;; +110;2480;992;;;;;; +110;2480;1008;;;;;; +110;2480;1024;;;;;; +110;2480;1040;;;;;; +291;1712;184 +291;2016;248 +291;2032;152 +240;1792;160;ow_de4 +111;1968;784;;;;;; +111;1984;784;;;;;; +111;2000;784;;;;;; +111;2016;784;;;;;; +111;2032;784;;;;;; +111;2048;784;;;;;; +111;2064;784;;;;;; +111;2064;800;;;;;; +111;2064;816;;;;;; +111;2080;784;;;;;; +111;2080;800;;;;;; +111;2080;816;;;;;; +111;2096;784;;;;;; +111;2096;800;;;;;; +111;2096;816;;;;;; +111;2112;784;;;;;; +111;2112;800;;;;;; +111;2112;816;;;;;; +111;2128;784;;;;;; +111;2128;800;;;;;; +111;2128;816;;;;;; +111;2144;784;;;;;; +111;2144;800;;;;;; +111;2144;816;;;;;; +111;2144;832;;;;;; +111;2160;784;;;;;; +111;2160;800;;;;;; +111;2176;784;;;;;; +111;2192;784;;;;;; +111;2208;784;;;;;; +111;2208;832;;;;;; +111;2208;848;;;;;; +111;2208;864;;;;;; +111;2224;784;;;;;; +111;2224;832;;;;;; +111;2224;848;;;;;; +111;2224;864;;;;;; +111;2240;784;;;;;; +111;2240;832;;;;;; +111;2240;848;;;;;; +111;2240;864;;;;;; +111;2256;784;;;;;; +111;2256;800;;;;;; +111;2256;832;;;;;; +111;2256;848;;;;;; +111;2256;864;;;;;; +111;2272;800;;;;;; +111;2288;800;;;;;; +111;2288;864;;;;;; +111;2304;800;;;;;; +111;2304;864;;;;;; +111;2320;800;;;;;; +111;2320;864;;;;;; +111;2336;864;;;;;; +111;2352;784;;;;;; +111;2352;816;;;;;; +111;2368;784;;;;;; +111;2368;816;;;;;; +111;2368;832;;;;;; +111;2368;848;;;;;; +111;2384;784;;;;;; +111;2384;816;;;;;; +111;2384;832;;;;;; +111;2384;848;;;;;; +111;2400;784;;;;;; +111;2400;800;;;;;; +111;2400;832;;;;;; +111;2400;848;;;;;; +111;2416;784;;;;;; +111;2416;800;;;;;; +111;2416;832;;;;;; +111;2416;848;;;;;; +111;2416;864;;;;;; +111;2432;784;;;;;; +111;2432;800;;;;;; +111;2432;864;;;;;; +111;2448;784;;;;;; +111;2448;800;;;;;; +111;2448;864;;;;;; +111;2464;640;;;;;; +111;2464;704;;;;;; +111;2464;800;;;;;; +111;2464;832;;;;;; +111;2464;864;;;;;; +111;2480;640;;;;;; +111;2480;784;;;;;; +111;2480;816;;;;;; +111;2496;576;;;;;; +111;2496;640;;;;;; +111;2496;816;;;;;; +111;2496;832;;;;;; +111;2496;864;;;;;; +111;2512;576;;;;;; +111;2512;832;;;;;; +111;2512;864;;;;;; +111;2528;592;;;;;; +111;2528;688;;;;;; +111;2528;768;;;;;; +111;2528;864;;;;;; +111;2544;592;;;;;; +111;2544;688;;;;;; +111;2544;848;;;;;; +111;2544;864;;;;;; +113;1952;736;;;;;; +113;1952;944;;;;;; +113;1952;960;;;;;; +113;1968;576;;;;;; +113;1968;736;;;;;; +113;1968;864;;;;;; +113;1968;880;;;;;; +113;1968;896;;;;;; +113;1968;944;;;;;; +113;1968;960;;;;;; +113;1984;544;;;;;; +113;1984;560;;;;;; +113;1984;576;;;;;; +113;1984;592;;;;;; +113;1984;720;;;;;; +113;1984;736;;;;;; +113;1984;864;;;;;; +113;1984;880;;;;;; +113;1984;896;;;;;; +113;1984;944;;;;;; +113;1984;960;;;;;; +113;2000;560;;;;;; +113;2000;576;;;;;; +113;2000;592;;;;;; +113;2000;720;;;;;; +113;2000;736;;;;;; +113;2000;864;;;;;; +113;2000;880;;;;;; +113;2000;896;;;;;; +113;2000;944;;;;;; +113;2000;960;;;;;; +113;2016;560;;;;;; +113;2016;576;;;;;; +113;2016;592;;;;;; +113;2016;720;;;;;; +113;2016;736;;;;;; +113;2016;864;;;;;; +113;2016;880;;;;;; +113;2016;896;;;;;; +113;2016;944;;;;;; +113;2016;960;;;;;; +113;2032;560;;;;;; +113;2032;592;;;;;; +113;2032;736;;;;;; +113;2032;864;;;;;; +113;2032;880;;;;;; +113;2032;896;;;;;; +113;2032;944;;;;;; +113;2032;960;;;;;; +113;2048;560;;;;;; +113;2048;592;;;;;; +113;2048;720;;;;;; +113;2048;736;;;;;; +113;2048;864;;;;;; +113;2048;880;;;;;; +113;2048;896;;;;;; +113;2048;928;;;;;; +113;2048;944;;;;;; +113;2048;960;;;;;; +113;2064;560;;;;;; +113;2064;576;;;;;; +113;2064;592;;;;;; +113;2064;656;;;;;; +113;2064;672;;;;;; +113;2064;688;;;;;; +113;2064;704;;;;;; +113;2064;720;;;;;; +113;2064;864;;;;;; +113;2064;880;;;;;; +113;2064;896;;;;;; +113;2064;928;;;;;; +113;2064;944;;;;;; +113;2064;960;;;;;; +113;2080;560;;;;;; +113;2080;576;;;;;; +113;2080;592;;;;;; +113;2080;656;;;;;; +113;2080;672;;;;;; +113;2080;688;;;;;; +113;2080;704;;;;;; +113;2080;720;;;;;; +113;2080;864;;;;;; +113;2080;880;;;;;; +113;2080;896;;;;;; +113;2080;928;;;;;; +113;2080;944;;;;;; +113;2080;960;;;;;; +113;2096;560;;;;;; +113;2096;576;;;;;; +113;2096;592;;;;;; +113;2096;656;;;;;; +113;2096;672;;;;;; +113;2096;688;;;;;; +113;2096;704;;;;;; +113;2096;720;;;;;; +113;2096;864;;;;;; +113;2096;880;;;;;; +113;2096;896;;;;;; +113;2096;944;;;;;; +113;2096;960;;;;;; +113;2112;576;;;;;; +113;2112;592;;;;;; +113;2112;688;;;;;; +113;2112;704;;;;;; +113;2112;720;;;;;; +113;2112;864;;;;;; +113;2112;880;;;;;; +113;2112;896;;;;;; +113;2112;912;;;;;; +113;2112;944;;;;;; +113;2112;960;;;;;; +113;2128;544;;;;;; +113;2128;576;;;;;; +113;2128;592;;;;;; +113;2128;704;;;;;; +113;2128;720;;;;;; +113;2128;736;;;;;; +113;2128;864;;;;;; +113;2128;880;;;;;; +113;2128;896;;;;;; +113;2128;912;;;;;; +113;2128;944;;;;;; +113;2128;960;;;;;; +113;2144;544;;;;;; +113;2144;560;;;;;; +113;2144;576;;;;;; +113;2144;592;;;;;; +113;2144;720;;;;;; +113;2144;736;;;;;; +113;2144;864;;;;;; +113;2144;880;;;;;; +113;2144;896;;;;;; +113;2144;912;;;;;; +113;2144;944;;;;;; +113;2144;960;;;;;; +113;2160;544;;;;;; +113;2160;560;;;;;; +113;2160;576;;;;;; +113;2160;592;;;;;; +113;2160;704;;;;;; +113;2160;720;;;;;; +113;2160;736;;;;;; +113;2160;944;;;;;; +113;2160;960;;;;;; +113;2176;576;;;;;; +113;2176;592;;;;;; +113;2176;704;;;;;; +113;2176;720;;;;;; +113;2176;736;;;;;; +113;2176;848;;;;;; +113;2176;944;;;;;; +113;2176;960;;;;;; +113;2192;592;;;;;; +113;2192;720;;;;;; +113;2192;736;;;;;; +113;2192;912;;;;;; +113;2192;944;;;;;; +113;2192;960;;;;;; +113;2208;592;;;;;; +113;2208;704;;;;;; +113;2208;720;;;;;; +113;2208;736;;;;;; +113;2208;912;;;;;; +113;2208;960;;;;;; +113;2224;608;;;;;; +113;2224;656;;;;;; +113;2224;672;;;;;; +113;2224;688;;;;;; +113;2224;704;;;;;; +113;2224;720;;;;;; +113;2224;736;;;;;; +113;2224;912;;;;;; +113;2224;928;;;;;; +113;2224;960;;;;;; +113;2240;576;;;;;; +113;2240;592;;;;;; +113;2240;608;;;;;; +113;2240;656;;;;;; +113;2240;672;;;;;; +113;2240;688;;;;;; +113;2240;704;;;;;; +113;2240;720;;;;;; +113;2240;736;;;;;; +113;2240;912;;;;;; +113;2240;928;;;;;; +113;2240;960;;;;;; +113;2256;576;;;;;; +113;2256;592;;;;;; +113;2256;608;;;;;; +113;2256;656;;;;;; +113;2256;672;;;;;; +113;2256;688;;;;;; +113;2256;912;;;;;; +113;2256;928;;;;;; +113;2256;960;;;;;; +113;2272;576;;;;;; +113;2272;592;;;;;; +113;2272;608;;;;;; +113;2272;656;;;;;; +113;2272;672;;;;;; +113;2272;832;;;;;; +113;2272;912;;;;;; +113;2272;928;;;;;; +113;2272;960;;;;;; +113;2288;544;;;;;; +113;2288;560;;;;;; +113;2288;576;;;;;; +113;2288;592;;;;;; +113;2288;608;;;;;; +113;2288;656;;;;;; +113;2288;672;;;;;; +113;2288;688;;;;;; +113;2288;832;;;;;; +113;2288;912;;;;;; +113;2288;960;;;;;; +113;2304;544;;;;;; +113;2304;560;;;;;; +113;2304;576;;;;;; +113;2304;592;;;;;; +113;2304;608;;;;;; +113;2304;656;;;;;; +113;2304;672;;;;;; +113;2304;688;;;;;; +113;2304;832;;;;;; +113;2304;912;;;;;; +113;2304;944;;;;;; +113;2304;960;;;;;; +113;2320;544;;;;;; +113;2320;560;;;;;; +113;2320;608;;;;;; +113;2320;656;;;;;; +113;2320;672;;;;;; +113;2320;688;;;;;; +113;2320;832;;;;;; +113;2320;912;;;;;; +113;2320;944;;;;;; +113;2320;960;;;;;; +113;2336;544;;;;;; +113;2336;560;;;;;; +113;2336;608;;;;;; +113;2336;656;;;;;; +113;2336;672;;;;;; +113;2336;688;;;;;; +113;2336;704;;;;;; +113;2336;720;;;;;; +113;2336;912;;;;;; +113;2336;944;;;;;; +113;2352;544;;;;;; +113;2352;560;;;;;; +113;2352;608;;;;;; +113;2352;656;;;;;; +113;2352;672;;;;;; +113;2352;704;;;;;; +113;2352;720;;;;;; +113;2352;912;;;;;; +113;2352;944;;;;;; +113;2368;544;;;;;; +113;2368;560;;;;;; +113;2368;608;;;;;; +113;2368;656;;;;;; +113;2368;704;;;;;; +113;2368;736;;;;;; +113;2368;912;;;;;; +113;2368;944;;;;;; +113;2384;544;;;;;; +113;2384;560;;;;;; +113;2384;608;;;;;; +113;2384;656;;;;;; +113;2384;688;;;;;; +113;2384;704;;;;;; +113;2384;736;;;;;; +113;2384;912;;;;;; +113;2384;944;;;;;; +113;2384;960;;;;;; +113;2400;544;;;;;; +113;2400;560;;;;;; +113;2400;608;;;;;; +113;2400;656;;;;;; +113;2400;672;;;;;; +113;2400;688;;;;;; +113;2400;704;;;;;; +113;2400;720;;;;;; +113;2400;736;;;;;; +113;2400;912;;;;;; +113;2400;944;;;;;; +113;2400;960;;;;;; +113;2416;544;;;;;; +113;2416;560;;;;;; +113;2416;608;;;;;; +113;2416;656;;;;;; +113;2416;672;;;;;; +113;2416;688;;;;;; +113;2416;704;;;;;; +113;2416;720;;;;;; +113;2416;736;;;;;; +113;2416;912;;;;;; +113;2416;944;;;;;; +113;2416;960;;;;;; +113;2432;544;;;;;; +113;2432;560;;;;;; +113;2432;688;;;;;; +113;2432;912;;;;;; +113;2432;944;;;;;; +113;2432;960;;;;;; +113;2448;544;;;;;; +113;2448;560;;;;;; +113;2448;688;;;;;; +113;2448;912;;;;;; +113;2464;544;;;;;; +113;2464;560;;;;;; +113;2464;912;;;;;; +113;2480;544;;;;;; +113;2480;560;;;;;; +113;2496;544;;;;;; +113;2512;544;;;;;; +113;2512;640;;;;;; +113;2512;704;;;;;; +113;2528;560;;;;;; +113;2528;640;;;;;; +113;2528;704;;;;;; +112;1968;912;;;;;; +112;1968;928;;;;;; +112;1984;912;;;;;; +112;1984;928;;;;;; +112;2000;912;;;;;; +112;2000;928;;;;;; +112;2016;912;;;;;; +112;2016;928;;;;;; +112;2032;800;;;;;; +112;2032;816;;;;;; +112;2032;912;;;;;; +112;2032;928;;;;;; +112;2048;800;;;;;; +112;2048;816;;;;;; +112;2240;800;;;;;; +112;2256;704;;;;;; +112;2256;720;;;;;; +112;2256;736;;;;;; +112;2272;688;;;;;; +112;2272;848;;;;;; +112;2272;864;;;;;; +112;2320;816;;;;;; +112;2336;736;;;;;; +112;2352;688;;;;;; +112;2368;672;;;;;; +112;2368;720;;;;;; +112;2400;864;;;;;; +112;2464;784;;;;;; +112;2464;816;;;;;; +112;2480;800;;;;;; +112;2480;832;;;;;; +112;2480;848;;;;;; +112;2480;864;;;;;; +112;2512;592;;;;;; +98;16;2000;;;;;; +98;80;2000;;;;;; +98;96;2000;;;;;; +98;112;2000;;;;;; +98;128;2000;;;;;; +98;144;2000;;;;;; +98;160;2000;;;;;; +98;176;2000;;;;;; +98;192;2000;;;;;; +98;208;2000;;;;;; +98;224;2000;;;;;; +98;240;2000;;;;;; +98;256;2000;;;;;; +98;272;2000;;;;;; +98;288;2000;;;;;; +98;304;2000;;;;;; +98;368;2000;;;;;; +98;384;2000;;;;;; +98;400;2000;;;;;; +98;416;2000;;;;;; +98;432;2000;;;;;; +98;448;2000;;;;;; +98;464;2000;;;;;; +98;480;2000;;;;;; +98;496;2000;;;;;; +98;512;2000;;;;;; +98;528;2000;;;;;; +98;544;2000;;;;;; +98;560;2000;;;;;; +98;576;2000;;;;;; +98;592;2000;;;;;; +98;608;2000;;;;;; +98;624;2000;;;;;; +98;640;2000;;;;;; +98;656;2000;;;;;; +98;672;2000;;;;;; +98;688;2000;;;;;; +98;704;2000;;;;;; +98;720;2000;;;;;; +98;736;2000;;;;;; +98;752;2000;;;;;; +98;768;2000;;;;;; +98;784;2000;;;;;; +98;832;2000;;;;;; +98;848;2000;;;;;; +98;864;2000;;;;;; +98;880;2000;;;;;; +98;896;2000;;;;;; +98;912;2000;;;;;; +98;928;2000;;;;;; +98;944;2000;;;;;; +99;-16;1984;;;;;; +99;-16;2000;;;;;; +99;0;1968;;;;;; +99;0;1984;;;;;; +99;0;2000;;;;;; +99;0;2016;;;;;; +99;0;2032;;;;;; +99;16;2016;;;;;; +99;16;2032;;;;;; +99;16;2048;;;;;; +99;32;2032;;;;;; +99;32;2048;;;;;; +99;48;2032;;;;;; +99;48;2048;;;;;; +99;64;2032;;;;;; +99;64;2048;;;;;; +99;80;2016;;;;;; +99;80;2032;;;;;; +99;80;2048;;;;;; +99;96;2016;;;;;; +99;96;2032;;;;;; +99;112;2016;;;;;; +99;112;2032;;;;;; +99;128;2016;;;;;; +99;128;2032;;;;;; +99;144;2016;;;;;; +99;144;2032;;;;;; +99;160;2016;;;;;; +99;160;2032;;;;;; +99;176;2016;;;;;; +99;176;2032;;;;;; +99;192;2016;;;;;; +99;192;2032;;;;;; +99;208;2016;;;;;; +99;208;2032;;;;;; +99;224;2016;;;;;; +99;224;2032;;;;;; +99;240;2016;;;;;; +99;240;2032;;;;;; +99;256;2016;;;;;; +99;256;2032;;;;;; +99;272;2016;;;;;; +99;272;2032;;;;;; +99;288;2016;;;;;; +99;288;2032;;;;;; +99;288;2048;;;;;; +99;304;2016;;;;;; +99;304;2032;;;;;; +99;304;2048;;;;;; +99;304;2064;;;;;; +99;320;2048;;;;;; +99;320;2064;;;;;; +99;336;2048;;;;;; +99;336;2064;;;;;; +99;352;2048;;;;;; +99;352;2064;;;;;; +99;368;2016;;;;;; +99;368;2032;;;;;; +99;368;2048;;;;;; +99;368;2064;;;;;; +99;384;2016;;;;;; +99;384;2032;;;;;; +99;384;2048;;;;;; +99;400;2016;;;;;; +99;400;2032;;;;;; +99;416;2016;;;;;; +99;416;2032;;;;;; +99;432;2016;;;;;; +99;432;2032;;;;;; +99;448;2016;;;;;; +99;448;2032;;;;;; +99;464;2016;;;;;; +99;464;2032;;;;;; +99;480;2016;;;;;; +99;480;2032;;;;;; +99;496;2016;;;;;; +99;496;2032;;;;;; +99;512;2016;;;;;; +99;512;2032;;;;;; +99;528;2016;;;;;; +99;528;2032;;;;;; +99;544;2016;;;;;; +99;544;2032;;;;;; +99;560;2016;;;;;; +99;560;2032;;;;;; +99;576;2016;;;;;; +99;576;2032;;;;;; +99;592;2016;;;;;; +99;592;2032;;;;;; +99;608;2016;;;;;; +99;608;2032;;;;;; +99;624;2016;;;;;; +99;624;2032;;;;;; +99;640;2016;;;;;; +99;640;2032;;;;;; +99;656;2016;;;;;; +99;656;2032;;;;;; +99;672;2016;;;;;; +99;672;2032;;;;;; +99;688;2016;;;;;; +99;688;2032;;;;;; +99;704;2016;;;;;; +99;704;2032;;;;;; +99;720;2016;;;;;; +99;720;2032;;;;;; +99;736;2016;;;;;; +99;736;2032;;;;;; +99;752;2016;;;;;; +99;752;2032;;;;;; +99;768;2016;;;;;; +99;768;2032;;;;;; +99;768;2048;;;;;; +99;768;2064;;;;;; +99;784;2016;;;;;; +99;784;2032;;;;;; +99;784;2048;;;;;; +99;784;2064;;;;;; +99;800;2032;;;;;; +99;800;2048;;;;;; +99;800;2064;;;;;; +99;816;2032;;;;;; +99;816;2048;;;;;; +99;816;2064;;;;;; +99;832;2016;;;;;; +99;832;2032;;;;;; +99;832;2048;;;;;; +99;832;2064;;;;;; +99;848;2016;;;;;; +99;848;2032;;;;;; +99;848;2048;;;;;; +99;864;2016;;;;;; +99;864;2032;;;;;; +99;880;2016;;;;;; +99;880;2032;;;;;; +99;896;2016;;;;;; +99;896;2032;;;;;; +99;912;2016;;;;;; +99;912;2032;;;;;; +99;928;2016;;;;;; +99;928;2032;;;;;; +99;944;2016;;;;;; +99;944;2032;;;;;; +99;944;2048;;;;;; +99;960;2048;;;;;; +103;-32;928;;;;;; +103;-32;944;;;;;; +103;-32;960;;;;;; +103;-32;976;;;;;; +103;-32;992;;;;;; +103;-32;1008;;;;;; +103;-32;1024;;;;;; +103;-32;1040;;;;;; +103;-32;1056;;;;;; +103;-32;1072;;;;;; +103;-32;1088;;;;;; +103;-32;1104;;;;;; +103;-16;208;;;;;; +103;-16;224;;;;;; +103;-16;240;;;;;; +103;-16;256;;;;;; +103;-16;272;;;;;; +103;-16;288;;;;;; +103;-16;304;;;;;; +103;-16;320;;;;;; +103;-16;336;;;;;; +103;-16;400;;;;;; +103;-16;416;;;;;; +103;-16;432;;;;;; +103;-16;448;;;;;; +103;-16;464;;;;;; +103;-16;480;;;;;; +103;-16;496;;;;;; +103;-16;512;;;;;; +103;-16;528;;;;;; +103;-16;544;;;;;; +103;-16;560;;;;;; +103;-16;576;;;;;; +103;-16;592;;;;;; +103;-16;608;;;;;; +103;-16;624;;;;;; +103;-16;640;;;;;; +103;-16;656;;;;;; +103;-16;672;;;;;; +103;-16;688;;;;;; +103;-16;704;;;;;; +103;-16;720;;;;;; +103;-16;736;;;;;; +103;-16;752;;;;;; +103;-16;768;;;;;; +103;-16;784;;;;;; +103;-16;800;;;;;; +103;-16;816;;;;;; +103;-16;832;;;;;; +103;-16;848;;;;;; +103;-16;864;;;;;; +103;-16;880;;;;;; +103;-16;896;;;;;; +103;-16;912;;;;;; +103;-16;928;;;;;; +103;-16;944;;;;;; +103;-16;960;;;;;; +103;-16;976;;;;;; +103;-16;992;;;;;; +103;-16;1008;;;;;; +103;-16;1024;;;;;; +103;-16;1040;;;;;; +103;-16;1056;;;;;; +103;-16;1072;;;;;; +103;-16;1088;;;;;; +103;-16;1104;;;;;; +103;-16;1120;;;;;; +103;-16;1136;;;;;; +103;-16;1152;;;;;; +103;-16;1536;;;;;; +103;-16;1552;;;;;; +103;-16;1568;;;;;; +103;-16;1584;;;;;; +103;-16;1600;;;;;; +103;-16;1616;;;;;; +103;-16;1632;;;;;; +103;-16;1648;;;;;; +103;-16;1664;;;;;; +103;-16;1680;;;;;; +103;-16;1696;;;;;; +103;-16;1712;;;;;; +103;-16;1728;;;;;; +103;-16;1744;;;;;; +103;-16;1760;;;;;; +103;-16;1776;;;;;; +103;-16;1792;;;;;; +103;-16;1808;;;;;; +103;-16;1824;;;;;; +103;-16;1840;;;;;; +103;-16;1856;;;;;; +103;-16;1872;;;;;; +103;-16;1888;;;;;; +103;-16;1904;;;;;; +103;-16;1920;;;;;; +103;-16;1936;;;;;; +103;-16;1952;;;;;; +103;0;192;;;;;; +103;0;208;;;;;; +103;0;224;;;;;; +103;0;240;;;;;; +103;0;256;;;;;; +103;0;272;;;;;; +103;0;288;;;;;; +103;0;304;;;;;; +103;0;320;;;;;; +103;0;336;;;;;; +103;0;352;;;;;; +103;0;368;;;;;; +103;0;384;;;;;; +103;0;400;;;;;; +103;0;416;;;;;; +103;0;432;;;;;; +103;0;448;;;;;; +103;0;464;;;;;; +103;0;480;;;;;; +103;0;496;;;;;; +103;0;512;;;;;; +103;0;528;;;;;; +103;0;544;;;;;; +103;0;560;;;;;; +103;0;576;;;;;; +103;0;592;;;;;; +103;0;608;;;;;; +103;0;624;;;;;; +103;0;640;;;;;; +103;0;656;;;;;; +103;0;672;;;;;; +103;0;688;;;;;; +103;0;704;;;;;; +103;0;720;;;;;; +103;0;736;;;;;; +103;0;752;;;;;; +103;0;768;;;;;; +103;0;784;;;;;; +103;0;800;;;;;; +103;0;816;;;;;; +103;0;832;;;;;; +103;0;848;;;;;; +103;0;864;;;;;; +103;0;880;;;;;; +103;0;896;;;;;; +103;0;912;;;;;; +103;0;928;;;;;; +103;0;944;;;;;; +103;0;1088;;;;;; +103;0;1104;;;;;; +103;0;1120;;;;;; +103;0;1136;;;;;; +103;0;1152;;;;;; +103;0;1168;;;;;; +103;0;1184;;;;;; +103;0;1200;;;;;; +103;0;1216;;;;;; +103;0;1232;;;;;; +103;0;1248;;;;;; +103;0;1264;;;;;; +103;0;1280;;;;;; +103;0;1296;;;;;; +103;0;1312;;;;;; +103;0;1328;;;;;; +103;0;1344;;;;;; +103;0;1360;;;;;; +103;0;1376;;;;;; +103;0;1392;;;;;; +103;0;1408;;;;;; +103;0;1424;;;;;; +103;0;1440;;;;;; +103;0;1456;;;;;; +103;0;1472;;;;;; +103;0;1488;;;;;; +103;0;1504;;;;;; +103;0;1520;;;;;; +103;0;1536;;;;;; +103;0;1552;;;;;; +103;0;1568;;;;;; +103;0;1584;;;;;; +103;0;1600;;;;;; +103;0;1616;;;;;; +103;0;1632;;;;;; +103;0;1648;;;;;; +103;0;1664;;;;;; +103;0;1680;;;;;; +103;0;1696;;;;;; +103;0;1712;;;;;; +103;0;1728;;;;;; +103;0;1744;;;;;; +103;0;1760;;;;;; +103;0;1776;;;;;; +103;0;1792;;;;;; +103;0;1808;;;;;; +103;0;1824;;;;;; +103;0;1840;;;;;; +103;0;1856;;;;;; +103;0;1872;;;;;; +103;0;1888;;;;;; +103;0;1904;;;;;; +103;0;1920;;;;;; +103;0;1936;;;;;; +103;0;1952;;;;;; +103;16;336;;;;;; +103;16;352;;;;;; +103;16;368;;;;;; +103;16;384;;;;;; +103;16;400;;;;;; +103;16;1136;;;;;; +103;16;1152;;;;;; +103;16;1168;;;;;; +103;16;1184;;;;;; +103;16;1200;;;;;; +103;16;1216;;;;;; +103;16;1232;;;;;; +103;16;1248;;;;;; +103;16;1264;;;;;; +103;16;1280;;;;;; +103;16;1296;;;;;; +103;16;1312;;;;;; +103;16;1328;;;;;; +103;16;1344;;;;;; +103;16;1360;;;;;; +103;16;1376;;;;;; +103;16;1392;;;;;; +103;16;1408;;;;;; +103;16;1424;;;;;; +103;16;1440;;;;;; +103;16;1456;;;;;; +103;16;1472;;;;;; +103;16;1488;;;;;; +103;16;1504;;;;;; +103;16;1520;;;;;; +103;16;1536;;;;;; +103;16;1552;;;;;; +103;992;2064;;;;;; +103;1008;2048;;;;;; +103;1008;2064;;;;;; +103;1024;2048;;;;;; +103;1024;2064;;;;;; +103;1040;2048;;;;;; +103;1040;2064;;;;;; +103;1056;2048;;;;;; +103;1056;2064;;;;;; +103;1072;2048;;;;;; +103;1072;2064;;;;;; +103;1072;2080;;;;;; +103;1088;2048;;;;;; +103;1088;2064;;;;;; +103;1088;2080;;;;;; +103;1104;2048;;;;;; +103;1104;2064;;;;;; +103;1104;2080;;;;;; +103;1120;2048;;;;;; +103;1120;2064;;;;;; +103;1120;2080;;;;;; +103;1136;2048;;;;;; +103;1136;2064;;;;;; +103;1136;2080;;;;;; +103;1152;2048;;;;;; +103;1152;2064;;;;;; +103;1152;2080;;;;;; +103;1168;2048;;;;;; +103;1168;2064;;;;;; +103;1168;2080;;;;;; +103;1184;2048;;;;;; +103;1184;2064;;;;;; +103;1184;2080;;;;;; +103;1200;2048;;;;;; +103;1200;2064;;;;;; +103;1200;2080;;;;;; +103;1216;2048;;;;;; +103;1216;2064;;;;;; +103;1216;2080;;;;;; +103;1232;2048;;;;;; +103;1232;2064;;;;;; +103;1232;2080;;;;;; +103;1248;2048;;;;;; +103;1248;2064;;;;;; +103;1248;2080;;;;;; +103;1264;2048;;;;;; +103;1264;2064;;;;;; +103;1264;2080;;;;;; +103;1280;2048;;;;;; +103;1280;2064;;;;;; +103;1296;2048;;;;;; +103;1296;2064;;;;;; +103;1312;2048;;;;;; +103;1312;2064;;;;;; +103;1328;2048;;;;;; +103;1328;2064;;;;;; +103;1344;2048;;;;;; +103;1344;2064;;;;;; +103;1360;2048;;;;;; +103;1360;2064;;;;;; +103;1376;2048;;;;;; +103;1376;2064;;;;;; +103;1392;2048;;;;;; +103;1392;2064;;;;;; +103;1408;2048;;;;;; +103;1408;2064;;;;;; +103;1408;2080;;;;;; +103;1424;2064;;;;;; +103;1424;2080;;;;;; +103;1440;2064;;;;;; +103;1440;2080;;;;;; +103;1456;2064;;;;;; +103;1456;2080;;;;;; +103;1472;2064;;;;;; +103;1472;2080;;;;;; +103;1488;2064;;;;;; +103;1488;2080;;;;;; +103;1504;2064;;;;;; +103;1504;2080;;;;;; +103;1520;2064;;;;;; +103;1520;2080;;;;;; +103;1536;2064;;;;;; +103;1536;2080;;;;;; +103;1552;2064;;;;;; +103;1552;2080;;;;;; +103;1568;2064;;;;;; +103;1568;2080;;;;;; +103;1584;2064;;;;;; +103;1584;2080;;;;;; +103;1600;2048;;;;;; +103;1600;2064;;;;;; +103;1616;2048;;;;;; +103;1616;2064;;;;;; +103;1632;2048;;;;;; +103;1632;2064;;;;;; +103;1648;2048;;;;;; +103;1648;2064;;;;;; +103;1664;2048;;;;;; +103;1664;2064;;;;;; +103;1664;2080;;;;;; +103;1680;2048;;;;;; +103;1680;2064;;;;;; +103;1680;2080;;;;;; +103;1696;2048;;;;;; +103;1696;2064;;;;;; +103;1696;2080;;;;;; +103;1712;2048;;;;;; +103;1712;2064;;;;;; +103;1728;2048;;;;;; +103;1728;2064;;;;;; +103;1744;2048;;;;;; +103;1744;2064;;;;;; +103;1760;2048;;;;;; +103;1760;2064;;;;;; +103;1776;2048;;;;;; +103;1776;2064;;;;;; +103;1792;2048;;;;;; +103;1792;2064;;;;;; +103;1808;2048;;;;;; +103;1808;2064;;;;;; +103;1824;2048;;;;;; +103;1824;2064;;;;;; +103;1840;2048;;;;;; +103;1840;2064;;;;;; +103;1856;2048;;;;;; +103;1856;2064;;;;;; +103;1872;2048;;;;;; +103;1872;2064;;;;;; +103;1888;2048;;;;;; +103;1888;2064;;;;;; +103;1904;2048;;;;;; +103;1904;2064;;;;;; +103;1920;2048;;;;;; +103;1920;2064;;;;;; +103;1936;2048;;;;;; +103;1936;2064;;;;;; +103;1952;2048;;;;;; +103;1952;2064;;;;;; +103;1952;2080;;;;;; +103;1968;2048;;;;;; +103;1968;2064;;;;;; +103;1968;2080;;;;;; +103;1984;2048;;;;;; +103;1984;2064;;;;;; +103;1984;2080;;;;;; +103;2000;2048;;;;;; +103;2000;2064;;;;;; +103;2000;2080;;;;;; +103;2016;2048;;;;;; +103;2016;2064;;;;;; +103;2016;2080;;;;;; +103;2032;2048;;;;;; +103;2032;2064;;;;;; +103;2032;2080;;;;;; +103;2048;2048;;;;;; +103;2048;2064;;;;;; +103;2048;2080;;;;;; +103;2064;2048;;;;;; +103;2064;2064;;;;;; +103;2064;2080;;;;;; +103;2080;2048;;;;;; +103;2080;2064;;;;;; +103;2080;2080;;;;;; +103;2096;2048;;;;;; +103;2096;2064;;;;;; +103;2096;2080;;;;;; +103;2112;2048;;;;;; +103;2112;2064;;;;;; +103;2112;2080;;;;;; +103;2128;2048;;;;;; +103;2128;2064;;;;;; +103;2128;2080;;;;;; +103;2144;2048;;;;;; +103;2144;2064;;;;;; +103;2144;2080;;;;;; +103;2160;2048;;;;;; +103;2160;2064;;;;;; +103;2160;2080;;;;;; +103;2176;2048;;;;;; +103;2176;2064;;;;;; +103;2192;2048;;;;;; +103;2208;2048;;;;;; +103;2224;2048;;;;;; +103;2240;2048;;;;;; +103;2256;2048;;;;;; +103;2272;2048;;;;;; +103;2288;2048;;;;;; +103;2304;2048;;;;;; +103;2320;2048;;;;;; +103;2336;2048;;;;;; +103;2352;2048;;;;;; +103;2368;2048;;;;;; +103;2384;2048;;;;;; +103;2400;2048;;;;;; +103;2416;2048;;;;;; +103;2432;2048;;;;;; +103;2432;2064;;;;;; +103;2448;2048;;;;;; +103;2448;2064;;;;;; +103;2464;2048;;;;;; +103;2464;2064;;;;;; +103;2464;2080;;;;;; +103;2480;2048;;;;;; +103;2480;2064;;;;;; +103;2480;2080;;;;;; +103;2496;2048;;;;;; +103;2496;2064;;;;;; +103;2496;2080;;;;;; +103;2512;2048;;;;;; +103;2512;2064;;;;;; +103;2512;2080;;;;;; +103;2528;2048;;;;;; +103;2528;2064;;;;;; +103;2528;2080;;;;;; +103;2544;2048;;;;;; +103;2544;2064;;;;;; +103;2544;2080;;;;;; +103;2560;240;;;;;; +103;2560;1072;;;;;; +103;2560;1088;;;;;; +103;2560;1104;;;;;; +103;2560;1120;;;;;; +103;2560;1136;;;;;; +103;2560;1152;;;;;; +103;2560;1168;;;;;; +103;2560;1184;;;;;; +103;2560;1200;;;;;; +103;2560;1216;;;;;; +103;2560;1232;;;;;; +103;2560;1248;;;;;; +103;2560;1264;;;;;; +103;2560;1280;;;;;; +103;2560;1296;;;;;; +103;2560;1312;;;;;; +103;2560;1328;;;;;; +103;2560;1344;;;;;; +103;2560;2048;;;;;; +103;2560;2064;;;;;; +103;2576;256;;;;;; +103;2576;272;;;;;; +103;2576;288;;;;;; +103;2576;304;;;;;; +103;2576;320;;;;;; +103;2576;336;;;;;; +103;2576;352;;;;;; +103;2576;368;;;;;; +103;2576;384;;;;;; +103;2576;400;;;;;; +103;2576;416;;;;;; +103;2576;432;;;;;; +103;2576;448;;;;;; +103;2576;464;;;;;; +103;2576;480;;;;;; +103;2576;496;;;;;; +103;2576;512;;;;;; +103;2576;528;;;;;; +103;2576;544;;;;;; +103;2576;560;;;;;; +103;2576;576;;;;;; +103;2576;592;;;;;; +103;2576;608;;;;;; +103;2576;624;;;;;; +103;2576;640;;;;;; +103;2576;656;;;;;; +103;2576;672;;;;;; +103;2576;688;;;;;; +103;2576;704;;;;;; +103;2576;720;;;;;; +103;2576;736;;;;;; +103;2576;752;;;;;; +103;2576;768;;;;;; +103;2576;784;;;;;; +103;2576;800;;;;;; +103;2576;816;;;;;; +103;2576;832;;;;;; +103;2576;848;;;;;; +103;2576;864;;;;;; +103;2576;880;;;;;; +103;2576;896;;;;;; +103;2576;912;;;;;; +103;2576;928;;;;;; +103;2576;944;;;;;; +103;2576;960;;;;;; +103;2576;976;;;;;; +103;2576;992;;;;;; +103;2576;1008;;;;;; +103;2576;1024;;;;;; +103;2576;1040;;;;;; +103;2576;1056;;;;;; +103;2576;1072;;;;;; +103;2576;1088;;;;;; +103;2576;1104;;;;;; +103;2576;1120;;;;;; +103;2576;1136;;;;;; +103;2576;1152;;;;;; +103;2576;1168;;;;;; +103;2576;1184;;;;;; +103;2576;1200;;;;;; +103;2576;1216;;;;;; +103;2576;1232;;;;;; +103;2576;1248;;;;;; +103;2576;1264;;;;;; +103;2576;1280;;;;;; +103;2576;1296;;;;;; +103;2576;1312;;;;;; +103;2576;1328;;;;;; +103;2576;1344;;;;;; +103;2576;1360;;;;;; +103;2576;1376;;;;;; +103;2576;1392;;;;;; +103;2576;1408;;;;;; +103;2576;1424;;;;;; +103;2576;1440;;;;;; +103;2576;1456;;;;;; +103;2576;1472;;;;;; +103;2576;1488;;;;;; +103;2576;1504;;;;;; +103;2576;1520;;;;;; +103;2576;1536;;;;;; +103;2576;1552;;;;;; +103;2576;1568;;;;;; +103;2576;1584;;;;;; +103;2576;1600;;;;;; +103;2576;1616;;;;;; +103;2576;1632;;;;;; +103;2576;1648;;;;;; +103;2576;1664;;;;;; +103;2576;1680;;;;;; +103;2576;1696;;;;;; +103;2576;1712;;;;;; +103;2576;1728;;;;;; +103;2576;1744;;;;;; +103;2576;1760;;;;;; +103;2576;1776;;;;;; +103;2576;1792;;;;;; +103;2576;1808;;;;;; +103;2576;1824;;;;;; +103;2576;1840;;;;;; +103;2576;1856;;;;;; +103;2576;1872;;;;;; +103;2576;1888;;;;;; +103;2576;1904;;;;;; +103;2576;1920;;;;;; +103;2576;1936;;;;;; +103;2576;1952;;;;;; +103;2576;1968;;;;;; +103;2576;1984;;;;;; +103;2576;2000;;;;;; +103;2576;2016;;;;;; +103;2576;2032;;;;;; +103;2576;2048;;;;;; +103;2592;272;;;;;; +103;2592;288;;;;;; +103;2592;304;;;;;; +103;2592;320;;;;;; +103;2592;336;;;;;; +103;2592;352;;;;;; +103;2592;368;;;;;; +103;2592;384;;;;;; +103;2592;400;;;;;; +103;2592;416;;;;;; +103;2592;432;;;;;; +103;2592;448;;;;;; +103;2592;464;;;;;; +103;2592;480;;;;;; +103;2592;496;;;;;; +103;2592;512;;;;;; +103;2592;528;;;;;; +103;2592;544;;;;;; +103;2592;560;;;;;; +103;2592;576;;;;;; +103;2592;592;;;;;; +103;2592;608;;;;;; +103;2592;624;;;;;; +103;2592;640;;;;;; +103;2592;656;;;;;; +103;2592;672;;;;;; +103;2592;688;;;;;; +103;2592;704;;;;;; +103;2592;720;;;;;; +103;2592;736;;;;;; +103;2592;752;;;;;; +103;2592;768;;;;;; +103;2592;784;;;;;; +103;2592;800;;;;;; +103;2592;816;;;;;; +103;2592;832;;;;;; +103;2592;848;;;;;; +103;2592;864;;;;;; +103;2592;880;;;;;; +103;2592;896;;;;;; +103;2592;912;;;;;; +103;2592;928;;;;;; +103;2592;944;;;;;; +103;2592;960;;;;;; +103;2592;976;;;;;; +103;2592;992;;;;;; +103;2592;1008;;;;;; +103;2592;1024;;;;;; +103;2592;1040;;;;;; +103;2592;1056;;;;;; +103;2592;1072;;;;;; +103;2592;1088;;;;;; +103;2592;1328;;;;;; +103;2592;1344;;;;;; +103;2592;1360;;;;;; +103;2592;1376;;;;;; +103;2592;1392;;;;;; +103;2592;1408;;;;;; +103;2592;1424;;;;;; +103;2592;1440;;;;;; +103;2592;1456;;;;;; +103;2592;1472;;;;;; +103;2592;1488;;;;;; +103;2592;1504;;;;;; +103;2592;1520;;;;;; +103;2592;1536;;;;;; +103;2592;1552;;;;;; +103;2592;1568;;;;;; +103;2592;1584;;;;;; +103;2592;1600;;;;;; +103;2592;1616;;;;;; +103;2592;1632;;;;;; +103;2592;1648;;;;;; +103;2592;1664;;;;;; +103;2592;1680;;;;;; +103;2592;1696;;;;;; +103;2592;1712;;;;;; +103;2592;1728;;;;;; +103;2592;1744;;;;;; +103;2592;1760;;;;;; +103;2592;1776;;;;;; +103;2592;1792;;;;;; +103;2592;1808;;;;;; +103;2592;1824;;;;;; +103;2592;1840;;;;;; +103;2592;1856;;;;;; +103;2592;1872;;;;;; +103;2592;1888;;;;;; +103;2592;1904;;;;;; +103;2592;1920;;;;;; +103;2592;1936;;;;;; +103;2592;1952;;;;;; +103;2592;1968;;;;;; +103;2592;1984;;;;;; +103;2592;2000;;;;;; +103;2592;2016;;;;;; +104;-16;1968;;;;;; +104;1280;2080;;;;;; +104;1600;2080;;;;;; +104;1712;2080;;;;;; +104;2176;2080;;;;;; +104;2192;2064;;;;;; +104;2560;2080;;;;;; +104;2576;240;;;;;; +104;2576;2064;;;;;; +104;2592;256;;;;;; +104;2592;1104;;;;;; +104;2592;1120;;;;;; +104;2592;1136;;;;;; +104;2592;1152;;;;;; +104;2592;1168;;;;;; +104;2592;1184;;;;;; +104;2592;1200;;;;;; +104;2592;1216;;;;;; +104;2592;1232;;;;;; +104;2592;1248;;;;;; +104;2592;1264;;;;;; +104;2592;1280;;;;;; +104;2592;1296;;;;;; +104;2592;1312;;;;;; +104;2592;2032;;;;;; +104;2592;2048;;;;;; +104;2608;272;;;;;; +104;2608;288;;;;;; +104;2608;304;;;;;; +104;2608;320;;;;;; +104;2608;336;;;;;; +104;2608;352;;;;;; +104;2608;368;;;;;; +104;2608;384;;;;;; +104;2608;400;;;;;; +104;2608;416;;;;;; +104;2608;432;;;;;; +104;2608;448;;;;;; +104;2608;464;;;;;; +104;2608;480;;;;;; +104;2608;496;;;;;; +104;2608;512;;;;;; +104;2608;528;;;;;; +104;2608;544;;;;;; +104;2608;560;;;;;; +104;2608;576;;;;;; +104;2608;592;;;;;; +104;2608;608;;;;;; +104;2608;624;;;;;; +104;2608;640;;;;;; +104;2608;656;;;;;; +104;2608;672;;;;;; +104;2608;688;;;;;; +104;2608;704;;;;;; +104;2608;720;;;;;; +104;2608;736;;;;;; +104;2608;752;;;;;; +104;2608;768;;;;;; +104;2608;784;;;;;; +104;2608;800;;;;;; +104;2608;816;;;;;; +104;2608;832;;;;;; +104;2608;848;;;;;; +104;2608;864;;;;;; +104;2608;880;;;;;; +104;2608;896;;;;;; +104;2608;912;;;;;; +104;2608;928;;;;;; +104;2608;944;;;;;; +104;2608;960;;;;;; +104;2608;976;;;;;; +104;2608;992;;;;;; +104;2608;1008;;;;;; +104;2608;1024;;;;;; +104;2608;1040;;;;;; +104;2608;1056;;;;;; +104;2608;1072;;;;;; +104;2608;1088;;;;;; +104;2608;1328;;;;;; +104;2608;1344;;;;;; +104;2608;1360;;;;;; +104;2608;1376;;;;;; +104;2608;1392;;;;;; +104;2608;1408;;;;;; +104;2608;1424;;;;;; +104;2608;1440;;;;;; +104;2608;1456;;;;;; +104;2608;1472;;;;;; +104;2608;1488;;;;;; +104;2608;1504;;;;;; +104;2608;1520;;;;;; +104;2608;1536;;;;;; +104;2608;1552;;;;;; +104;2608;1568;;;;;; +104;2608;1584;;;;;; +104;2608;1600;;;;;; +104;2608;1616;;;;;; +104;2608;1632;;;;;; +104;2608;1648;;;;;; +104;2608;1664;;;;;; +104;2608;1680;;;;;; +104;2608;1696;;;;;; +104;2608;1712;;;;;; +104;2608;1728;;;;;; +104;2608;1744;;;;;; +104;2608;1760;;;;;; +104;2608;1776;;;;;; +104;2608;1792;;;;;; +104;2608;1808;;;;;; +104;2608;1824;;;;;; +104;2608;1840;;;;;; +104;2608;1856;;;;;; +104;2608;1872;;;;;; +104;2608;1888;;;;;; +104;2608;1904;;;;;; +104;2608;1920;;;;;; +104;2608;1936;;;;;; +104;2608;1952;;;;;; +104;2608;1968;;;;;; +104;2608;1984;;;;;; +104;2608;2000;;;;;; +104;2608;2016;;;;;; +105;-48;928;;;;;; +105;-48;944;;;;;; +105;-48;960;;;;;; +105;-48;976;;;;;; +105;-48;992;;;;;; +105;-48;1008;;;;;; +105;-48;1024;;;;;; +105;-48;1040;;;;;; +105;-48;1056;;;;;; +105;-48;1072;;;;;; +105;-48;1088;;;;;; +105;-48;1104;;;;;; +105;-32;208;;;;;; +105;-32;224;;;;;; +105;-32;240;;;;;; +105;-32;256;;;;;; +105;-32;272;;;;;; +105;-32;288;;;;;; +105;-32;304;;;;;; +105;-32;320;;;;;; +105;-32;336;;;;;; +105;-32;400;;;;;; +105;-32;416;;;;;; +105;-32;432;;;;;; +105;-32;448;;;;;; +105;-32;464;;;;;; +105;-32;480;;;;;; +105;-32;496;;;;;; +105;-32;512;;;;;; +105;-32;528;;;;;; +105;-32;544;;;;;; +105;-32;560;;;;;; +105;-32;576;;;;;; +105;-32;592;;;;;; +105;-32;608;;;;;; +105;-32;624;;;;;; +105;-32;640;;;;;; +105;-32;656;;;;;; +105;-32;672;;;;;; +105;-32;688;;;;;; +105;-32;704;;;;;; +105;-32;720;;;;;; +105;-32;736;;;;;; +105;-32;752;;;;;; +105;-32;768;;;;;; +105;-32;784;;;;;; +105;-32;800;;;;;; +105;-32;816;;;;;; +105;-32;832;;;;;; +105;-32;848;;;;;; +105;-32;864;;;;;; +105;-32;880;;;;;; +105;-32;896;;;;;; +105;-32;912;;;;;; +105;-32;1120;;;;;; +105;-32;1136;;;;;; +105;-32;1152;;;;;; +105;-32;1536;;;;;; +105;-32;1552;;;;;; +105;-32;1568;;;;;; +105;-32;1584;;;;;; +105;-32;1600;;;;;; +105;-32;1616;;;;;; +105;-32;1632;;;;;; +105;-32;1648;;;;;; +105;-32;1664;;;;;; +105;-32;1680;;;;;; +105;-32;1696;;;;;; +105;-32;1712;;;;;; +105;-32;1728;;;;;; +105;-32;1744;;;;;; +105;-32;1760;;;;;; +105;-32;1776;;;;;; +105;-32;1792;;;;;; +105;-32;1808;;;;;; +105;-32;1824;;;;;; +105;-32;1840;;;;;; +105;-32;1856;;;;;; +105;-32;1872;;;;;; +105;-32;1888;;;;;; +105;-32;1904;;;;;; +105;-32;1920;;;;;; +105;-32;1936;;;;;; +105;-32;1952;;;;;; +105;-32;1968;;;;;; +105;-16;192;;;;;; +105;-16;352;;;;;; +105;-16;368;;;;;; +105;-16;384;;;;;; +105;-16;1168;;;;;; +105;-16;1184;;;;;; +105;-16;1200;;;;;; +105;-16;1216;;;;;; +105;-16;1232;;;;;; +105;-16;1248;;;;;; +105;-16;1264;;;;;; +105;-16;1280;;;;;; +105;-16;1296;;;;;; +105;-16;1312;;;;;; +105;-16;1328;;;;;; +105;-16;1344;;;;;; +105;-16;1360;;;;;; +105;-16;1376;;;;;; +105;-16;1392;;;;;; +105;-16;1408;;;;;; +105;-16;1424;;;;;; +105;-16;1440;;;;;; +105;-16;1456;;;;;; +105;-16;1472;;;;;; +105;-16;1488;;;;;; +105;-16;1504;;;;;; +105;-16;1520;;;;;; +105;0;176;;;;;; +105;976;2064;;;;;; +105;992;2048;;;;;; +105;1056;2080;;;;;; +105;1392;2080;;;;;; +105;1648;2080;;;;;; +105;1936;2080;;;;;; +105;2416;2064;;;;;; +105;2448;2080;;;;;; +100;-16;2016;;;;;; +100;0;2048;;;;;; +100;16;2064;;;;;; +100;32;2064;;;;;; +100;48;2064;;;;;; +100;64;2064;;;;;; +100;80;2064;;;;;; +100;96;2048;;;;;; +100;112;2048;;;;;; +100;128;2048;;;;;; +100;144;2048;;;;;; +100;160;2048;;;;;; +100;176;2048;;;;;; +100;192;2048;;;;;; +100;208;2048;;;;;; +100;224;2048;;;;;; +100;240;2048;;;;;; +100;256;2048;;;;;; +100;272;2048;;;;;; +100;288;2064;;;;;; +100;304;2080;;;;;; +100;320;2080;;;;;; +100;336;2080;;;;;; +100;352;2080;;;;;; +100;368;2080;;;;;; +100;384;2064;;;;;; +100;400;2048;;;;;; +100;416;2048;;;;;; +100;432;2048;;;;;; +100;448;2048;;;;;; +100;464;2048;;;;;; +100;480;2048;;;;;; +100;496;2048;;;;;; +100;512;2048;;;;;; +100;528;2048;;;;;; +100;544;2048;;;;;; +100;560;2048;;;;;; +100;576;2048;;;;;; +100;592;2048;;;;;; +100;608;2048;;;;;; +100;624;2048;;;;;; +100;640;2048;;;;;; +100;656;2048;;;;;; +100;672;2048;;;;;; +100;688;2048;;;;;; +100;704;2048;;;;;; +100;720;2048;;;;;; +100;736;2048;;;;;; +100;752;2048;;;;;; +100;784;2080;;;;;; +100;800;2080;;;;;; +100;816;2080;;;;;; +100;832;2080;;;;;; +100;848;2064;;;;;; +100;864;2048;;;;;; +100;880;2048;;;;;; +100;896;2048;;;;;; +100;912;2048;;;;;; +100;928;2048;;;;;; +100;944;2064;;;;;; +100;960;2064;;;;;; +100;976;2048;;;;;; +198;416;1199;ow_weather_bird +91;864;784;;;; +451;800;912; +451;816;912; +451;1056;944;1750 diff --git a/bin/Data/Maps/overworld.map.data b/bin/Data/Maps/overworld.map.data new file mode 100644 index 0000000..dae58c4 --- /dev/null +++ b/bin/Data/Maps/overworld.map.data @@ -0,0 +1,131 @@ +161 +129 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;;;;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;;;;;;;;;;;;;;;;;;;1;1;;;;;;;;;1;1;;;;;1;;;;;;1;1;1;1;1;;;;1;1;;; +;;;;1;1;1;1;1;;;;;;;1;;;;1;1;1;1;1;1;1;;;;;;;;;;1;;;;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;1;1;;;;;;;;;;;;;;;;;;;;;1;1;1;;;;;;;;;;;;;;;;;;;1;;;;;;1;1;;;1;1;;;;;;;;;1;1;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;; +;;;;1;1;1;1;1;;;;;;;1;1;1;1;1;1;1;1;1;1;1;;1;1;1;1;1;1;1;1;1;1;;1;1;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;1;1;;1;1;1;1;1;1;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;1;1;1;;;;1;1;1;1;1;1;1;1;;;;;;1;1;;;;;;;;;;;;;;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;;;;;;;;;;;;;1;1;1;1;1;1;1;1;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;;;;;;;;;;;;;1;1;1;1;1;1;1;1;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;1;1;1;;1;1;1;1;1;1;1;;;;1;1;1;1;1;1;1;1;1;1;1;;;1;;1;1;1;;1;;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;;;;;1;;1;1;1;1;1;;1;1;1;1;1;1;1;1;;1;;;;;;1;1;;;;1;1;1;;;;;;;;;;;;;;;;;1;1;;;;;;;;;1;;;;1;1;1;1;1;1;1;;;;1;;; +;;;;1;1;1;1;1;;1;1;1;1;1;1;;;;1;1;1;1;1;1;1;1;1;1;1;;1;1;;1;;1;;1;1;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;1;;;;;;;;1;1;1;;1;1;1;1;1;;1;1;1;;;;;;;;;;;;;;;;;;;;;;1;;;;;;;;;;;;;;;1;1;1;;;;;;;;;;;;;;;;;;;;;;1;;; +;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;1;;1;1;1;1;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;1;;;;;;;;1;1;1;;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;;;;;;;;;;;;;;;;;;;;1;1;;;;;;;;1;1;1;1;;;;;;1;;; +;;;1;1;1;1;1;1;1;;;;;1;1;1;;;;;;;;;;;;;;;;1;1;;1;;1;1;;1;1;;;;;;;;;;;;;;;;;1;1;;;;;;;;;;;;;;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;;;;;;1;1;;;;;;;;;;;;;;;;;;;;1;1;;;;;;;;;;;;;;;1;1;1;;; +;;;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;1;1;1;1;1;1;1;1;1;1;;;;;;;1;1;1;1;1;;; +;;;;;;;;;;;;1;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;1;1;;1;;1;;1;1;1;1;;;;;;;;;;;;;;;;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;1;1;1;1;1;;;;;;;;;;;1;1;1;;;1;1;1;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;;;;;1;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;;;;;;;;;;;;;;;;;;;;;;1;1;;;;;;;1;;1;;1;1;1;1;1;;;;;;;;;;;;;;;;1;1;;;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;1;;;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;1;1;;;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;;;;;1;1;1;1;1;1;1;1;;;;;; +;;;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;1;;;1;1;1;;;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;;1;1;;;1;1;1;1;1;1;1;1;1;1;1;;;;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;1;;;;1;;;;1;1;;;;1;1;1;1;;1;;;;;1;1;1;1;1;1;1;1;;;;;; +;;;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;1;1;;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;;1;1;;;1;1;1;;;;;;1;1;1;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;1;;;;;1;1;1;1;;;;; +;;;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;1;;;;;1;;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;1;;1;1;;;1;1;1;;;;;;;;;;1;;;;1;1;;;;1;1;;;;1;1;;;;;;;;;;;;;;;;1;;;;1;;;;1;1;;;;1;1;1;1;1;1;;;;;1;1;;;;;;1;1;;;;; +;;;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;1;;;;;1;;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;1;;1;1;;;1;1;1;;;;;;;;;;1;;;;1;1;;;;1;1;;;;1;1;;;;;;;;;;;;;;;;1;;;;1;;;;1;1;;;;1;1;1;1;1;1;;;;;1;1;;;;;;1;1;;;;; +;;;1;1;1;1;;;;;;1;1;1;1;1;1;1;1;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;;;1;;;;;1;1;1;1;1;;;;;;1;1;1;1;1;1;1;;;;;1;1;;;1;1;1;;;;1;;;;;;1;1;1;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;1;;;;1;;;;1;1;;;;1;1;1;1;1;1;;;;1;1;1;;;;;;1;1;;;;; +;;;1;1;1;1;;;;;;1;1;;;1;1;;;;;1;1;;;;;;;;;;;;;;;;;;;;;;1;1;1;;;;;1;;;;1;1;1;1;1;1;;;;;;1;1;1;1;1;1;;;;;;;1;;;1;1;;;;;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;1;1;1;;;1;1;;1;;;;;; +;;1;1;1;;1;1;1;1;;;;;;;;;;;;;1;1;1;1;;;;;;;;;;;;;;;;;;;1;1;;;;;1;1;1;;;;;;;;;;;1;1;1;1;1;1;1;1;1;1;;;;;;;1;1;1;1;1;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;1;1;1;;;1;1;1;1;;;;;; +;;1;1;1;1;1;;;;;;1;1;1;1;;;;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;1;1;;;1;1;1;1;1;;;;;;;;;;;1;;1;1;;1;1;1;1;1;1;1;;1;1;;1;1;1;1;1;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;1;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;1;1;1;1;1;1;;;1;1;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;1;1;1;1;;;;;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;;;;;;;1;1;1;1;1;1;;;;;1;1;;1;1;1;;;;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;;;;;;;;;;;;;;;;;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;3;3;3;3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;;;;;;;;;;;;;;;;;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;3;3;3;3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;;;;;;;;;;;;;;;;;1;1;;;1;1;;;;;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;3;3;3;3;3;3;3;3;3;3;3;3;;;3;3;3;;;;;;;3;3;3;3;3;3;3;3;3;3;;;;;;;;;;1;1;1;1;1;1;;;;1;1;;;;;;1;1;;;1;1;;;;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;3;;;;;;;3;;3;;;3;3;3;;;;;;;3;3;3;3;3;3;3;3;3;3;3;;;;;;;1;;;1;1;1;1;1;1;1;1;1;1;;;;;;1;1;1;1;;;1;1;1;1;1;1;1;;;1;;;;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;3;3;3;3;;3;3;3;3;3;3;3;3;3;3;;;;;3;3;3;3;3;3;3;3;1;1;;1;1;1;;1;1;1;1;1;;;;;1;1;1;1;1;1;1;1;1;1;;;1;;;1;1;1;1;1;1;1;;;;;;;;;1;1;1;1;1;1;;;;;;1;1;1;1;1;1;1;1;1;;;;;;;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;3;3;3;3;3;3;3;3;3;;;3;3;3;3;;;;;3;3;3;3;3;3;3;;;;;3;3;3;3;3;3;3;3;1;1;;;1;;;1;1;;;1;;;;;1;1;1;;;1;1;;;1;1;1;1;;;1;;;1;;1;1;;;;;;;;;1;1;1;;;;;;;;;;;;;1;1;1;1;1;;;;;;;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;3;3;3;3;3;3;3;3;3;;;3;3;3;3;;;;;;3;3;3;3;;;;;;;;;;;;;3;3;1;1;1;;;;1;1;1;;;1;;;;;1;1;1;;;1;1;;;1;1;1;1;1;1;1;;;1;1;1;1;;;;;;;;;1;1;;;;;;;;;;;;;;;1;1;1;1;;;;;;;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;3;3;3;3;;;;;;;;3;3;3;3;;;;;;3;3;3;3;;;;;;;;;;;;;;;;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;;;1;1;1;1;;;1;1;;;1;1;1;1;1;1;1;;;;;;;;1;1;1;;;;;;;;;;;;;;;1;1;1;1;1;1;1;;;;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;3;3;3;3;;;;;;;;3;3;3;3;;;;;;3;3;3;3;;;;;;;;;;;;;;;;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;;;1;1;1;1;;;1;1;;;1;1;1;1;1;1;1;;;;;;;;1;1;1;;;;;;;;;;;;;;;1;1;1;1;1;1;1;;;;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;3;3;3;3;;;;;;;3;3;3;3;3;;;;;;3;3;3;3;;;;;;;;;;;;;;;;1;1;1;1;1;1;1;1;;;;;1;1;1;1;1;1;;;1;1;1;1;1;;;1;1;1;1;1;1;1;1;1;1;;;;;;;;1;1;1;;;;;;;;;;;;;;;1;1;1;;1;1;1;;;;1;1;1;1;;;;;;;;;1;1;;;;;;;;1;;1;;;;;;;;;;;;;;;;;;;;;;;;; +;;;3;3;3;3;;;;;;3;3;3;3;3;3;3;;;;;3;3;3;3;3;;;;;;3;;;;;3;;;;;;;;;1;1;1;;;;;1;1;1;;;1;;;1;;;1;1;;;1;1;1;1;;;1;1;1;1;;;;;;;;1;1;1;;;;;;;;;;;;;;;1;1;1;1;1;1;1;;;;1;1;;;;;;;;;;;;1;;;;;;;;;1;1;1;;;;;;;;;;;;;;;;;;;;;;;; +;;;3;3;3;3;3;3;3;;;3;3;;;3;3;3;;;;;3;3;3;3;3;3;;;;;3;;;;;3;;;;;;;;;1;1;1;;;1;;;1;1;;;;;;;;;;;;1;1;1;1;1;;;1;1;1;1;;;;;;;1;1;1;1;;;;;;;;;;;;;;;;1;1;1;1;1;;;;;1;1;;;;;;;;;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;3;3;3;3;3;3;3;;;3;3;;;3;3;3;;;;;3;3;3;3;3;3;;;;;3;;;;;3;;;;;;;;;1;1;1;;;1;;;1;1;1;1;;;;;1;;;;1;1;1;1;1;1;1;1;1;;;1;;;;;;;1;1;1;1;;;;;;;;;;;;;;;1;1;1;;1;1;1;;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;3;3;3;3;3;;;3;3;3;3;3;3;3;;;;;3;3;3;3;3;3;;;;;3;3;3;3;3;3;;;;;;;;;1;1;1;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;;;1;;;;;;;1;1;1;1;;;;;;;;;;;;;;;1;1;1;1;1;1;1;;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;3;3;3;3;3;;;3;3;3;3;3;3;;;;;;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;;;;;;;;;1;1;1;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;;;;;;;1;1;1;1;;;;;;;;;;;;;;;1;;1;1;1;;1;;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;3;3;3;3;;;;;;3;3;3;;;;;;;;;3;3;3;3;;;;;;;;;1;1;1;1;;;;;;;;;1;1;;;;;;;;;;;;;;;1;1;;;;;;;;;;1;1;;;;;;;;;;;;;;;;;;;1;1;1;;;;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;3;3;3;3;;;;;;3;3;3;;;;;;;;;3;3;3;3;;;;;;;;;1;1;1;1;;;;;;;;;1;1;;;;;;;;;;;;;;;1;1;;;;;;;;;;1;1;;;;;;;;;;;;;;;;;;;1;1;1;;;;;;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;3;3;3;3;3;3;3;3;3;3;3;3;;;;;;3;3;3;;;;;;;;3;3;3;3;3;;;;;;;;1;1;1;1;1;1;1;1;1;;;;1;1;1;;;;;;;;;;;;;;;1;1;;;;;;;;;;1;1;;;;;;;;;;;;;;;;;;;1;1;1;;;;;;1;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;3;3;3;3;3;3;3;3;3;3;3;3;;;;;;3;3;3;;;;;;;3;3;3;3;3;3;3;;;;;;;1;1;1;1;1;1;1;1;1;;;;1;1;;;;;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;;;;;;1;1;;;;1;1;1;1;;;;;;1;1;1;;;;1;1;1;;1;1;1;1;1;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;3;3;3;;;;;;;3;3;3;;;;;;3;3;3;;;;;;;3;3;;;3;3;3;;;;;;;;1;1;1;1;1;1;1;;;1;;;1;;;;;1;;1;;1;;1;;;1;1;;1;;1;;1;;;;;;1;1;1;1;1;1;1;1;1;;;;;;1;1;1;1;1;1;1;1;1;;1;1;1;1;1;;;1;1;;;;;;;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;3;3;3;;;;;;;3;3;3;;;;;;3;3;3;3;3;3;3;;;3;3;;;3;3;3;;;;1;1;;;;1;1;1;1;1;1;;;1;;;1;;;;;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;;;;;;1;1;1;1;1;1;1;1;1;;1;;1;;1;1;1;1;1;1;1;1;1;;;;;;1;1;;1;1;;;;;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;3;3;3;;;;;;;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;;;3;3;3;3;3;3;3;;;;1;;1;;;;1;1;1;1;1;1;1;1;1;;1;1;1;1;1;1;;1;;1;;1;;;1;1;;1;;1;;1;;;;;;1;1;1;1;1;1;1;1;1;1;1;;1;1;1;1;1;1;1;1;1;1;1;;;;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;3;3;3;3;;;;;;;3;3;3;;;;;;3;3;3;3;3;3;3;;;3;3;3;3;3;3;;;;;1;1;1;1;;;1;1;1;1;1;1;1;1;1;;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;;;;;;1;1;1;1;1;1;1;1;1;1;1;;1;1;1;1;1;1;1;1;1;1;1;;;;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;3;3;3;3;3;3;3;3;3;3;3;3;3;;;;;;3;;;;;;;;;;;3;3;3;3;;;;;1;1;1;1;;;;;;;;;;;;;1;1;;;;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;1;;1;;;;;;;;;;;;;;;;;;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;3;3;3;3;3;3;3;3;3;3;3;3;3;;;;;;3;;;;;;;;;;;3;3;3;3;;;;;1;1;1;1;;;;;;;;;;;;;1;1;;;;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;3;3;3;3;3;3;3;3;3;3;3;3;3;;;;;;3;;;;;3;3;3;3;3;3;3;;3;3;3;;;;;;;;;1;1;1;1;1;1;1;1;1;1;;1;1;;;;1;1;;1;;1;1;;;1;1;;1;;1;;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;3;3;3;3;3;3;3;3;;;;;;;;;;3;;;;;3;;;;;3;3;3;3;3;3;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;1;1;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;3;3;3;;;;;3;;;;;;;;;;3;3;3;3;3;3;;;;;;3;3;3;;3;;;;;1;1;1;1;shell:shell_9;1;1;1;1;1;1;;1;;;1;1;;;;1;1;;1;;1;1;1;1;1;1;;1;;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;3;3;3;;;;;3;3;3;3;;;;;;;3;3;3;3;3;3;;;;;3;3;3;3;3;3;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;;1;1;1;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;3;3;3;;;;;3;3;3;3;;;;;;;3;3;3;3;3;3;;;;;3;3;;3;3;3;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;3;3;3;3;3;;;;;;3;3;3;3;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;1;;;;;;1;1;1;1;1;1;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;3;3;3;3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;;1;1;1;;;;;;;;;;;;;;;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;3;3;3;3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;1;1;1;;;;;;;;;;;;;;;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;3;3;3;3;3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;3;3;3;3;3;;;;;;;;;;;;;;1;1;1;;;;;;1;1;;;;1;;1;1;1;1;1;1;1;1;1;;;;;1;1;1;1;1;1;1;1;;;;;;;1;1;1;1;;1;1;1;1;1;1;;;1;1;1;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;1;1;1;1;1;;1;1;1;1;;;;;;;;;;;;;;;;;1;1;;;;;;;;;;;1;1;1;1;1;1;;;;;;;;;; +;;;;;;3;3;3;;;;;;;;;1;1;;;;1;1;1;;;;;;1;1;;;;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;1;;1;1;1;1;1;1;1;1;1;;;1;1;1;;;1;1;1;;;;1;1;1;1;1;1;1;;1;1;;1;;;;;;;;;1;1;1;1;1;;;;;1;;;;;;;;;;;1;;;;;;1;1;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;3;;;;;;;;;;1;1;;;;1;1;1;;;;;;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;;;;;;;;;;;;;1;;;1;1;1;1;1;;1;;1;1;1;1;1;1;1;1;1;1;;;1;1;1;;;;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;1;1;1;;;1;1;1;1;1;1;;1;;;;;;;;;;;1;;;;;;1;1;;;;;;;;;;;;;;;;;;;;;;1;;;; +;;;;;;;3;;;;;;;;;;1;1;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;;;1;;;;;;;;;;;1;;;1;1;1;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;1;1;;;;;;1;1;1;;;1;1;1;1;1;1;;1;;;;;;;;;;;1;;;;;;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;1;1;;; +;;;;;;;3;;;;;1;1;1;1;1;1;1;;;;1;;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;;;1;1;1;1;;;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;;1;1;;;1;1;1;1;1;1;1;;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;;1;;;;;;;;;;;1;;;;;;;;;;;;;;1;1;1;1;1;1;1;;1;1;1;;;;;1;1;;; +;;;;;;;3;;;;;;1;1;1;1;1;1;;;;1;;;;;;;;;;;;;;1;1;1;1;;;1;1;1;1;;;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;;;;;;;;1;1;1;;;;;;;1;1;;;;;;;;1;1;1;1;1;1;1;;;;;;;;1;;;;;;;;;;;1;;;;;;;;;;;;1;1;;1;;1;1;;1;;1;1;1;;;;;1;1;;; +;;;;;;;1;;;;;;1;1;1;1;1;1;;;;1;;;;;;;;;;;;;;1;1;1;1;;;1;1;1;1;;;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;;;;;;;;1;1;1;;;;;;;1;1;;;;;;;;1;1;1;1;1;1;1;;;;;;;;1;;;;;;;;;;;1;;;;;;;;;;;;1;1;;1;;1;1;;1;;1;1;1;;;;;1;1;;; +;;;;;;;1;;;;;1;1;1;1;1;1;1;;;;1;;;;;;;;1;1;1;1;1;1;1;1;1;1;;;1;1;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;;;;1;1;1;1;1;1;;1;1;1;1;1;;1;1;1;1;1;;;1;1;1;1;1;1;1;1;;;;1;1;1;1;1;1;1;;;;1;1;1;1;1;;;;;;;1;1;1;1;1;;;;;;;;;;;;1;1;1;1;1;1;1;;1;1;1;1;1;;;;;1;1;;; +;;;;;;1;1;1;;;;1;;;1;1;1;1;1;;;1;;;1;1;1;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;;1;1;1;1;1;;;1;;1;1;1;1;;1;1;1;1;1;;1;1;1;;1;;;1;1;;1;1;1;;1;;;;;;;1;1;1;;;;;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;;;1;;;;;1;1;;; +;;;;;1;1;1;1;;;;1;;;1;1;1;1;1;;;1;;1;;;;1;;1;1;1;1;;;;1;1;1;;;1;1;1;1;;;1;1;1;1;1;1;;;;;;1;1;1;1;1;1;1;;1;1;;;;;1;1;1;1;1;;1;1;1;;;;1;1;;1;1;;;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;;1;1;1;1;1;1;1;1;1;1;;1;1;1;1;1;;; +;;;;;1;1;1;1;;;;1;1;1;1;;;1;1;;;1;;1;;;;1;;1;1;1;1;;;;1;1;1;;;1;1;1;;;;1;1;1;1;1;1;1;1;;;;1;1;1;;1;1;1;1;1;1;;;;;1;;1;1;;;;;;;;;1;1;1;1;1;;;1;1;;1;1;1;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;1;1;;;1;1;;;;;1;1;1;;;;; +;;;;;1;;1;1;;;;1;1;1;1;;;1;1;;;1;;1;;;;1;;1;1;1;1;;;;1;1;1;;;;;;;;1;1;1;1;1;1;1;1;1;;;;1;1;1;1;1;1;1;1;;1;1;;;1;1;1;1;1;1;;;;;;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;;;; +;;;;;1;1;1;1;;;;1;1;1;1;1;1;1;1;;;1;;;1;1;1;;;1;1;1;1;1;1;1;1;1;1;;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;1;;;1;1;1;1;;;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;; +;;;;;1;1;1;1;;;;;;;1;1;1;;;;;1;;;;;;;;1;1;1;1;1;1;1;1;1;1;;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;1;;;;;;;;;1;1;1;1;1;;;;;;;;;;;;;;;;;;;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;;;;;;; +;;;;;1;1;1;1;;;;;;;1;1;1;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;1;;;;;;;;;1;1;1;1;1;;;;;;;;;;;;;;;;;;;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;;;;;;; +;;;;;1;1;1;1;1;1;1;1;;;;1;1;1;1;1;1;1;;;;;;;;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;1;1;1;1;;;1;1;;;1;1;1;1;1;;;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;;;;;1;1;1;1;;;;;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;;;;;;; +;;;;;1;1;1;;;1;1;1;;;;;1;1;1;1;1;1;;1;1;1;1;;;1;1;1;1;1;1;1;1;1;1;;;1;;;;1;;;1;1;1;1;1;;;;;;;1;1;1;1;;;;;;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;;;;;;1;1;;;1;1;;1;;;;1;1;1;1;;;;;;1;1;;;;;;;;;;;;;1;1;1;1;;1;1;1;1;1;1;1;1;1;;1;1;1;1;1;1;;;;1;;;;; +;;;1;;;;;;1;1;1;1;;;;;;1;1;1;1;1;;1;;;;;;1;1;1;1;1;1;1;1;1;1;;;1;;;;1;;;1;1;1;1;1;;1;1;1;1;1;1;1;1;1;;;1;1;1;;;;;;1;1;1;1;1;1;1;1;1;;;;;;;1;1;1;1;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;1;1;;;;;;;;;;;;;1;1;1;1;;1;1;1;1;1;1;1;;1;;1;;1;1;1;1;;;;1;;;;; +;;;1;;;;;;1;1;1;1;1;1;;1;1;1;1;1;1;1;;1;;;;1;;1;1;1;1;1;1;1;1;1;1;;;1;1;1;;1;1;1;;;;1;1;;1;shell:shell_5;1;1;1;1;1;1;1;;;1;1;1;;;;;;1;1;;;1;1;1;1;1;;1;;1;1;;;;;;;1;1;;1;;1;1;1;1;;;;;;;;1;1;1;1;;;;;;1;;;;1;1;1;;1;1;1;;;1;1;;1;;1;;1;;;1;;;;;;;;1;1;1;;;;1;;;;; +;;;1;1;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;1;1;1;1;1;;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;;;;1;1;;1;1;1;1;1;1;1;1;1;;;1;1;1;;;;;;1;1;;;1;1;;;;;shell:shell_14;1;1;1;1;;1;1;1;1;1;1;1;1;;1;1;1;1;;;;;;;1;1;1;1;1;;;;;1;1;;;;1;1;1;;1;1;1;;;1;1;;1;;1;;1;;;1;1;;1;;1;;1;1;1;1;;;;1;;;;; +;;;1;1;;1;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;1;;;;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;;;;1;1;;1;1;1;1;1;1;1;1;1;;;1;1;1;;;;;;1;1;;;1;1;;;;1;1;1;1;1;1;;1;1;;1;;1;;1;;1;1;1;1;1;1;1;1;1;1;1;1;1;;1;;;;;1;;;;;1;1;;;;1;1;;;1;1;;1;1;1;;1;1;1;1;1;1;1;;1;1;1;1;1;1;;;;1;;;;; +;;;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;;;;1;1;;;;;;;;;;;;;;;;;;;;;1;1;;;1;1;;;;1;;;;;1;;1;1;1;1;1;1;1;1;;1;;;;;;;;;;;;;;;;;;;1;1;;;;;;;;;;;;;1;1;;1;1;1;;;;;;;;;;;;;;;1;;;;1;;;;; +;;;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;;;;1;1;;;;;;;;;;;;;;;;;;;;;1;1;;;1;1;;;;1;;;;;1;;1;1;1;1;1;1;1;1;;1;;;;;;;;;;;;;;;;;;;1;1;;;;;;;;;;;;;1;1;;1;1;1;;;;;;;;;;;;;;;1;;;;1;;;;; +;;;;;;1;1;1;1;;;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;1;1;1;1;1;1;1;1;1;;;;1;1;1;1;1;1;1;;;;1;1;;;;;;;;1;1;1;1;;1;1;;1;1;1;1;;1;1;;;1;1;;;;1;;;;;1;;1;1;;1;;1;;1;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;1;1;;;1;1;;;;;;1;1;1;1;1;;1;1;1;1;1;1;1;1;1;1;1;;1;;1;1;1;1;;;;1;1;;;; +;;;;;;1;1;1;1;;;;;;;;;;1;1;1;1;;;;;;;;1;1;1;1;1;;;;1;;;;1;1;1;1;1;;1;;;;1;1;;1;;;;1;1;1;1;1;1;;1;1;;1;1;1;1;;1;1;1;;;1;;;;1;;;;;1;;1;1;1;1;1;1;1;1;;1;1;1;1;1;;;;;;;;;;;;;;;1;1;;;1;;;;;;;1;1;1;1;1;;1;1;1;1;1;1;1;1;;1;;;;;1;1;1;1;1;1;1;1;1;;;; +;;;1;1;1;1;1;1;1;;;;1;;;;1;;1;1;1;1;;;;;;;;1;1;1;1;1;;;;1;;;;1;1;1;1;;;;;;;1;1;;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;1;1;;;1;;;;1;1;1;1;1;1;;1;1;;1;1;1;;;;1;1;1;1;1;;;;;;;;;;;;;;;1;1;;;1;;;;;;;1;1;1;1;1;;1;1;;;;;;1;;1;;;;;;;;1;;1;;1;1;;;; +;;;1;1;1;1;1;1;1;;;1;1;;;;1;1;1;1;1;1;;;;;;;;1;1;1;1;1;;;;1;;;;1;1;;;;;;;;;1;1;;1;1;1;1;1;1;1;1;;;;;1;1;;;;;;;1;1;;;1;;;;1;1;1;;;;;1;1;1;1;1;;1;1;1;1;1;1;1;;;;;;;;;;;;;;;1;1;1;;;1;;;1;;;;;;;;;;1;1;;;;;;1;;1;1;;1;;;;;;;;;;1;;;; +;;;1;1;1;1;1;1;1;;;1;1;;;;1;1;1;1;1;1;;;;;;;;1;1;1;1;1;1;1;1;1;;;;;;;;1;1;;;;;1;1;1;;;;;;1;1;1;;1;1;;1;1;;;;;;;;1;;;1;;;;;1;1;;;;;;;;;1;;1;;;;;;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;;;;;;;;;;;;;1;1;;1;1;1;1;1;;1;1;1;1;1;1;1;1;;;1;;1;1;;;; +;;;1;1;1;1;1;1;;;;;1;1;1;1;1;1;1;1;1;1;;;;;;;;1;1;1;1;1;1;1;;;;;;;;;1;1;1;1;;;;1;1;1;1;1;1;1;;1;1;1;;1;1;;;;;;;;;;1;1;;;1;;;;;1;1;;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;;1;1;1;1;1;1;1;1;;1;1;1;1;1;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;; +;;;;;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;;;1;;;;;1;1;;1;;1;;;1;;1;1;1;;;;;;;;;;;;;1;;;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;;1;;;;;1;1;;1;;1;;;1;;1;1;1;;;;;;;;;;;;;1;;;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;1;1;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;1;;1;;1;;1;1;1;1;1;1;1;;1;;;;;;;;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;1;;;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;;1;1;1;;;; +;;;;;1;1;1;1;;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;;1;1;1;1;1;1;1;1;1;;1;;;;1;1;1;1;1;;;;;1;dkey2:dkey2Collected;1;1;1;1;1;1;1;1;1;;1;;;;;;;;;;1;1;1;1;1;;;;;;;;;;;;;;;;1;;;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;1;1;;;;;;;;;;;;;1;1;1;1;1;1;1;;; +;;1;1;;;;;;;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;;;;;;;;;1;1;1;1;1;1;;;1;1;1;1;1;;;1;1;1;1;1;1;1;;;;;;;1;;;;;1;1;1;;1;1;1;1;1;1;1;;1;;;;;;1;1;1;1;;;;;;;;;;;;;;;;;;;;;1;;;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;1;;;;;;;;;;;1;1;1;;1;1;1;1;1;;; +;;1;1;;;;;;;1;1;1;1;1;1;;1;1;1;;;;;;1;;;;;;;;;1;1;1;1;1;1;;;;;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;;;1;;;;;;;;;1;1;1;1;1;1;1;;1;;;;;;1;1;1;1;;;;;;;;;;;;;;;;;;;;;1;;;1;1;1;1;1;1;;;;;;;;;1;;;;1;1;;;;;;;;1;;;;;;;;;;;;;1;1;1;;;;1;;; +;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;;;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;1;1;1;1;;;;;;1;1;1;1;1;1;1;;;1;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;1;;;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;1;;;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;1;;;;;;;;;;;;;;;;1;1;1;1;;; +;;1;1;1;1;1;1;1;;;;1;1;1;1;1;;1;1;;;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;;;;1;1;1;;1;;;;;;;1;;1;1;1;1;;;1;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;1;;;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;1;;;1;1;1;1;1;1;1;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;;;;;;;;;;;;;1;1;1;1;1;1;1;;; +;;;;;;;;;;1;1;1;1;1;1;1;;1;1;;;1;1;1;1;1;1;1;;;;;;;;;;;;;;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;;;1;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;1;;;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;1;;;1;1;1;1;1;1;1;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;;;;;;1;;;;;;;1;;;1;1;;;;; +;;;;;;;;;;1;1;1;1;1;1;1;;1;1;;;1;1;1;1;1;1;1;;;;;;;;;;;;;;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;;;1;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;1;;;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;1;;;1;1;1;1;1;1;1;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;;;;;;1;;;;;;;1;;;1;1;;;;; +;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;1;1;;;1;1;1;1;1;1;1;1;;;1;1;;;;;;;;;1;1;1;1;1;1;1;;1;1;;1;1;;1;1;1;1;;;1;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;1;;;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;1;1;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;1;;;1;1;1;1;;;;;;;1;1;;1;1;1;1;1;; +;;1;1;1;1;1;1;1;1;1;1;1;;;;;;1;1;;;1;1;1;1;1;1;1;1;;;1;1;;;;;;;;;;1;1;1;1;1;1;;1;1;1;1;1;1;1;;1;1;;;1;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;1;;;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;1;1;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;1;;;1;;;1;1;;1;1;1;1;1;1;1;;1;1;1;1;; +;;;;;;;;;;;;;;;;;;1;1;;;1;1;1;1;1;1;1;;;;1;1;;;;;;;;;1;1;;1;1;1;1;1;1;1;1;;1;1;1;1;;1;;;1;;;;;1;1;1;1;1;1;1;1;1;1;1;;1;;;1;1;1;1;1;1;;;;;;;;;;;;;;;;;shell:shell_20;;;;;;;;;1;1;1;1;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;1;;;1;;1;1;1;1;1;1;1;1;1;1;1;1;;1;1;1;; +;;;;;;;;;;;;;;1;1;1;1;1;1;;;1;1;;;1;1;1;;;;1;1;;;;;;;;;;;1;;;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;;;;;;;;1;1;1;1;1;1;;1;1;;;1;1;;;;;;;;;;;;;;;;;;;;;1;1;1;1;;;;;;1;1;1;1;;;;;;1;1;1;1;1;1;1;1;1;1;1;;;;;;1;1;;;1;;;1;1;1;1;1;1;1;1;1;1;1;;;;1;; +;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;;;1;1;1;1;;;1;1;1;;;;;;;;;;1;;;;;1;;;1;1;1;;1;1;1;;;;;1;1;1;1;1;1;1;;;;;;;;1;1;1;;;1;1;;;;;;;;;;door:dungeon5_entry:left;;door:dungeon5_entry:right;;;;;;;;;;1;1;1;;;;;;1;1;1;1;1;1;;;;;1;1;1;1;1;1;1;1;1;1;;1;;;;1;;;;1;;;;1;1;1;1;;;1;1;1;1;1;1;;1;; +;;1;1;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;1;;;;;;;;;1;;;1;1;1;;;;;1;1;1;1;1;1;1;1;1;1;;;;;1;1;1;;;;1;1;1;1;1;1;1;1;1;;;;;1;1;;;;;;;;;;;;;;;;;;;;;;1;1;1;;;;;;1;1;1;1;1;1;;;;;;1;1;1;;;;;;;;;;1;1;1;;;;1;1;1;;1;1;1;1;;;1;1;1;1;1;1;;1;; +;;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;;;;;;;;;;;;;;;;;;;;;;1;1;1;;;;;;1;1;1;1;1;1;;;;;;1;;;;;;;;;;;;1;;;;;;1;1;1;;1;;;;;;;;;;;;;1;; +;;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;;;;;;;;;;;;;;;;;;;;;;1;1;1;;;;;;1;1;1;1;1;1;;;;;;1;;;;;;;;;1;;;1;;;;;;1;1;1;;1;;;;;;;;;;;;;1;; +;;1;1;1;1;1;1;1;1;1;1;1;;1;1;1;1;1;;;;;1;1;1;1;1;1;;;;;1;;;;;;;;;;;;;;1;1;1;1;1;1;1;1;1;;1;1;1;;;;;;;;;1;1;1;1;1;1;1;1;1;;;;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;1;1;;;;;;1;;;;;;;;;1;;;1;1;1;;;;1;1;1;;1;1;1;1;;;1;1;1;1;1;1;;1;; +;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;1;1;1;1;1;1;;;;;1;;;;;;;;;;;;;;1;1;1;1;1;1;1;;1;1;1;;1;;;;;;;;;1;1;1;1;1;1;1;1;1;;;1;1;1;1;1;;;;;;;;;;;;;;;1;1;1;1;1;;;;;;;;;;;1;1;1;1;1;1;;;;;;1;;;;;;;;;1;;;1;1;;;1;1;1;1;1;;1;1;1;1;;;1;1;1;1;1;1;;1;; +;;1;1;1;;;;;1;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;1;1;;1;1;1;1;;1;1;1;1;1;;;;1;1;1;;;;;;;1;;;;1;1;1;1;1;1;1;1;1;;;;;;;;;;1;1;1;1;1;1;;;;;;;;;;;1;1;1;1;1;1;;;;;;1;;;;;;;;;;;1;1;1;;1;1;1;;;;;1;1;1;1;1;1;1;1;1;;1;1;;1;; +;;1;1;1;;;;;1;;;1;1;;;;1;1;;;;;;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;1;1;1;1;1;;;;1;1;;;;;;;;;;1;1;1;1;1;1;1;;;;;;;1;1;1;1;1;1;1;1;1;;;;;1;1;;;;;;;;;;;1;1;;;1;1;1;;;;;1;1;1;1;1;1;1;1;1;1;1;1;;1;; +;;1;1;1;1;1;1;1;1;;;1;1;;1;1;1;1;1;1;1;1;;1;1;1;1;;;;;;1;1;1;1;;;;;;;;;1;1;1;1;1;1;1;1;;1;1;1;;;1;1;1;1;1;1;;;;;1;;;1;1;;;1;1;;1;1;1;1;;;;1;1;;;;;;;;;;;;1;1;1;1;;;;;;;1;1;1;1;;;1;1;1;1;;;;;1;1;;;;;;;;;;;1;1;;1;1;1;1;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;1;; +;;1;1;1;1;1;1;1;1;;;1;1;;1;1;;1;1;1;1;1;1;1;;1;1;;;;;;1;1;1;1;;;;;;;;1;;1;1;1;1;;;1;1;1;1;1;1;;;;;;;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;1;;;1;1;1;1;1;1;1;1;;;1;1;1;1;;;;;1;1;;;;;;;;;;;1;1;;1;1;1;1;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;1;; +;;1;1;;;;;;;;;;;;1;1;1;1;;;;;1;1;1;1;1;;;;;;;;;;;;;;;;;1;1;1;1;1;1;;;;;;;1;1;1;1;;;;;;1;1;1;1;1;;;;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;1;1;;;1;1;1;1;;;;;1;1;1;1;;;;;;1;1;;;;;;;;;;;1;1;;1;1;1;1;;1;1;1;1;1;1;1;;;1;1;1;;;;;1;; +;;1;1;;;;;;;;;;;;1;1;1;1;;;;;1;1;1;1;1;;;;;;;;;;;;;;;;;1;1;1;1;1;1;;;;;;;1;1;1;1;;;;;;1;1;1;1;1;;;;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;1;1;;;1;1;1;1;;;;;1;1;1;1;;;;;;1;1;;;;;;;;;;;1;1;;1;1;1;1;;1;1;1;1;1;1;1;;;1;1;1;;;;;1;; +;;1;1;;1;1;1;1;1;1;1;1;1;1;1;1;;1;;;;;1;1;1;1;1;;;;;;;;;;;;;;;;;1;1;;1;1;1;;;;1;1;1;;1;1;1;;;;;;1;1;1;1;1;;;;;;;;;1;;;;;;;;;1;1;1;1;1;1;1;;;;;;;;;1;1;;;;;1;1;;;1;1;1;1;1;1;;;;;;1;1;;;;;;;;;;;1;1;;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;1;; +;;1;1;;1;1;1;;1;1;1;1;1;1;1;1;1;1;;;;;1;1;1;1;1;1;;;;;1;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;1;1;1;;;;;;;;;;;1;1;1;1;;;;;;;1;;;;;;;;;;;1;1;1;1;1;;;1;1;1;1;;;1;1;;;;;1;1;;;1;1;1;1;1;1;;;;;;1;1;1;;;1;1;1;1;1;;1;1;1;;;;;;;1;;1;1;;1;1;1;1;1;1;1;;;;;1;; +;;;1;;1;1;1;1;1;1;1;1;1;;1;1;1;1;;1;1;1;1;1;1;1;1;1;;1;1;1;1;1;1;1;1;1;;1;1;1;1;1;;1;1;1;;;;;;;1;1;1;;;;;;;;;;;1;1;1;1;1;1;;;;1;1;;;;;;;;;;;1;1;1;1;;;;1;1;1;1;;;1;1;;;;;1;1;1;1;1;1;1;1;1;1;;;;;1;1;1;1;1;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;1;1;;1;1;;;1;1;1;;1;1;1;1;; +;;;1;;1;1;;1;1;1;1;1;1;1;1;1;;1;1;;;;1;1;1;1;1;;1;1;1;1;1;;1;1;1;1;1;1;1;;1;1;1;1;1;1;1;;;1;1;1;1;1;1;1;1;;;;;;;1;1;1;1;1;1;1;;;;;;;;;;;;1;1;;;;1;1;1;1;;;1;1;1;;1;;;;1;;;;;1;1;1;1;1;1;1;1;;;;;;;1;1;1;1;1;;;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;;;1;1;1;;1;1;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;1;;;;;;;;;;;;;;;;;1;1;1;1;;;1;1;1;1;1;;;;1;;;;;1;1;1;1;1;1;1;;;;;;;;;1;1;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;;;;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;1;1;1;1;1;1;1;1;1;1;1;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/bin/Data/Maps/photoHouse.map b/bin/Data/Maps/photoHouse.map new file mode 100644 index 0000000..b1e6fae --- /dev/null +++ b/bin/Data/Maps/photoHouse.map @@ -0,0 +1,601 @@ +3 +0 +0 +house.png +10 +8 +3 +19,47,47,71,71,71,71,47,47,21, +45,51,51,65,50,50,66,51,51,46, +45,51,91,65,64,64,66,51,51,46, +45,51,51,51,51,51,51,51,51,46, +45,51,51,51,51,51,51,51,51,46, +45,51,51,69,69,69,69,51,51,46, +45,91,51,69,69,69,69,51,51,46, +20,48,48,48,39,38,48,48,48,22, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +45 +382;-32;32; +171;79;4;2;;photo_house_positioned;1;False;True +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;0;64;;; +0;0;80;;; +0;0;96;;; +0;16;0;;; +0;16;112;;; +0;32;0;;; +0;32;112;;; +0;48;0;;; +0;48;112;;; +0;64;0;;; +0;80;0;;; +0;96;0;;; +0;96;112;;; +0;112;0;;; +0;112;112;;; +0;128;0;;; +0;128;112;;; +0;144;16;;; +0;144;32;;; +0;144;48;;; +0;144;64;;; +0;144;80;;; +0;144;96;;; +3;64;112;;; +4;80;112;;; +153;72;120;;;photoHouse;overworld.map;photoHouse;1;; +284;-32;0;;;; +58;112;64;;;;;; +308;144;32;;;;; +308;144;80;;;;; +310;0;32;;;;; +310;0;80;;;;; +297;72;112;;;;;175; +9;16;96;;; +9;32;32;;; +287;-32;64;1 +164;32;27;spawned_photo_book;1;book;.photo_book.2; +164;72;120;photo_house_blocked;1;pushDialog;photo_house_blockade; +77;13;82;;;; +377;112;80;;photo_mouse_house diff --git a/bin/Data/Maps/photoHouse.map.data b/bin/Data/Maps/photoHouse.map.data new file mode 100644 index 0000000..c90cdd4 --- /dev/null +++ b/bin/Data/Maps/photoHouse.map.data @@ -0,0 +1,10 @@ +10 +8 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/pond.map b/bin/Data/Maps/pond.map new file mode 100644 index 0000000..cf0763f --- /dev/null +++ b/bin/Data/Maps/pond.map @@ -0,0 +1,573 @@ +3 +0 +0 +tileset 2d.png +10 +8 +3 +6,5,6,5,6,5,6,5,6,5, +34,34,34,34,34,34,34,34,47,47, +0,0,0,0,0,0,0,0,30,26, +0,0,0,0,0,0,0,0,8,7, +0,0,0,0,0,0,0,0,0,9, +0,0,0,0,0,0,0,4,14,7, +0,4,0,0,0,0,4,14,7,7, +10,10,10,10,10,10,10,7,7,7, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +17 +126;0;32;;;;; +126;16;32;;;;; +126;32;32;;;;; +126;48;32;;;;; +126;64;32;;;;; +126;80;32;;;;; +126;96;32;;;;; +126;112;32;;;;; +399;16;88;;;500 +398;16;47;;; +398;44;59;;36;900 +398;52;35;;36;150 +400;132;18 +168;176;64;pondBigFish;!pondReset&pondHeart; +287;-24;0;1 +164;120;64;pondHeart;;fish_big;2.0.0; +164;120;64;pondBigFish;1;fish_big;1.0.0; diff --git a/bin/Data/Maps/pond.map.data b/bin/Data/Maps/pond.map.data new file mode 100644 index 0000000..c90cdd4 --- /dev/null +++ b/bin/Data/Maps/pond.map.data @@ -0,0 +1,10 @@ +10 +8 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/shellhouse.map b/bin/Data/Maps/shellhouse.map new file mode 100644 index 0000000..eaf037c --- /dev/null +++ b/bin/Data/Maps/shellhouse.map @@ -0,0 +1,595 @@ +3 +1 +1 +house.png +12 +10 +3 +,,,,,,,,,,,, +,94,94,94,94,94,94,94,94,94,94,, +,94,84,84,84,84,84,84,92,99,92,, +,94,59,88,59,59,88,59,94,99,94,, +,59,59,59,59,59,59,59,92,99,92,, +,59,83,83,59,59,59,59,94,99,94,, +,59,87,87,59,59,59,59,92,99,92,, +,59,87,87,59,59,59,59,94,99,94,, +,94,94,94,94,94,94,94,94,99,94,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +,,,,,,,,,,,0, +,,,,,,,,,,,0, +,,,,,,,,,,,0, +,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,0,0,0,0,0,0,0,0,0,0,0, +524 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +waterfallSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +32 +0;16;32;;; +0;16;48;;; +0;16;128;;; +0;32;16;;; +0;32;128;;; +0;48;16;;; +0;48;128;;; +0;64;16;;; +0;64;128;;; +0;80;16;;; +0;80;128;;; +0;96;16;;; +0;96;128;;; +0;112;16;;; +0;112;128;;; +0;128;32;;; +0;128;48;;; +0;128;64;;; +0;128;80;;; +0;128;96;;; +0;128;112;;; +153;8;112;;;shellhouse;overworld.map;shellhouse;2;; +284;-16;40;;;; +167;192;16;spawnSwordParticle; +167;192;48;spawnSword; +298;8;88;200;;;;200; +257;-16;16 +287;-16;64;9 +164;88;72;spawnSword;1;swordSpawner;; +164;96;80;spawnSwordParticle;1;animatorL;1.Particles/shell_mansion_particle.idle.True; +92;52;81;;;; +181;144;128 diff --git a/bin/Data/Maps/shellhouse.map.data b/bin/Data/Maps/shellhouse.map.data new file mode 100644 index 0000000..966622a --- /dev/null +++ b/bin/Data/Maps/shellhouse.map.data @@ -0,0 +1,12 @@ +12 +10 +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; diff --git a/bin/Data/Maps/shop1.map b/bin/Data/Maps/shop1.map new file mode 100644 index 0000000..bcba9bd --- /dev/null +++ b/bin/Data/Maps/shop1.map @@ -0,0 +1,600 @@ +3 +0 +0 +house.png +10 +8 +3 +19,47,47,47,47,47,47,47,47,21, +45,10,10,10,10,10,10,10,10,46, +45,10,10,10,10,10,10,10,10,46, +45,73,73,73,73,73,73,73,73,46, +45,51,51,51,51,51,51,51,51,46, +45,51,51,51,51,51,51,51,51,46, +45,51,51,51,51,51,51,51,51,46, +20,48,48,48,39,38,48,48,48,22, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +44 +382;-24;96; +0;0;48;;; +0;0;64;;; +0;0;80;;; +0;0;96;;; +0;16;112;;; +0;32;112;;; +0;48;112;;; +0;96;112;;; +0;112;112;;; +0;128;112;;; +0;144;48;;; +0;144;64;;; +0;144;80;;; +0;144;96;;; +3;64;112;;; +4;80;112;;; +2;16;48;;; +2;32;48;;; +2;48;48;;; +2;64;48;;; +2;80;48;;; +2;96;48;;; +2;112;48;;; +2;128;48;;; +174;16;-16;check_item0 +174;168;0;houseMusic +153;72;120;;;s1;overworld.map;s1;1;; +299;72;112;;;;;; +285;-24;24;;;; +176;-24;72 +58;96;80;;;;;; +311;32;0;;;;; +311;112;0;;;;; +287;-24;0;6 +164;16;16;shopItem0;1;storeItem;bow.980.20; +164;16;16;shopItem0;0;storeItem;shovel.200.1; +164;16;16;shopItem0;2;storeItem;arrow.10.10; +164;72;120;isWatched;1;pushDialog;shopkeeper_try_steal; +164;112;16;shopLevel;1;storeItem;bomb.10.10; +368;112;80 +205;96;80;shopkeeper;;0.4.16.12;2 +202;48;16;heart;10;3 +202;80;16;shield;20; diff --git a/bin/Data/Maps/shop1.map.data b/bin/Data/Maps/shop1.map.data new file mode 100644 index 0000000..c90cdd4 --- /dev/null +++ b/bin/Data/Maps/shop1.map.data @@ -0,0 +1,10 @@ +10 +8 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/shop2.map b/bin/Data/Maps/shop2.map new file mode 100644 index 0000000..f1900e8 --- /dev/null +++ b/bin/Data/Maps/shop2.map @@ -0,0 +1,623 @@ +3 +0 +0 +house.png +10 +8 +3 +13,36,36,36,36,36,36,36,36,11, +37,10,10,10,10,10,10,10,10,34, +37,10,10,10,10,10,10,10,10,34, +37,10,10,10,10,10,10,10,10,34, +37,10,10,10,10,10,10,10,10,34, +37,73,40,40,40,40,40,40,40,34, +37,51,69,51,51,51,51,51,51,34, +12,35,35,35,39,38,35,35,35,14, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +67 +382;0;208; +0;0;80;;; +0;0;96;;; +0;16;112;;; +0;32;80;;; +0;32;112;;; +0;48;80;;; +0;48;112;;; +0;64;80;;; +0;72;128;;; +0;80;80;;; +0;96;80;;; +0;96;112;;; +0;112;80;;; +0;112;112;;; +0;128;80;;; +0;128;112;;; +0;144;96;;; +3;64;112;;; +4;80;112;;; +179;16;6 +180;32;64 +153;72;120;;;s2;overworld.map;s2;1;; +299;72;112;;;;;; +285;0;144;;;; +200;48;32;;trendy_0;heart_1;; +200;64;64;;trendy_4;powderTrendy;; +200;80;32;;trendy_1;ruby30;; +200;80;48;;trade0Collected;trade0;; +200;112;32;;trendy_2;ruby30;; +200;112;64;;trendy_3;shield0;; +176;32;144 +168;176;64;trendy_closed;trendy_0&trendy_1&trendy_2&trendy_3&trendy_4&trade0Collected; +167;176;96;npc_trendy;0 +311;32;0;;;;; +311;112;0;;;;; +312;144;32;;;;; +312;144;80;;;;; +313;32;112;;;;; +313;112;112;;;;; +314;0;32;;;;; +314;0;80;;;;; +170;72;96;trendy_2;3;;;True +170;72;96;trendy_1;3;;;True +170;72;96;trendy_3;3;;;True +170;72;96;trendy_4;3;;;True +170;72;96;trendy_0;3;;;True +287;0;176;1 +192;16;16; +192;16;32; +192;16;48; +192;16;64; +192;48;32; +192;48;48; +192;48;64;3 +192;64;32;1 +192;64;64;3 +192;80;32;1 +192;80;64;3 +192;96;32;1 +192;96;64;3 +192;112;32;1 +192;112;48;2 +192;112;64;2 +193;16;80 +175;112;96;;;trendy_marin +381;128;94 diff --git a/bin/Data/Maps/shop2.map.data b/bin/Data/Maps/shop2.map.data new file mode 100644 index 0000000..c90cdd4 --- /dev/null +++ b/bin/Data/Maps/shop2.map.data @@ -0,0 +1,10 @@ +10 +8 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/shop3.map b/bin/Data/Maps/shop3.map new file mode 100644 index 0000000..6f0e883 --- /dev/null +++ b/bin/Data/Maps/shop3.map @@ -0,0 +1,622 @@ +3 +0 +0 +house.png +10 +8 +3 +6,31,100,31,31,31,31,31,31,7, +30,51,81,51,51,51,51,51,61,33, +30,51,51,51,51,51,51,51,29,33, +30,51,51,1,1,1,1,51,51,33, +30,51,51,1,1,1,1,51,51,33, +30,51,51,49,1,1,1,51,51,33, +30,51,51,51,51,51,51,51,51,33, +9,32,32,32,39,38,32,32,32,8, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +66 +382;-24;48; +0;0;16;;; +0;0;32;;; +0;0;48;;; +0;0;64;;; +0;0;80;;; +0;0;96;;; +0;16;0;;; +0;16;112;;; +0;32;112;;; +0;48;0;;; +0;48;112;;; +0;64;0;;; +0;72;128;;; +0;80;0;;; +0;96;0;;; +0;96;112;;; +0;112;0;;; +0;112;112;;; +0;128;0;;; +0;128;112;;; +0;144;16;;; +0;144;32;;; +0;144;48;;; +0;144;64;;; +0;144;80;;; +0;144;96;;; +3;64;112;;; +4;80;112;;; +2;32;16;;; +153;72;120;;;s3;overworld.map;s3;1;; +299;72;112;;;;;; +284;-24;24;;220;180;125 +22;72;112;;;; +167;168;24;witch_lamp_lit;1 +302;96;80;;;;True;witch_lamp +9;48;80;;; +9;128;16;;; +9;128;32;;; +390;64;32 +287;-24;0;6 +164;72;112;blockWitchDoor;1;c1;; +164;168;0;witch_lamp;1;dialogBox;witch_lamp_lit; +357;64;64;witch;0.0.14.18;;idle +232;16;16;;;;;; +232;16;32;;heart;;;; +232;16;48;;;;;; +232;16;64;;;;;; +232;16;80;;;;;; +232;16;96;;heart;;;; +232;32;32;;;;;; +232;32;48;;powder_1;;;; +232;48;16;;;;;; +232;48;32;;heart;;;; +232;64;16;;;;;; +232;80;16;;;;;; +232;96;16;;;;;; +232;96;32;;;;;; +232;112;16;;heart;;;; +232;112;32;;;;;; +232;112;48;;powder_1;;;; +232;128;48;;;;;; +232;128;64;;;;;; +232;128;80;;;;;; +232;128;96;;;;;; +205;32;8;npc_house_chest;;;1 diff --git a/bin/Data/Maps/shop3.map.data b/bin/Data/Maps/shop3.map.data new file mode 100644 index 0000000..c90cdd4 --- /dev/null +++ b/bin/Data/Maps/shop3.map.data @@ -0,0 +1,10 @@ +10 +8 +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; +;;;;;;;;;; diff --git a/bin/Data/Maps/underwater fish.map b/bin/Data/Maps/underwater fish.map new file mode 100644 index 0000000..274964c --- /dev/null +++ b/bin/Data/Maps/underwater fish.map @@ -0,0 +1,643 @@ +3 +1 +1 +tileset 2d.png +12 +10 +3 +,,,,,,,,,,,, +,13,22,87,87,87,87,19,9,9,9,, +,22,87,87,87,87,87,87,19,9,9,, +,0,0,0,0,0,0,0,0,8,9,, +,0,0,0,0,0,0,0,0,0,9,, +,0,0,0,0,0,0,0,0,0,9,, +,0,0,0,0,0,0,0,0,4,9,, +,12,0,0,0,0,0,0,4,14,9,, +,13,12,0,4,0,0,4,14,9,9,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +,,,,,,,,,,,, +0,0,0,0,0,0,0,0,0,0,0,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +,,,,,,,,,,,0, +,,,,,,,,,,,0, +,,,,,,,,,,,0, +,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,,,,,,,,,,,0, +0,0,0,0,0,0,0,0,0,0,0,0, +523 +c1 +c2 +c5 +c3 +c4 +colliderL0 +colliderL1 +colliderL2 +colliderL3 +lowCollider16 +lowCollider0 +lowCollider1 +lowCollider2 +lowCollider3 +c13 +c6 +c7 +c8 +c9 +c10 +c11 +c12 +enemyWall +drownResetExclude +hookshotGrip +lowerLevelCollider +lowerLevelCollider1 +lowerLevelCollider2 +colliderLevel1 +raftCollider +c1PushIgnore +oneWayBridge2 +oneWayBridge0 +break_collider_end +break_sprite_start +tree0 +treeWoods +treeWoods2 +tree1 +tree2 +tree3 +tree4 +tree5 +stree +phonehouse +tree9 +seashell_house +strandplant +strandshell +dungeonOneStatue +dungeonOneStatueKey +dungeonStatue +dungeonStatueGrey +dungeonStatueD7 +caveFairyStatue +gravejardfence +desertpillar +phone +itemShop +armosStatue +armosDarkStatue +statueCastle +dungeon3Head +banana +npc_bag +statueD3 +statueD3Key +statueMermaid +mountainStone +dungeon7_keyhole +overworldDonut +cave_table +cave_bed +vase_empty +vase_flower +painting +owl_statue +photohouse_light +castle_roof_0 +castle_roof_1 +castle_roof_2 +castle_roof_3 +castle_roof_4 +castle_roof_5 +roof01 +roof02 +roof03 +roof04 +roof05 +roof06 +d5_entry +witch_house +seashell_post +stairsCastle +stairsWoods +dungeon_stairs +dungeon_6_stairs +break_sprite_end +wave1 +wave2 +wave6 +pondWoods +water1 +wave3 +wave4 +wave5 +water2 +water3 +water4 +water5 +waterFall +waterLeft +waterUp +waterRight +waterDown +flower +flowerforest +flowerforest2 +flower2 +flower3 +sand1 +sand2 +sand3 +2dPondWater +2dWaterDungeon +2dWaterDungeonDark +2dWater +2dWaterDungeon2 +colorTileRed +colorTileGreen +colorTileBlue +break_tile_end +tower_background +final_stairs +final_background +final_windfish +final_fountain +final_background_stairs +fence +fenceUL +fenceU +fenceUR +fenceL +fenceR +fenceDL +fenceD +fenceDR +fenceTR +fenceTL +fenceBR +fenceBL +break_fence_end +overworldObject +door +door2d +doorEgg +lowFloor +water +waterDeep +eggTeleporter +stairs +teleporter +jump +jumpRaft +objectSpawner +objectRespawner +positionDialog +keysetter +keyConditionSetter +button +leaveButton +buttonTouch +buttonOrder +scriptBox +dialogBox +scriptOnTouch +itemDisabler +shadowDisabler +shadowSetter +candyGrabber +candyGrabberControls +shellHouse +swordSpawner +waterCurrent0 +waterCurrent1 +waterCurrent2 +waterCurrent3 +waterCurrentFast0 +waterCurrentFast1 +waterCurrentFast2 +waterCurrentFast3 +quicksand +rollband +rollbandEdge +animatorL +fog +break_real_stuff_start +destroyableStone +weatherBird +chest +item +itemTester +storeItem +signpost +signpostWoods +sign +pushDialog +pushKeySetter +hitKeySetter +shellHitSpawner +sideWaves +aquaticPlant +stoneSpawner +bush +bushForest +gras +gras0 +gras1 +gras2 +gras3 +grasForest +grasSwamp +gravestone +moveStone +moveStoneCave +moveStoneFrogHouse +moveStoneD3 +leverStone +stone +stoneWoods +stoneSkull +pot +pot2 +pot2D +d6Statue +castleDoor +cactus +overworldTeleporter +bridge +pullBridge +waterFallSpawner +book +bed +raft +break_dungeon_start +dungeon +upperLevel +upperLevel2 +dungeonBlackRoom +roomDarkener +colorShift +dungeonKeyhole +enemytrigger +hitTrigger +killOrderTrigger +graveTrigger +objectHider +link2dspawner +dungeonLadder +dungeonLadderTop +dungeonPullLever +ddoor +dungeonEntrance +dungeonSixEntry +dungeon7_tower +mermaid_statue +destroyable_barrier +stoneWall +destroyableWallCave +destroyableWallColorDungeon +destroyableWallDungeon7 +dungeonCrystal +caveCrystal +crystalD4 +hardCrystal +caveBreakingFloor +caveBreakingFloor2 +caveBreakingFloor3 +dungeonHole +breakingFloorCastle +dungeon5BreakingFloor +dungeon2BreakingFloor +dungeon8BreakingFloor +breakingFloorHouse +dungeonBlacker +houseBlacker +caveBlacker +music +musicTiles +compassSound +shoreSound +dungeonFairy +dungeonBall +dungeonPillar +lava +lava2d +break_dungeon_start_real +light +caveLight +doorLight +dungeon2dLight +spriteLight +lamp +lamp2 +torch_d2_2d +torch_d4_2d +torch_d6_2d +lamp_wall_0 +lamp_wall_1 +lamp_wall_2 +lamp_wall_3 +lamp_wall_house_0 +lamp_wall_house_1 +lamp_wall_house_2 +lamp_wall_house_3 +lamp_wall_dt_0 +lamp_wall_dt_1 +lamp_wall_dt_2 +lamp_wall_dt_3 +torch_d4 +torch_d8 +dungeonWall +dungeonWall3 +dungeonWall3cracks +dungeon4Block +dungeon6Wall +dungeon7Wall +dungeon8Wall +dungeon8WallCracks +caveWallBottom +dungeonSwitch +dungeonOneWay +dungeonTeleporter +keyholeBlock +dungeonBarriere +dungeonBarriereOrange +dungeonBarriereRed +dungeonColorSwitch +break_dungeon_end +hole +visiblehole +fullHole +holeReset +holeTeleporter +doorEnding +boat +movingPlatform2D +chainPlatform +spikes2D +dungeonRollBand +dungeonOwl +dungeonHorseHead +colorJumpTile +spikes +iceBlock +break_hole_end +break_people_start +person +personNew +letterBoy +maria +mariaDisabler +grandmother +mariaDungeonEntry +owl +fisherman +alligator +raccoon +shopkeeper +tracy +mamu +manbo +walrus +walrusSwim +mermaid +ghost +lostBoy +photoMouse +chickenDude +painter +hippo +trendy +BowWow +npcMonkey +bobWowSmall +bird +cock +letterBird +letterBirdGreen +dogo +mouse +frog +butterfly +fairy +npcBat +npcColorDungeon +honeycomb +tarinZZZ +fish_small +fish_big +fishing_link +ballGame +ballChildrenAttacked +break_people_end +break_enemies_start +enemy_respawner +e1 +e2 +e_wingedOctorok +e3 +e4 +e5 +moblinSword +shroudedStalfos +stalfosKnight +e19 +e_moblinPigSword +e_darknutSpear +e_darknut +e_wallKnight +e_madBomber +e6 +e8 +e9 +e15 +e7 +e10 +e11 +e_antiFairy +e12 +polsVoice +e_dungeonGhost +e_bomber +e_pokey +e_spinyBeetle +e_tektite +e13 +stalfosGreen +e_armos +e_Vacuum +e_bombite +e_bombiteGreen +e16 +e17 +e18 +e20 +e_raven +e21 +e_giantGhini +zombie +zombieSpawner +e23 +e_Beetle +e_BeetleSpawner +spikedBeetle +goponga_flower +goponga_flower_giant +e_fish +cardboy +monkey +torchTrap +e_pairodd +maskMimic +e_ArmMimic +e_waterTektite +e_peahat +e_ironMask +e_star +e_flyingTile +e_wizzrobe +e_beamos +e_camoGoblin +e_bonePutter +e_karakoro +e_gibdo +e_antiKirby +e_vire +e_rope +e_flameFountain +e_floorLayer +e_rockSpawner +e_anglerFry +break_enemies_end +break_2d_start +e14 +e_CheepCheep +e_Bloober +e_giantBubble +e_thwimp +e_PiranhaPlant +e_MegaThwomp +e_SpikedThwomp +e_Podoboo +break_2d_end +break_mbosses_start +mb1 +mb_king_moblin +mb_hinox +mb_BallAndChainSoldier +mb_dodongo_snake +mb_desert_lanmola +mb_cue_ball +mb_MasterStalfos +mb_Gohma +mb_ArmosKnight +mb_Smasher +mb_StoneHinox +mb_GiantBuzzBlob +mb_GrimCreeper +mb_TurtleRock +mb_Blaino +break_mbosses_end +break_nightmare_start +nightmare-moldorm +nightmare_genie +nightmare_slime_eye +nightmare_angler_fish +nightmare_slime_eel +facade +nightmare_HardhitBeetle +nightmare_EvilEagle +nightmare_HotHead +nightmare +81 +126;16;48;;;;; +126;32;48;;;;; +126;48;48;;;;; +126;64;48;;;;; +126;80;48;;;;; +126;96;48;;;;; +126;112;48;;;;; +126;128;48;;;;; +0;16;32;;; +0;16;112;;; +0;32;16;;; +0;32;128;;; +0;48;144;;; +0;64;144;;; +0;80;144;;; +0;96;144;;; +0;112;16;;; +0;112;144;;; +0;128;32;;; +0;128;128;;; +0;144;48;;; +0;144;112;;; +0;160;64;;; +0;160;80;;; +0;160;96;;; +286;16;-16;;;; +153;0;48;;64;underwater_fish;overworld.map;underwater_fish;2;3; +257;-16;-16 +371;96;54; +287;48;-16;37 +158;0;48 +158;0;64 +158;0;80 +158;0;96 +158;16;48 +158;16;64 +158;16;80 +158;16;96 +158;32;48 +158;32;64 +158;32;80 +158;32;96 +158;32;112 +158;48;48 +158;48;64 +158;48;80 +158;48;96 +158;48;112 +158;48;128 +158;64;48 +158;64;64 +158;64;80 +158;64;96 +158;64;112 +158;64;128 +158;80;48 +158;80;64 +158;80;80 +158;80;96 +158;80;112 +158;80;128 +158;96;48 +158;96;64 +158;96;80 +158;96;96 +158;96;112 +158;96;128 +158;112;48 +158;112;64 +158;112;80 +158;112;96 +158;112;112 +158;112;128 +158;128;48 +158;128;64 +158;128;80 +158;128;96 +158;128;112 +158;144;64 +158;144;80 +158;144;96 diff --git a/bin/Data/Maps/underwater fish.map.data b/bin/Data/Maps/underwater fish.map.data new file mode 100644 index 0000000..966622a --- /dev/null +++ b/bin/Data/Maps/underwater fish.map.data @@ -0,0 +1,12 @@ +12 +10 +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; +;;;;;;;;;;;; diff --git a/bin/Data/Music/awakening.gbs b/bin/Data/Music/awakening.gbs new file mode 100644 index 0000000..0f53154 Binary files /dev/null and b/bin/Data/Music/awakening.gbs differ diff --git a/bin/Data/Photo Mode/photos.atlas b/bin/Data/Photo Mode/photos.atlas new file mode 100644 index 0000000..fa53636 --- /dev/null +++ b/bin/Data/Photo Mode/photos.atlas @@ -0,0 +1,20 @@ +1 +1 +:0,0,0,0,0,0 +photo_1:1,1,160,144,0,0 +photo_1_alt:162,1,160,144,0,0 +photo_2:323,1,160,144,0,0 +photo_3:1,146,160,144,0,0 +photo_4:162,146,160,144,0,0 +photo_5:323,146,160,144,0,0 +photo_6:1,291,160,144,0,0 +photo_7:162,291,160,144,0,0 +photo_8:323,291,160,144,0,0 +photo_9:1,436,160,144,0,0 +photo_10:162,436,160,144,0,0 +photo_11:323,436,160,144,0,0 +photo_12:1,581,160,144,0,0 +photo_book:162,581,174,115,0,0 +photo_no:338,581,24,16,0,0 +photo_ok:364,581,20,16,0,0 +photo_cursor:386,581,15,16,0,0 diff --git a/bin/Data/Photo Mode/photos.png b/bin/Data/Photo Mode/photos.png new file mode 100644 index 0000000..13895ee Binary files /dev/null and b/bin/Data/Photo Mode/photos.png differ diff --git a/bin/Data/Sequences/end sequence.atlas b/bin/Data/Sequences/end sequence.atlas new file mode 100644 index 0000000..00817c7 --- /dev/null +++ b/bin/Data/Sequences/end sequence.atlas @@ -0,0 +1,34 @@ +1 +1 +cloud_color_0:209,256,8,8,0,0 +cloud_color_1:218,256,8,8,0,0 +cloud_color_2:227,256,8,8,0,0 +cloud_color_3:236,256,8,8,0,0 +cloud_color_4:209,265,8,8,0,0 +cloud_color_5:218,265,8,8,0,0 +cloud_color_6:227,265,8,8,0,0 +cloud_color_7:236,265,8,8,0,0 +cloud_color_8:245,265,8,8,0,0 +cloud_color_9:254,265,8,8,0,0 +editor_final_platform:1184,32,16,16,0,1 +final_2:0,26,0,0,0,0 +final_background_stairs:1169,16,46,272,23,0 +final_barrel:321,161,14,13,0,0 +final_cloud:192,256,16,16,0,0 +final_fountain:36,22,16,16,0,0 +final_island:192,288,144,64,0,0 +final_island_background:16,256,160,144,0,0 +final_lay:12,592,360,48,0,0 +final_log:344,208,8,6,0,0 +final_log_2:305,167,14,7,0,0 +final_marin_ending:303,464,49,64,0,0 +final_s6:380,244,360,324,0,0 +final_sky:796,20,360,900,0,0 +final_sky_1:380,592,360,48,0,0 +final_sky_2:412,20,360,180,0,0 +final_stairs:192,48,16,16,0,0 +sun:624,848,32,32,0,0 +sun_0:659,852,5,5,0,0 +sun_1:659,858,6,6,0,0 +sun_2:659,865,9,9,0,0 +wale_sky:301,54,38,63,19,0 diff --git a/bin/Data/Sequences/end sequence.png b/bin/Data/Sequences/end sequence.png new file mode 100644 index 0000000..da488e1 Binary files /dev/null and b/bin/Data/Sequences/end sequence.png differ diff --git a/bin/Data/Sequences/game sequences.atlas b/bin/Data/Sequences/game sequences.atlas new file mode 100644 index 0000000..d13d705 --- /dev/null +++ b/bin/Data/Sequences/game sequences.atlas @@ -0,0 +1,19 @@ +1 +1 +:140,5,23,27,0,0 +link:38,7,31,25,0,0 +tower_background:8,80,160,144,0,0 +tower_top:176,80,32,79,0,0 +tower_bottom:56,176,64,48,0,0 +beach_background:8,232,320,128,0,0 +beach_palm:408,232,56,88,0,0 +cliff_background:8,368,160,144,0,0 +shrine:176,368,160,144,0,0 +trade_picture:368,6,103,128,0,0 +bowWow_background:344,368,160,144,0,0 +seqBowWowChain:269,64,8,8,4,4 +seqBowWowSmoke:240,48,16,16,11,16 +seqBowWowParticle:267,74,10,16,5,9 +seqCastleBackground:8,520,160,144,0,0 +seqGravestoneBackground:176,520,160,144,0,0 +seqWeatherBirdBackground:344,520,160,144,0,0 diff --git a/bin/Data/Sequences/game sequences.png b/bin/Data/Sequences/game sequences.png new file mode 100644 index 0000000..321cedb Binary files /dev/null and b/bin/Data/Sequences/game sequences.png differ diff --git a/bin/Data/Sequences/thanos noise.png b/bin/Data/Sequences/thanos noise.png new file mode 100644 index 0000000..9f8d5c9 Binary files /dev/null and b/bin/Data/Sequences/thanos noise.png differ diff --git a/bin/Data/Sequences/wind fish.atlas b/bin/Data/Sequences/wind fish.atlas new file mode 100644 index 0000000..2385f62 --- /dev/null +++ b/bin/Data/Sequences/wind fish.atlas @@ -0,0 +1,4 @@ +1 +1 +final_wale:0,0,160,112,16,16 +editor_windfish:51,60,16,16,0,0 diff --git a/bin/Data/Sequences/wind fish.png b/bin/Data/Sequences/wind fish.png new file mode 100644 index 0000000..73500c6 Binary files /dev/null and b/bin/Data/Sequences/wind fish.png differ diff --git a/bin/Data/musicOverworld.data b/bin/Data/musicOverworld.data new file mode 100644 index 0000000..6cd15b9 --- /dev/null +++ b/bin/Data/musicOverworld.data @@ -0,0 +1,130 @@ +160 +128 +5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5; +5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5; +5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5; +5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5; +5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5; +5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5; +5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5; +5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5; +5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5; +5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5; +5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5; +5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5; +5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5; +5;5;5;5;5;5;5;5;5;5;4;4;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5; +5;5;5;5;5;5;5;5;5;5;4;4;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5; +5;5;5;5;5;5;5;4;4;4;4;4;4;4;4;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5;5; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;5;4;4;4;4;4;4;4;4;4;5;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;5;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;8;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7;7; +8;8;8;8;8;8;8;8;8;8;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +8;8;8;8;8;8;8;8;8;8;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +8;8;8;8;8;8;8;8;8;8;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +8;8;8;8;8;8;8;8;8;8;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +8;8;8;8;8;8;8;8;8;8;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +8;8;8;8;8;8;8;8;8;8;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +8;8;8;8;8;8;8;8;8;8;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +8;8;8;8;8;8;8;8;8;8;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;10;10;10;10;10;10;10;10;10;10;10;10;10;10;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;10;10;10;10;10;10;10;10;10;10;10;10;10;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; +4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4;4; diff --git a/bin/Data/scripts.zScript b/bin/Data/scripts.zScript new file mode 100644 index 0000000..0610ec0 --- /dev/null +++ b/bin/Data/scripts.zScript @@ -0,0 +1,1822 @@ +// test scripts +test_sequence:0 -> [start_sequence:towerCollapse] + +test_dialog:0 -> [dialog:choice:npc_lost_boy_0:choice_Nope:choice_Cant] +test_dialog_1:0 -> [dialog:choice:npc_hippo_0:choice_Nope:choice_Cant] +test_dialog_2:0 -> [dialog:choice:npc_hippo_0:choice_Nope:choice_Cant:choice_Cant] +test_dialog_3:0 -> [dialog:choice:npc_hippo_0:choice_Nope:choice_Cant:choice_Nope:choice_Cant] + +test_sign_0:0 -> [music:53:1] -> [stop_music:3000:1] +test_sign_1:0 -> npc_tracy_8 + + +// overworld +overworld:0 -> [set:dungeon_1:0] -> [set:dungeon_2:0] -> [set:dungeon_3:0] -> [set:dungeon_4:0] -> [set:dungeon_5:0] -> [set:dungeon_6:0] -> [set:dungeon_7:0] -> [set:dungeon_8:0] -> [set:crystal_hard:0] -> [set:pondReset:0] -> [set:rabbit_0Jump:533] -> [set:rabbit_1Jump:533] -> [set:rabbit_3Jump:533] -> [path:overworldMusic] + +// before the sword is collected the overworld music is changed +overworldMusic:introMusic:1 -> [music:28:1] +overworldMusic:0 -> + +// before the sword is collected the house music is changed +houseMusic:introMusic:1 -> [music:28:1] +houseMusic:0 -> + +bowWowHouse:villageAttacked:1 -> [set:npc09Jump:1125] -> [set:npc09Range:128] -> [music:13:2] +bowWowHouse:0 -> + +ocarina:0 -> ocarina + +// dungeon intro text +dungeon_1:0 -> dungeon_1 -> [set:1] +dungeon_1:1 -> + +dungeon_2:0 -> dungeon_2 -> [set:1] +dungeon_2:1 -> + +dungeon_3:0 -> dungeon_3 -> [set:1] +dungeon_3:1 -> + +dungeon_4:0 -> dungeon_4 -> [set:1] +dungeon_4:1 -> + +dungeon_5:0 -> dungeon_5 -> [set:1] +dungeon_5:1 -> + +dungeon_6:0 -> dungeon_6 -> [set:1] +dungeon_6:1 -> + +dungeon_7:0 -> dungeon_7 -> [set:1] +dungeon_7:1 -> + +dungeon_8:0 -> dungeon_8 -> [set:1] +dungeon_8:1 -> + +// maria in the house +marin_intro:0 -> maria_0_0 -> [set:maria:1] -> [set:tarin:0] -> [set:introMusic:1] + +maria:1 -> maria_0_1 + +// maria standing outside and singing +// tarin is missing +marin_start_singing:0 -> [wait:dialogOpen:0] -> [set:maria_sing:1] +marin_start_singing_animals:0 -> [wait:dialogOpen:0] -> [set:maria_sing_animals:1] + +maria:2 -> maria_1_0 -> [path:marin_start_singing] +maria:1_1 -> maria_1_1 -> [path:marin_start_singing] +// tarin sleeping +maria:1_2 -> maria_1_2 -> [path:marin_start_singing] + +maria:4 -> maria_1_8 -> [set:3] + +maria:marin_thanks:1 -> marin_5_0 -> [set:marin_thanks:] + +// tarin is back -> sing +maria:maria_state:1 -> [check_item:ocarina_maria:1:learned_song] -> [path:maria_learned_song] +// in the right village +maria:maria_state:4 -> [check_item:ocarina_maria:1:learned_song] -> [path:maria_learned_song_2] + +maria:maria_state:6 -> [check_item:ocarina_maria:1:learned_song] -> [path:maria_learned_song_3] + +// coming out of the dungeon +marin_dungeon_leave:marin_dungeon_hearts:1 -> marin_dungeon_hearts +marin_dungeon_leave:marin_dungeon_hearts:2 -> marin_dungeon_hearts_alt +marin_dungeon_leave:marin_dungeon_time:1 -> marin_dungeon_leave_time +marin_dungeon_leave:0 -> marin_dungeon_leave + +// digging while marin is following the player +dig_dialog:maria_state:3 -> [countdown:100] -> marin_digging +dig_dialog:0 -> + +break_pot:maria_state:3 -> [path:marin_break_pot_dungeon] +break_pot:0 -> +// dont show the message in the dungeon when marin is not following the player +marin_break_pot_dungeon:maria_dungeon:0 -> [path:marin_break_pot] +marin_break_pot_dungeon:maria_dungeon:1 -> +marin_break_pot:0 -> [countdown:275] -> marin_pot_0 -> [set:1] +marin_break_pot:1 -> [countdown:275] -> marin_pot_1 + +// hitting a bird +bird_hit:maria_state:3 -> [path:bird_hit_marin] +bird_hit:0 -> + +bird_hit_marin:0 -> marin_cucco_0 -> [set:1] +bird_hit_marin:1 -> marin_cucco_1 + +// marin in the mountains +marin_help:0 -> [update_objects] -> marin_4_0 -> marin_4_1 +marin_saved:0 -> [save_history:true] -> [set:link_direction:2] -> [freeze:250] -> marin_4_2 -> marin_4_3 -> marin_4_4 -> [set:seq_tarin:1] -> [set:seqTarinFade:-125] -> [set:seqTarinMove:72,0,1] -> [freeze:seqTarinMoving:0] -> [set:seqTarinAnimation:stand_1] -> [set:maria_play_animation:stand_3] -> marin_4_5 -> [freeze:600] -> [set:link_direction:3] -> marin_4_6 -> [freeze:600] -> [set:maria_play_animation:stand_0] -> [set:seqTarinAnimation:-] -> [set:seqTarinMove:-72,0,0.5] -> [set:maria_walk:0,14,0.5] -> [freeze:1] -> [set:maria_walk:-14,0,0.5] -> [freeze:marinMoving:0] -> [set:maria_play_animation:stand_1] -> [freeze:1000] -> [set:seqTarinFade:125] -> [freeze:500] -> [set:maria_walk:-64,0,0.75] -> [freeze:1000] -> [set:maria_fade:125] -> [set:seq_tarin:0] -> [set:marin_thanks:1] -> [set:owl:8_0] -> [save_history:false] + +npc08:0 -> npc08_0 +npc08:1 -> npc08_1 + +// lost boy on the mountain +npc_lost_boy:0 -> [check_item:trade6:1:has_item] -> [path:npc_lost_boy_item] +npc_lost_boy:1 -> npc_lost_boy_4 + +npc_lost_boy_item:has_item:0 -> [dialog:choice:npc_lost_boy_0:choice_Nope:choice_Cant] -> [path:npc_lost_boy_choice_0] +npc_lost_boy_item:has_item:1 -> [dialog:choice:npc_lost_boy_0:choice_Yes:choice_Nope] -> [path:npc_lost_boy_choice_1] +// do not have the item so we cant trade it +npc_lost_boy_choice_0:choice:0 -> npc_lost_boy_1 +npc_lost_boy_choice_0:choice:1 -> npc_lost_boy_1 + +// trading sequence +npc_lost_boy_choice_1:choice:0 -> [save_history:true] -> [remove_item:trade6:1:result] -> npc_lost_boy_2 -> [wait:dialogOpen:0] -> [music_speed:1.5] -> [set:npc_lost_boy_eat:1] -> [freeze:3300] -> [music_speed:1] -> npc_lost_boy_3 -> [wait:dialogOpen:0] -> [add_item:trade7:1] -> [set:ow_npc_bag:0] -> [set:npc_lost_boy_state:2] -> [set:npc08:1] -> [set:npc07:0] -> [set:npc_lost_boy:1] -> [save_history:false] +npc_lost_boy_choice_1:choice:1 -> npc_lost_boy_1 + +// not learned song -> check ocarina || learned song -> just sing +maria_learned_song:learned_song:0 -> [check_item:ocarina:1:has_ocarina] -> [path:marin_singing] +maria_learned_song:learned_song:1 -> maria_1_1 -> [path:marin_start_singing] +// no ocarina -> sing for herself || ocarina -> teach song +marin_singing:has_ocarina:0 -> maria_1_1 -> [path:marin_start_singing] +marin_singing:has_ocarina:1 -> maria_1_3 -> [wait:dialogOpen:0] -> [freeze:350] -> [set:maria_start_duo:1] + +maria_learned_song_3:learned_song:0 -> [check_item:ocarina:1:has_ocarina] -> [path:marin_singing] +maria_learned_song_3:learned_song:1 -> [path:marin_learned_song] +// learned the song after getting saved +marin_learned_song:0 -> maria_1_8 -> [set:1] +marin_learned_song:1 -> marin_5_1 + +maria_learned_song_2:learned_song:0 -> [check_item:ocarina:1:has_ocarina] -> [path:marin_singing_2] +maria_learned_song_2:learned_song:1 -> maria_1_9 -> [path:marin_start_singing_animals] +marin_singing_2:has_ocarina:0 -> maria_1_9 -> [path:marin_start_singing_animals] +marin_singing_2:has_ocarina:1 -> maria_1_3 -> [wait:dialogOpen:0] -> [freeze:350] -> [set:maria_start_duo:1] + +marin_singing_end:0 -> [dialog:choice:maria_1_4:choice_Yes:choice_No] -> [path:maria_song_repeat] + +// get the song || replay the song +maria_song_repeat:choice:0 -> [set:maria:4] -> [add_item:ocarina_maria:1] +maria_song_repeat:choice:1 -> maria_1_6 -> [wait:dialogOpen:0] -> [freeze:350] -> [set:maria_start_duo:1] + +// maria at the beach +maria:6 -> [dialog:choice:marin_2_0:choice_Yes!:choice_No...] -> [path:maria_beach_choice] +maria_beach_choice:choice:0 -> [set:maria:7] -> [start_sequence:marinBeach] +maria_beach_choice:choice:1 -> marin_2_1 + +maria:7 -> + +ocarina_bad:maria_state:3 -> ocarina_bad_marin +ocarina_bad:0 -> ocarina_bad + +// rooster wake up dialog +rooster:0 -> [save_history:true] -> [set:chicken_dude:1] -> [set:has_rooster:1] -> [set:ulrira_d7:2] -> [freeze:1000] -> rooster_0 -> [save_history:false] + +// ghost grave powder dialog +ghost_grave_powder_dialog:has_ghost:0 -> [set:ghost_grave_powder:0] +ghost_grave_powder_dialog:0 -> ghost_grave_powder -> [set:ghost_grave_powder:0] + +// ghost +ghost_start_following:0 -> [set:has_ghost:1] -> [set:ghost_blockade:1] -> [set:ulrira_ghost:1] + +ghost_return:0 -> [cooldown:60000:result] -> [path:ghost_return_cooldown] +ghost_return:1 -> +ghost_return_cooldown:result:0 -> +ghost_return_cooldown:result:1 -> [sound:D360-45-2D] -> [path:ghost_return_dialog] +ghost_return_dialog:0 -> ghost_0 +ghost_return_dialog:1 -> ghost_5 + +// go in dialog +ghost_house_dialog:0 -> [path:ghost_house_dialog_check] +ghost_house_dialog:1 -> +ghost_house_dialog_check:has_ghost:0 -> +ghost_house_dialog_check:has_ghost:1 -> [cooldown:60000:result] -> [path:ghost_house_dialog_cooldown] +ghost_house_dialog_cooldown:result:0 -> +ghost_house_dialog_cooldown:result:1 -> ghost_2 + +// house sequence +ghost_house_sequence:has_ghost:0 -> +ghost_house_sequence:has_ghost:1 -> [path:ghost_house_seq] +ghost_house_seq:0 -> [save_history:true] -> [set:1] -> [set:ghost_return_dialog:1] -> [set:ghost_house_dialog:1] -> [set:ghost_move:0,-56,0.5] -> [freeze:2500] -> [set:ghost_move:-21,-10,0.5] -> [freeze:2000] -> [set:ghost_move:-10,-21,0.5] -> [freeze:1700] -> [set:ghost_move:53,13,0.5] -> [freeze:3100] -> ghost_3 -> [set:ghost_move:-20,50,0.5] -> [freeze:1750] -> ghost_4 -> [set:ghost_follow:1] -> [wait:dialogOpen:0] -> [set:link_move:0,1] -> [set:lock_player:1000] -> [save_history:false] +ghost_house_seq:1 -> + +// grave sequence +ghost_grave_sequence:has_ghost:0 -> +ghost_grave_sequence:has_ghost:1 -> [update_objects] -> [save_history:true] -> [set:ghost_blockade:0] -> [set:ghost_return:1] -> [set:ghost_shell:1] -> [freeze:2000] -> ghost_6 -> [wait:dialogOpen:0] -> [set:ghost_fade:175] -> [freeze:500] -> [remove_item:ghost:1:result] -> [set:has_ghost:0] -> [set:ulrira_ghost:0] -> [set:owl:5_0] -> [save_history:false] + + +// beach sequence +seq_beach:0 -> [save_history:true] -> [music:77:2] -> [countdown:2000] -> [set:1] -> [path:seq_beach] +seq_beach:1 -> marin_2_2 -> [wait:dialogOpen:0] -> [seq_play:marin:ocean_look] -> [countdown:3300] -> marin_2_3 -> [wait:dialogOpen:0] -> [seq_play:marin:ocean_look] -> [countdown:4000] -> [seq_play:marin:ocean_ask] -> [dialog:choice:marin_2_4:choice_Yeah:choice_No...] -> [path:maria_beach_listening] +maria_beach_listening:choice:0 -> marin_2_6 -> [set:seq_beach:2] -> [wait:dialogOpen:0] -> [seq_play:marin:ocean_sit] -> [countdown:750] -> [path:seq_beach] +maria_beach_listening:choice:1 -> marin_2_5 -> [set:seq_beach:1] -> [wait:dialogOpen:0] -> [seq_play:marin:ocean_sit] -> [countdown:750] -> [path:seq_beach] +seq_beach:2 -> [seq_play:marin:ocean_ask] -> marin_2_7 -> [wait:dialogOpen:0] -> [countdown:1000] -> [close_overlay] -> [music:-1:2] -> [set:maria:7] -> [set:maria_state:3] -> [add_item:marin:1] -> [set:has_marin:1] -> [save_history:false] + +// block walking into dungeons when the ghost is following the player +ghost_blockade:0 -> +ghost_blockade:1 -> ghost_1 + + +// waking up the walrus +walrus:has_marin:0 -> [update_objects] -> walrus_0 +walrus:has_marin:1 -> [update_objects] -> [dialog:choice:maria_3_0:choice_Yes:choice_No...] -> [path:walrus_choice] +walrus_choice:choice:0 -> [path:walrus_sequence] +walrus_choice:choice:1 -> marin_3_1 +walrus_sequence:0 -> [update_objects] -> [save_history:true] -> [set:maria_sing_walrus:1] -> [set:walrus_despawn:1] -> [set:walrus_dance:1] -> [freeze:16000] -> [set:maria_stop_singing:1] -> [set:maria_play_animation:stand_2] -> [set:link_direction:2] -> [freeze:750] -> [set:maria_play_animation:stand_3] -> [set:link_direction:3] -> maria_3_2 -> [wait:dialogOpen:0] -> [freeze:500] -> [set:seq_rabit:1] -> [set:seqRabitFade:-100] -> [set:seqRabitMove:96,0,0.75] -> [freeze:1000] -> [set:maria_play_animation:stand_0] -> [set:link_direction:0] -> [freeze:1500] -> [set:seqRabitJump:1000] -> [freeze:500] -> maria_3_3 -> [freeze:50] -> [wait:dialogOpen:0] -> [set:maria_play_animation:stand_2] -> [freeze:50] -> maria_3_4 -> [wait:dialogOpen:0] -> [set:seqRabitMove:-128,0,1.25] -> [freeze:250] -> [set:maria_walk:-128,0,0.75] -> [freeze:750] -> [set:seqRabitFade:100] -> [freeze:750] -> [set:maria_fade:100] -> [freeze:100] -> [remove_item:marin:1:result] -> [set:has_marin:0] -> [set:maria_state:4] -> [set:seq_rabit:0] -> [set:hide_rabbit_0:1] -> [set:hide_rabbit_1:1] -> [set:hide_rabbit_2:1] -> [set:hide_rabbit_3:1] -> [set:npc_chef:2] -> [set:npc_boy_0:2] -> [set:npc_boy_1:3] -> [set:npc_boy_2:1] -> [set:npc_boy_ball_left:2] -> [set:npc_boy_ball_right:2] -> [set:tarin:7] -> [set:tarin_state:6] -> [save_history:false] + +walrus_swim:0 -> [update_objects] -> walrus_1 + +// show a different message when marin is following the player +npc_house_chest:has_marin:1 -> npc_house_chest_marin +npc_house_chest:0 -> npc_house_chest + +bookcase:has_marin:1 -> npc_house_chest_marin +bookcase:0 -> bookcase + +// tarin house +// can not look into the chest while tarin is around awake +tarin_chest:tarin_state:0 -> tarin_chest +tarin_chest:tarin_state:3 -> tarin_chest +tarin_chest:0 -> [path:npc_house_chest] + +// tarin +tarin:0 -> tarin_0 -> [add_item:shield:1] -> [set:1] +tarin:1 -> tarin_1 + +// tarin is in the woods +// raccoon sequence +raccoon:0 -> raccoon_0 +// warning message shown before the teleport point +raccoon_warning:0 -> [update_objects] -> raccoon_1 -> [set:raccoon_warning:1] +raccoon_warning:1 -> + +raccoon_transformed:0 -> tarin_raccoon_2 -> [set:1] -> [set:tarin:2] -> [set:tarin_state:2] -> [set:maria:1_2] -> [set:raccoon_warning:] +tarin_healed:0 -> tarin_raccoon_3 + +// tarin sleeping +tarin:2 -> tarin_2 +tarin:3 -> tarin_3 +// banana +tarin:4 -> tarin_4 + +// collecting the stick => tarin stands next to the tree after the stick is collected +trade4:0 -> trade4 -> [set:tarin:5] -> [set:tarin_state:4] + +// tarin trading sequence +tarin:5 -> [dialog:choice:tarin_stick:choice_Can:choice_Cant] -> [path:tarin_stick] +tarin_stick:choice:0 -> [save_history:true] -> [remove_item:trade4:1:result] -> [set:tarinAnimation:show] -> [set:tarinStickAnimation:show] -> [music:-1:-1] -> [sound:D360-01-01] -> [freeze:1800] -> [set:tarinAnimation:walk_0] -> [set:tarinStickAnimation:walk_0] -> [set:tarinMove:-3,-18,0.75] -> [freeze:225] -> [set:link_direction:1] -> [freeze:tarinMoving:0] -> [set:tarinAnimation:stick_down] -> [set:tarinStickAnimation:stick_down] -> [freeze:50] -> [music:51:2] -> [freeze:500] -> [set:tarinAnimation:stick_up] -> [set:tarinStickAnimation:stick_up] -> [freeze:550] -> [set:honeycombHit:1] -> [set:tarinAnimation:stick_down] -> [set:tarinStickAnimation:stick_down] -> [freeze:550] -> [set:honeycombReset:1] -> [set:tarinAnimation:stick_up] -> [set:tarinStickAnimation:stick_up] -> [freeze:550] -> [set:honeycombHit:1] -> [set:tarinAnimation:stick_down] -> [set:tarinStickAnimation:stick_down] -> [freeze:550] -> [set:honeycombReset:1] -> [set:tarinAnimation:stick_up] -> [set:tarinStickAnimation:stick_up] -> [freeze:550] -> [set:tarinAnimation:-] -> [set:tarinStickAnimation:] -> [set:tarinJump:1.75,-0.125] -> [freeze:550] -> [path:bee_chase] -> [save_history:false] +tarin_stick:choice:1 -> tarin_stick_no + +// bee chase +bee_chase:0 -> [save_history:true] -> [set:honeycombAttack:1] -> [set:tarinMove:22,0,2] -> [freeze:0] -> [set:beeTargetMove:56,6,2.5] -> [freeze:1] -> [set:tarinMove:0,-44,2] -> [set:beeTargetMove:0,-44,2] -> [freeze:1] -> [set:tarinMove:-80,0,2] -> [set:beeTargetMove:-80,0,2] -> [freeze:1] -> [set:tarinMove:0,80,2] -> [set:beeTargetMove:0,80,2] -> [freeze:1] -> [set:tarinMove:80,0,2] -> [set:beeTargetMove:80,0,2] -> [freeze:1] -> [set:tarinMove:0,-80,2] -> [set:beeTargetMove:0,-80,2] -> [freeze:1] -> [set:tarinMove:-80,0,2] -> [set:beeTargetMove:-80,0,2] -> [freeze:1] -> [set:tarinMove:0,80,2] -> [set:beeTargetMove:0,80,2] -> [freeze:1] -> [set:tarinMove:80,0,2] -> [set:beeTargetMove:80,0,2] -> [freeze:1] -> [set:tarinMove:0,-80,2] -> [set:beeTargetMove:0,-80,2] -> [freeze:1] -> [set:tarinMove:-80,0,2] -> [set:beeTargetMove:-80,0,2] -> [freeze:1] -> [set:tarinMove:-50,25,2.5] -> [set:beeTargetMove:-50,25,2.25] -> [freeze:tarinMoving:0] -> [set:tarinMove:-50,25,2.5] -> [set:beeTargetMove:-50,25,2.25] -> [set:tarinFade:125] -> [freeze:100] -> [set:honeycombFade:125] -> [freeze:400] -> [set:honeycombFall:1] -> [set:ow_honeycomb_fallen:1] -> [set:tarin:6] -> [set:tarin_state:5] -> [countdown:1500] -> [music:-1:2] -> [save_history:false] + +// tarin sleeping after the trading sequence +tarin:6 -> tarin_5 + +shield_intro:0 -> shield_intro -> [set:1] +shield_intro:1 -> + +sword1Collected:0 -> [update_objects] -> [save_history:true] -> sword1 -> [countdown:750] -> [music:-1:1] -> [music:-1:2] -> [stop_music] -> [set:introMusic:0] -> [wait:dialogOpen:0] -> [music:48:0] -> [save_history:false] +sword2Collected:0 -> [sound:D368-16-10] -> sword2 -> [set:hasSword2:1] + +heartMeterFilled:0 -> heartMeterFilled -> [sound:D360-25-19] + +heartMeterFull:0 -> [music:-1:2] + +maria_collected:0 -> [music:-1:-1] -> maria_collected -> [wait:dialogOpen:0] -> [music:48:0] + +goldLeaf:0 -> goldLeaf -> [set:1] +goldLeaf:1 -> goldLeaf -> [set:2] +goldLeaf:2 -> goldLeaf -> [set:3] +goldLeaf:3 -> goldLeaf -> [set:4] +goldLeaf:4 -> goldLeafLast + +// don't show any message? +door_smallkey:0 -> + +toadstool_check:0 -> [check_item:toadstool:1:has_toadstool] -> [check_item:powder:1:has_powder] + +toadstool_hole:0 -> [freeze:550] -> toadstool_hole + +// only show the message when at least 60 seconds have passed and the player does not have a stonelifter +stone:0 -> [check_item:stonelifter:1:has_stonelifter] -> [check_item:stonelifter2:1:has_stonelifter2] -> [cooldown:600000:result] -> [path:stone_cooldown] +stone_cooldown:result:0 -> +stone_cooldown:result:1 -> [path:stone_message] +stone_message:has_stonelifter:1 -> +stone_message:has_stonelifter2:1 -> +stone_message:0 -> stone + +ice_block:0 -> [cooldown:600000:result] -> [path:ice_block_cooldown] +ice_block_cooldown:result:0 -> +ice_block_cooldown:result:1 -> ice_block_message + +rock_cracks:0 -> [cooldown:600000:result] -> [path:rock_cracks_cooldown] +rock_cracks_cooldown:result:0 -> +rock_cracks_cooldown:result:1 -> rock_cracks_message + +// Ulrira +// show an init message one time +npc04:0 -> npc04 -> npc04_game + +phone:0 -> phone_1 -> [set:1] + +// green boy next to the game house +npc_boy_0:grandma_gone_dialog:1 -> npc_boy_grandmother +npc_boy_0:maria_state:3 -> npc_boy_marin_following +npc_boy_0:0 -> [path:npc05_help] +npc_boy_0:1 -> npc_boy_island +npc_boy_0:2 -> npc_boy_marin_gone + +// village +npc_boy_1:grandma_gone_dialog:1 -> npc_boy_grandmother +npc_boy_1:maria_state:3 -> npc_boy_marin_following +npc_boy_1:0 -> [path:npc05_help] +npc_boy_1:1 -> npc_boy_marin +npc_boy_1:2 -> npc_boy_shrine +npc_boy_1:3 -> npc_boy_marin_gone + +// boy next to the rooster statue +npc_boy_2:grandma_gone_dialog:1 -> npc_boy_grandmother +npc_boy_2:maria_state:3 -> npc_boy_marin_following +npc_boy_2:0 -> npc_boy_marin_beach +npc_boy_2:1 -> npc_boy_marin_gone +npc_boy_2:2 -> npc_boy_island + +// boys playing ball +npc_boy_ball_left:grandma_gone_dialog:1 -> npc_boy_grandmother +npc_boy_ball_left:maria_state:3 -> npc_boy_marin_following +npc_boy_ball_left:0 -> [path:npc05_help] +npc_boy_ball_left:1 -> npc_ball_left +npc_boy_ball_left:2 -> npc_boy_marin_gone + +npc_boy_ball_right:grandma_gone_dialog:1 -> npc_boy_grandmother +npc_boy_ball_right:maria_state:3 -> npc_boy_marin_following +npc_boy_ball_right:0 -> [path:npc05_help] +npc_boy_ball_right:1 -> npc_ball_right +npc_boy_ball_right:2 -> npc_boy_marin_gone + +// attacked ball boys +npc_kid_attacked:0 -> [update_objects] -> npc_kid_attacked + +npc05_help:0 -> npc05_1 -> [set:1] +npc05_help:1 -> npc05_2 -> [set:2] +npc05_help:2 -> npc05_3 -> [set:0] +//npc05_help:3 -> npc05_3 -> [set:0] + +// Family house +// husband lost in the mountains +npc07:1 -> npc07_5 +npc07:trade0:0 -> [check_item:trade0:1:result] -> [path:npc07_traded] +npc07:trade0:1 -> npc07_0 + +npc07_traded:result:0 -> npc07_0 -> npc07_1 +npc07_traded:result:1 -> [dialog:choice:npc07_2:choice_Yes:choice_No] -> [path:npc07_trade] + +npc07_trade:choice:0 -> npc07_4 -> [save_history:true] -> [remove_item:trade0:1:result] -> [add_item:trade1:1] -> [set:trade0:1] -> trade0 -> [save_history:false] +npc07_trade:choice:1 -> npc07_3 + +// girl in the bowwow house +// BowWow is missing +npc09:bowWow:1 -> npc09_1 +// give BowWow back +npc09:bowWow:3 -> npc09_3 -> [wait:dialogOpen:0] -> [set:bowWow:4] -> [set:has_bowWow:0] -> [set:ulrira:3_1] -> [fill_hearts] +// player has bowwow and not finished the second dungeon +npc09:has_bowWow:1 -> npc09_2 + +npc09:0 -> npc09_0 + +bowWow2:0 -> bowWow2 + +npc12:0 -> npc10_0 + +npc_chef:maria_state:3 -> [set:npc_chefAnimation:left] -> npc_chef_marin -> [wait:dialogOpen:0] -> [set:npc_chefAnimation:idle] + +npc_chef:0 -> [set:npc_chefAnimation:left] -> [check_item:trade5:1:result] -> [path:npc_chef_item] +npc_chef:1 -> [set:npc_chefAnimation:left] -> npc_chef_4 -> [wait:dialogOpen:0] -> [set:npc_chefAnimation:idle] +npc_chef:2 -> [set:npc_chefAnimation:left] -> npc_chef_0 -> [wait:dialogOpen:0] -> [set:npc_chefAnimation:idle] + +npc_chef_item:result:0 -> npc_chef_1 -> [wait:dialogOpen:0] -> [set:npc_chefAnimation:idle] +npc_chef_item:result:1 -> [dialog:choice:npc_chef_2:choice_Yes:choice_No] -> [path:npc_chef_trade] + +npc_chef_trade:choice:0 -> [save_history:true] -> [remove_item:trade5:1:result] -> [add_item:trade6:1] -> [sound:D368-16-10] -> [set:npc_chef:1] -> [set:pineapple_gone:1] -> [set:npc_chefAnimation:idle] -> [save_history:false] +npc_chef_trade:choice:1 -> npc_chef_3 -> [wait:dialogOpen:0] -> [set:npc_chefAnimation:idle] + +// marin at the beach; boy getting lost in the mountains +trade6Collected:0 -> [save_history:true] -> trade6 -> [wait:player_shows_item:0] -> [freeze:250] -> npc_chef_4 -> [set:maria_state:2] -> [set:maria:6] -> [set:npc_lost_boy_state:1] -> [set:ow_npc_bag:1] -> [set:npc07:1] -> [set:spawned_npc_boy_2:1] -> [save_history:false] + +// small bowwow +bowWow3:0 -> bowWow3_0 -> [check_item:trade1:1:result] -> [path:bowWow3_trade] +bowWow3_trade:result:1 -> [dialog:choice:bowWow3_1:choice_Yes:choice_No!] -> [path:bowWow3_traded] +bowWow3_trade:result:0 -> + +bowWow3_traded:choice:0 -> [sound:D370-24-18] -> bowWow3_3 -> [save_history:true] -> [remove_item:trade1:1:result] -> [set:trade1:1] -> [add_item:trade2:1] -> trade1 -> [save_history:false] +bowWow3_traded:choice:1 -> [sound:D370-24-18] -> bowWow3_2 + +bowWow_dig:0 -> [cooldown:5000:result] -> [path:bowWow_dig_cooldown] +bowWow_dig_cooldown:result:0 -> +bowWow_dig_cooldown:result:1 -> bowWow_dig + +// fisherman +npc_fisherman:0 -> npc_fisherman_0 -> [dialog:choice:npc_fisherman_choice:choice_Fish:choice_Not_Now] -> [path:npc_fisherman_choice] +npc_fisherman_choice:choice:0 -> [check_item:ruby:10:result] -> [path:npc_fisherman_money] +npc_fisherman_choice:choice:1 -> npc_fisherman_1 + +npc_fisherman_money:result:0 -> npc_fisherman_2 +npc_fisherman_money:result:1 -> [remove_item:ruby:10:result] -> npc_fisherman_3 -> [set:enterPond:yes] + +// fisherman under the bridge +npc_bridge:0 -> [set:npc_bridgeAnimation:look] -> [check_item:trade10:1:result] -> [path:npc_bridge_trade] +npc_bridge:1 -> [path:npc_bridge_trade_finished] + +npc_bridge_trade:result:0 -> [path:npc_bridge_trade_finished] +npc_bridge_trade:result:1 -> [dialog:choice:npc_bridge_1:choice_Okay:choice_No] -> [path:npc_bridge_choice] + +npc_bridge_choice:choice:0 -> [save_history:true] -> [remove_item:trade10:1:result] -> npc_bridge_3 -> [freeze:dialogOpen:0] -> [music_speed:1.75] -> [set:npc_bridgeAnimation:look] -> [set:npc_bridgeAnimation:idle] -> [freeze:800] -> [set:npc_bridgeAnimation:down] -> [freeze:200] -> [set:npc_bridgeAnimation:idle] -> [freeze:300] -> [set:npc_bridgeAnimation:down] -> [freeze:100] -> [set:npc_bridgeAnimation:idle] -> [freeze:400] -> [set:npc_bridgeAnimation:down] -> [freeze:100] -> [set:npc_bridgeAnimation:idle] -> [freeze:300] -> [set:npc_bridgeAnimation:down] -> [freeze:150] -> [set:npc_bridgeAnimation:idle] -> [freeze:150] -> [set:npc_bridgeAnimation:pull] -> [freeze:800] -> [set:npc_bridgeAnimation:pull_look] -> npc_bridge_4 -> [wait:dialogOpen:0] -> [set:npc_bridgeAnimation:pull] -> [freeze:500] -> [set:npc_bridgeAnimation:idle] -> [music_speed:1.0] -> [set:spawn_necklace:1] -> [freeze:1000] -> [set:npc_bridge:1] -> [save_history:false] +npc_bridge_choice:choice:1 -> [set:npc_bridgeAnimation:look] -> npc_bridge_2 + +// already traded? +npc_bridge_trade_finished:bridge_photo:0 -> [path:photo_sequence_bridge] +npc_bridge_trade_finished:0 -> npc_bridge_5 + +trade11:0 -> [set:npc_bridgeAnimation:look] -> trade11 -> [wait:dialogOpen:0] -> [freeze:500] + +// letter boy over the forest +npc_letter_boy:0 -> [check_item:trade8:1:result] -> [path:npc_letter_boy_item] +npc_letter_boy:1 -> npc_letter_boy_4 -> [set:2] +npc_letter_boy:2 -> npc_letter_boy_5 + +npc_letter_boy_item:result:0 -> npc_letter_boy_0 +npc_letter_boy_item:result:1 -> npc_letter_boy_1 -> [wait:dialogOpen:0] -> [start_sequence:picture] + +close_picture:0 -> [freeze:250] -> [dialog:choice:npc_letter_boy_2:choice_Fine:choice_No...] -> [path:npc_letter_boy_choice] + +npc_letter_boy_choice:choice:0 -> [save_history:true] -> [remove_item:trade8:1:result] -> [add_item:trade9:1] -> [set:ulrira_wife:1] -> [set:npc_letter_boy:1] -> [set:missing_broom:1] -> [path:grandma_gone_check] +npc_letter_boy_choice:choice:1 -> [path:npc_letter_boy_please] + +grandma_gone_check:npc_grandmother_moved:0 -> [set:grandma_gone_dialog:0] -> [save_history:false] +grandma_gone_check:npc_grandmother_moved:1 -> [check_item:trade9:1:result] -> [path:grandma_gone_check_broom] +grandma_gone_check_broom:result:0 -> [set:grandma_gone_dialog:0] -> [save_history:false] +grandma_gone_check_broom:result:1 -> [set:grandma_gone_dialog:1] -> [save_history:false] + +npc_letter_boy_please:0 -> [dialog:choice:npc_letter_boy_3:choice_Fine:choice_No_Way] -> [path:npc_letter_boy_choice] + +// mermaid in the water +npc_mermaid_dive:0 -> [freeze:250] -> npc_mermaid_1 -> [wait:dialogOpen:0] -> [freeze:100] -> [set:npc_mermaid_dive:1] -> [freeze:350] + +npc_mermaid:0 -> [check_item:trade11:1:result] -> [path:npc_mermaid_item] +npc_mermaid:1 -> npc_mermaid_5 + +npc_mermaid_item:result:0 -> npc_mermaid_0 +npc_mermaid_item:result:1 -> [dialog:choice:npc_mermaid_2:choice_Give:choice_Keep] -> [path:npc_mermaid_choice] + +npc_mermaid_choice:choice:0 -> [save_history:true] -> [remove_item:trade11:1:result] -> [set:link_dive:1500] -> [freeze:750] -> npc_mermaid_3 -> [freeze:750] -> [freeze:500] -> [add_item:trade12:1] -> [set:npc_painter:1] -> [set:mermaid_state:1] -> [set:npc_mermaid:1] -> [save_history:false] +npc_mermaid_choice:choice:1 -> npc_mermaid_4 + +// would look better if there would be a little pause where the player is not holding the item +trade12:0 -> trade12 -> [wait:dialogOpen:0] -> [set:npc_mermaid_leave:1] -> [set:npc_mermaid_gone:1] + +trade13:0 -> trade13 -> [set:npc_painter:2] + +// woman with the broom +npc_grandmother:villageAttacked:1 -> npc_broom_bowwow +// init state +npc_grandmother:missing_broom:0 -> npc_broom_0 + +// missing broom +npc_grandmother:missing_broom:1 -> [path:npc_broom] +npc_broom:0 -> [check_item:trade9:1:result] -> [path:npc_broom_check_item] +npc_broom_check_item:result:0 -> npc_broom_1 +npc_broom_check_item:result:1 -> [dialog:choice:npc_broom_2:choice_Yes:choice_No] -> [path:npc_broom_choice] + +npc_broom_choice:choice:0 -> [save_history:true] -> [sound:D360-01-01] -> [remove_item:trade9:1:result] -> [set:grandma_gone_dialog:0] -> [set:show_broom:1] -> [freeze:2200] -> [set:show_broom:0] -> [set:missing_broom:2] -> [freeze:500] -> npc_broom_3 -> [add_item:trade10:1] -> [set:ulrira_wife:0] -> [save_history:false] +npc_broom_choice:choice:1 -> npc_broom_5 + +// got the broom back +npc_grandmother:missing_broom:2 -> npc_broom_4 + + +// letter girl in the right town +npc_letter_girl:0 -> [check_item:trade7:1:result] -> [path:npc_letter_girl_trade] +npc_letter_girl:1 -> npc_letter_girl_4 + +npc_letter_girl_trade:result:0 -> npc_letter_girl_0 +npc_letter_girl_trade:result:1 -> [dialog:choice:npc_letter_girl_1:choice_Yes:choice_No] -> [path:npc_letter_girl_choice] +npc_letter_girl_choice:choice:0 -> npc_letter_girl_2 -> [save_history:true] -> [wait:dialogOpen:0] -> [remove_item:trade7:1:result] -> [add_item:trade8:1] -> [set:npc_letter_girl:1] -> [set:flower_traded:1] -> [save_history:false] +npc_letter_girl_choice:choice:1 -> npc_letter_girl_3 + + +// raft ride +npc_raft:raft_active:0 -> [dialog:choice:npc_raft_0:choice_Yes:choice_No_Way] -> [path:npc_raft_choice] +npc_raft:raft_active:1 -> npc_raft_1 + +npc_raft_choice:choice:0 -> [remove_item:ruby:100:removedMoney] -> [path:npc_raft_money] +npc_raft_choice:choice:1 -> + +npc_raft_money:removedMoney:0 -> npc_raft_2 +npc_raft_money:removedMoney:1 -> npc_raft_1 -> [set:raft_active:1] + +// boy from the castle with the frogs +// do not talk to player when he walks in with bowwow +npc_frog_boy:has_bowWow:1 -> npc_frog_body_bowwow + +npc_frog_boy:0 -> [dialog:choice:npc_frog_boy_0:choice_Okay:choice_No_Way] -> [set:1] -> [set:ulrira_banana:1] -> [path:npc_frog_boy_choice] + +npc_frog_boy_choice:choice:0 -> npc_frog_body_impressed +npc_frog_boy_choice:choice:1 -> npc_frog_body_coward + +npc_frog_boy:1 -> [save_history:true] -> [remove_item:goldLeaf:5:result] -> [path:npc_frog_boy_leafs] +npc_frog_boy:2 -> [path:npc_frog_boy_finished] + +npc_frog_boy_finished:frogHouseMovedStone:0 -> npc_frog_body_bien +npc_frog_boy_finished:frogHouseMovedStone:1 -> npc_frog_body_debt + +npc_frog_boy_leafs:result:0 -> npc_frog_body_please -> [save_history:false] +npc_frog_boy_leafs:result:1 -> npc_frog_body_bien -> [set:npc_frog_boy:2] -> [set:npc_frog_boyMove:-16,0,0.5] -> [set:npc_frog_house:1] -> [set:ulrira_leafs:0] -> [set:ulrira:shovel] -> [save_history:false] + +// instantly move to the target position +npc_frog_house:0 -> +npc_frog_house:1 -> [set:npc_frog_boyMove:-16,0,32] + +ow_castle_bush_sound:0 -> [sound:D360-02-02] -> [set:1] +ow_castle_bush_sound:1 -> + +castle_boss_door_sound:0 -> [sound:D360-02-02] -> [set:1] +castle_boss_door_sound:1 -> + +castle_boss_door_open:0 -> [sound:D360-02-02] -> [set:1] +castle_boss_door_open:1 -> + +// fishing game +fish_big:0 -> npc_fisherman_6 -> [add_item:ruby:20] -> [dialog:choice:npc_fisherman_6_1:choice_Cast:choice_Not_Now] -> [path:fishing_replay] +fish_small:0 -> npc_fisherman_7 -> [add_item:ruby:5] -> [dialog:choice:npc_fisherman_7_1:choice_Okay:choice_No] -> [path:fishing_replay] +fish_big_heart:0 -> [sound:D360-01-01] -> [set:pondHeart:1] -> [set:pondReset:1] -> [add_item:heartMeterSilent:1] -> [add_item:ruby:20] -> [check_item:heartMeter:1:result] -> [path:fish_heart_full] + +// different dialog depending on if the piece fills out a complete heart or not +fish_heart_full:result:1 -> npc_fisherman_8 -> [dialog:choice:npc_fisherman_8_1:choice_Yes:choice_No] -> [path:fishing_replay] +fish_heart_full:result:0 -> npc_fisherman_8_full -> [dialog:choice:npc_fisherman_8_1:choice_Yes:choice_No] -> [path:fishing_replay] + +fishing_replay:choice:0 -> [check_item:ruby:10:money] -> [path:fishing_replay_money] +fishing_replay:choice:1 -> [set:leavePond:yes] + +fishing_replay_money:money:0 -> npc_fisherman_2 -> [set:leavePond:yes] +fishing_replay_money:money:1 -> [path:fishing_replay_pond] + +fishing_replay_pond:emptyPond:0 -> [remove_item:ruby:10:result] -> npc_fisherman_3 +fishing_replay_pond:emptyPond:1 -> [path:fish_empty_pound] + +fish_empty_pound:0 -> npc_fisherman_9 -> [dialog:choice:npc_fisherman_9_1:choice_Okay:choice_No] -> [path:fish_empty_pound_choice] +fish_empty_pound_choice:0 -> npc_fisherman_10 -> [set:leavePond:yes] +fish_empty_pound_choice:1 -> npc_fisherman_1 -> [set:leavePond:yes] + +fishing_empty:0 -> [dialog:choice:npc_fisherman_4:choice_Cast:choice_Not_Now] -> [path:fishing_replay] +fishing_loss:0 -> [dialog:choice:npc_fisherman_5:choice_Cast:choice_Not_Now] -> [path:fishing_replay] + +// npc +alligator:trade2:0 -> [update_objects] -> [check_item:trade2:1:result] -> [path:alligator_trade] +alligator:trade2:1 -> [update_objects] -> [path:alligator_postTrade] + +// in the original game the new line is given when the player reenters the house +// not so sure if this is better but currently there is no way to do this in the engine +alligator_postTrade:alligator_thanks:0 -> [update_objects] -> alligator_6 -> [set:alligator_thanks:1] +alligator_postTrade:alligator_thanks:1 -> [update_objects] -> alligator_7 + +alligator_trade:result:1 -> [update_objects] -> alligator_1 -> [dialog:choice:alligator_2:choice_Give:choice_Dont] -> [path:alligator_traded] +alligator_trade:result:0 -> [update_objects] -> alligator_0 + +alligator_traded:choice:0 -> [update_objects] -> alligator_4 -> [wait:dialogOpen:0] -> [set:alligator_eat:eat] +alligator_traded:choice:1 -> [update_objects] -> alligator_3 + +alligator_after_eat:0 -> [update_objects] -> [save_history:true] -> alligator_5 -> [remove_item:trade2:1:result] -> [add_item:trade3:1] -> trade2 -> [set:trade2:1] -> [set:tarin:gone] -> [save_history:false] + + +npc11:0 -> [path:npc05] + +// shop +shopkeeper:holdItem:0 -> [update_objects] -> shopkeeper_0 +shopkeeper:holdItem:1 -> [path:shopkeeper_buy] + +shopkeeper_buy:itemShopItem:bow -> [update_objects] -> [dialog:choice:itemShop_bow:itemShop_buy:itemShop_no_way] -> [path:itemShop] +shopkeeper_buy:itemShopItem:arrow -> [update_objects] -> [dialog:choice:itemShop_arrow:itemShop_buy:itemShop_dont] -> [path:itemShop] +shopkeeper_buy:itemShopItem:shovel -> [update_objects] -> [dialog:choice:itemShop_shovel:itemShop_buy:itemShop_no_way!] -> [path:itemShop] +shopkeeper_buy:itemShopItem:heart -> [update_objects] -> [dialog:choice:itemShop_hearts:itemShop_buy:itemShop_dont] -> [path:itemShop] +shopkeeper_buy:itemShopItem:shield -> [update_objects] -> [dialog:choice:itemShop_shield:itemShop_buy:itemShop_dont] -> [path:itemShop] +shopkeeper_buy:itemShopItem:bomb -> [update_objects] -> [dialog:choice:itemShop_bomb:itemShop_buy:itemShop_dont] -> [path:itemShop] +shopkeeper_buy:0 -> [update_objects] -> [dialog:choice:itemShop_dialog:itemShop_buy:itemShop_dont] -> [path:itemShop] + +shopkeeper_try_steal:0 -> shopkeeper_4 +shopkeeper_steal:0 -> shopkeeper_5 -> [path:stealing_photo] +// unlock the photo if link already talked to the photo mouse +stealing_photo:photo_1:0 -> +stealing_photo:photo_1:1 -> [set:photo_7:1] -> [path:photo_count_increase] + +itemShop:choice:0 -> [buy:result] -> [path:itemBuy] +itemShop:choice:1 -> [set:result:1] -> [set:holdItem:0] + +itemBuy:result:0 -> [update_objects] -> shopkeeper_1 -> [wait:dialogOpen:0] -> [set:holdItem:0] +itemBuy:result:1 -> [update_objects] -> shopkeeper_2 -> [wait:dialogOpen:0] -> [set:holdItem:0] +itemBuy:result:2 -> [update_objects] -> shopkeeper_3 -> [wait:dialogOpen:0] -> [set:holdItem:0] + +itemBuy_steal:0 -> itemShop_steal + +itemShop_revenge:0 -> [update_objects] -> [music:24:2] -> itemShop_revenge + +// set shopItem0 variable +check_item0:npc_hidden:1 -> [check_item:bow:0:has_bow] -> [path:check_bow] +check_item0:0 -> [check_item:shovel:1:has_shovel] -> [path:check_shovel] + +check_shovel:has_shovel:0 -> [set:shopItem0:0] +check_shovel:has_shovel:1 -> [check_item:bow:0:has_bow] -> [path:check_bow] + +check_bow:has_bow:0 -> [set:shopItem0:1] +check_bow:has_bow:1 -> [set:shopItem0:2] + +// -- candy trendy -- +npc_trendy:trendy_closed:1 -> npc_trendy_closed + +npc_trendy:0 -> [path:npc_trand_init_0] +// play again dialog +npc_trendy:1 -> [path:npc_trand_init_1] + +npc_trand_init_0:can_play:0 -> [dialog:choice:npc_trendy_open:npc_trendy_play:npc_trendy_no_play] -> [path:npc_trendy_choice] +npc_trand_init_0:can_play:1 -> npc_trendy_start + +npc_trand_init_1:can_play:0 -> [dialog:choice:npc_trendy_again:npc_trendy_play:npc_trendy_no_play] -> [path:npc_trendy_choice] +npc_trand_init_1:can_play:1 -> npc_trendy_start + +// check if the player has enought cash +npc_trendy_choice:choice:0 -> [check_item:ruby:10:result] -> [path:npc_trendy_money] +npc_trendy_choice:choice:1 -> + +npc_trendy_money:result:0 -> npc_trendy_no_cash +npc_trendy_money:result:1 -> [path:npc_trendy_start_game] + +npc_trendy_start_game:npc_trendy:1 -> npc_trendy_good_luck -> [set:can_play:1] -> [set:trendy_button_1:1] -> [remove_item:ruby:10:result] +npc_trendy_start_game:0 -> npc_trendy_start -> [set:npc_trendy:1] -> [set:can_play:1] -> [set:trendy_button_1:1] -> [remove_item:ruby:10:result] + +// marin playing the game +trendy_marin:0 -> [update_objects] -> [path:trendy_marin_check] +trendy_marin:1 -> + +trendy_marin_check:has_marin:0 -> +trendy_marin_check:has_marin:1 -> [update_objects] -> [save_history:true] -> [set:trendy_marin:1] -> [dialog:choice:maria_game_0:choice_Okay:choice_No_Way] -> [path:trendy_marin_choice] + +trendy_marin_choice:choice:0 -> [path:trendy_marin_start] +trendy_marin_choice:choice:1 -> [update_objects] -> [dialog:choice:maria_game_1:choice_Yes:choice_Okay] -> [path:trendy_marin_start] + +trendy_marin_start:0 -> [update_objects] -> npc_trendy_start -> [wait:dialogOpen:0] -> [set:trendy_button_1:1] -> [set:maria_walk:40,106,0.5,] -> [freeze:500] -> [set:link_direction:0] -> [freeze:marinMoving:0] -> [set:maria_play_animation:stand_1] -> [freeze:1000] -> [set:trendy_marin_game:1] -> [freeze:3000] -> [set:link_direction:1] -> [freeze:8600] -> [set:link_direction:2] -> [freeze:8500] -> [set:link_direction:1] -> [freeze:2500] -> [set:link_direction:0] + +trendy_marin_end:0 -> [update_objects] -> maria_game_2 -> [wait:dialogOpen:0] -> [map_transition:overworld.map:s2] -> [save_history:false] + +// bat +// first choice does not matter +npcBat:0 -> [dialog:choice:npcBat_Intro:choice_Yes:choice_N-No] -> [path:npcBatPowder] + +npcBatPowder:upgradePowder:0 -> [dialog:choice:npcBat_Powder:choice_Yes:choice_N-No] -> [path:npcBatPowderChoice] +npcBatPowder:upgradePowder:1 -> [path:npcBatBomb] +npcBatPowderChoice:choice:0 -> [set:npcBatThunder:1] -> [freeze:3300] -> [set:upgradePowder:1] -> [add_item_amount:powder:40] -> [set:npcBatThunder:0] -> [freeze:100] -> npcBat_End -> [save_hitory:false] +npcBatPowderChoice:choice:1 -> [path:npcBatBomb] + +npcBatBomb:upgradeBomb:0 -> [dialog:choice:npcBat_Bombs:choice_Yes:choice_N-No] -> [path:npcBatBombChoice] +npcBatBomb:upgradeBomb:1 -> [path:npcBatArrow] +npcBatBombChoice:choice:0 -> [set:npcBatThunder:1] -> [freeze:3300] -> [set:upgradeBomb:1] -> [add_item_amount:bomb:60] -> [set:npcBatThunder:0] -> [freeze:100] -> npcBat_End -> [save_hitory:false] +npcBatBombChoice:choice:1 -> [path:npcBatArrow] + +npcBatArrow:upgradeBow:0 -> [dialog:choice:npcBat_Arrows:choice_Yes:choice_N-No] -> [path:npcBatArrowChoice] +npcBatArrow:upgradeBow:1 -> [path:npcBatPowder] +npcBatArrowChoice:choice:0 -> [set:npcBatThunder:1] -> [freeze:3300] -> [set:upgradeBow:1] -> [add_item_amount:bow:60] -> [set:npcBatThunder:0] -> [freeze:100] -> npcBat_End -> [save_hitory:false] +npcBatArrowChoice:choice:1 -> [path:npcBatPowder] + +// Library +book1:0 -> book1_0 -> [dialog:choice:book:book_yes:book_no] -> [path:cbook1] +cbook1:choice:0 -> [set:book1_open:1] -> book1_1 -> [wait:dialogOpen:0] -> [set:book1_open:0] +cbook1:choice:1 -> + +book2:0 -> book2_0 -> [dialog:choice:book:book_yes:book_no] -> [path:cbook2] +cbook2:choice:0 -> [set:book2_open:1] -> book2_1 -> [wait:dialogOpen:0] -> [set:book2_open:0] +cbook2:choice:1 -> + +book3:0 -> book3_0 -> [dialog:choice:book:book_yes:book_no] -> [path:cbook3] +cbook3:choice:0 -> [set:book3_open:1] -> book3_1 -> [wait:dialogOpen:0] -> [set:book3_open:0] +cbook3:choice:1 -> + +book4:0 -> book4_0 -> [dialog:choice:book:book_yes:book_no] -> [path:cbook4] +cbook4:choice:0 -> [set:book4_open:1] -> book4_1 -> [wait:dialogOpen:0] -> [set:book4_open:0] +cbook4:choice:1 -> + +book5:0 -> book5_0 -> [dialog:choice:book:book_yes:book_no] -> [path:cbook5] +cbook5:choice:0 -> [set:book5_open:1] -> book5_1 -> [wait:dialogOpen:0] -> [set:book5_open:0] +cbook5:choice:1 -> + +book6:0 -> book6_0 -> [dialog:choice:book:book_yes:book_no] -> [path:cbook6] +cbook6:choice:0 -> [set:book6_open:1] -> book6_1 -> [wait:dialogOpen:0] -> [set:book6_open:0] +cbook6:choice:1 -> + +book7:0 -> book7_0 -> [dialog:choice:book7_1:book_look:book_dont] -> [path:cbook7] +cbook7:choice:0 -> [set:book7_open:1] -> [freeze:250] -> [start_sequence:map] -> [freeze:250] -> [wait:dialogOpen:0] -> [set:book7_open:0] +cbook7:choice:1 -> + +book8:0 -> book8_0 -> [dialog:choice:book_realy_read:choice_YES:choice_NO] -> [path:cbook8] +cbook8:choice:0 -> [set:book8_open:1] -> [check_item:trade13:1:result] -> [path:cbook8_item] +cbook8:choice:1 -> +// check if the player has the glasses +cbook8_item:result:0 -> book8_1 -> [wait:dialogOpen:0] -> [set:book8_open:0] +cbook8_item:result:1 -> [path:cbook8_open] + +cbook8_open:eggDirections:0 -> book8_2 -> [wait:dialogOpen:0] -> [set:book8_open:0] +cbook8_open:eggDirections:1 -> book8_3 -> [wait:dialogOpen:0] -> [set:book8_open:0] +cbook8_open:eggDirections:2 -> book8_4 -> [wait:dialogOpen:0] -> [set:book8_open:0] +cbook8_open:eggDirections:3 -> book8_5 -> [wait:dialogOpen:0] -> [set:book8_open:0] + +book9:0 -> [dialog:choice:book_read:book_yes:book_no] -> [path:cbook9] +cbook9:choice:0 -> [set:book9_open:1] -> book9_1 -> [wait:dialogOpen:0] -> [set:book9_open:0] +cbook9:choice:1 -> + +photo_book:0 -> [dialog:choice:photo_book:choice_Look:choice_Dont] -> [path:photo_book_choice] +photo_book_choice:choice:0 -> [open_book] +photo_book_choice:choice:1 -> + + +// == ulrira == +// init dialog only shown one time +ulrira:0 -> ulrira_0 -> [set:ulrira:1] + +// player already has the banana? +ulrira:ulrira_banana:1 -> [check_item:trade3:1:result] -> [path:ulrira_banana] +ulrira_banana:result:0 -> ulrira_3_2 +ulrira_banana:result:1 -> ulrira_3_1 + +// two different tips for finding the golden leafs +ulrira:ulrira_leafs:1 -> [check_item:goldLeaf:5:result] -> [path:ulrira_leafs_check] +// all leafs collected => show other message +ulrira_leafs_check:result:0 -> [path:ulrira_leaf_tip] +ulrira_leafs_check:result:1 -> ulrira_shovel + +// go through 3 different tips +ulrira_leaf_tip:0 -> [set:1] -> ulrira_leaf_0 +ulrira_leaf_tip:1 -> [set:2] -> ulrira_leaf_1 +ulrira_leaf_tip:2 -> [set:0] -> ulrira_leaf_2 + +ulrira:ulrira_ghost:1 -> ulrira_ghost +ulrira:ulrira_wife:1 -> ulrira_wife + +ulrira:ulrira_d3:1 -> ulrira_3_3 + +ulrira:ulrira_d4:1 -> ulrira_4_0 +ulrira:ulrira_d4:2 -> ulrira_4_1 + +ulrira:ulrira_d5:1 -> ulrira_5_0 + +ulrira:ulrira_mamu:1 -> ulrira_mamu + +ulrira:ulrira_d6:1 -> ulrira_6_0 + +ulrira:ulrira_d7:1 -> ulrira_7_0 +ulrira:ulrira_d7:2 -> ulrira_7_1 +ulrira:ulrira_d7:3 -> ulrira_7_2 + +ulrira:ulrira_d8:1 -> ulrira_8_0 +ulrira:ulrira_d8:2 -> ulrira_8_1 + +ulrira:ulrira_d9:1 -> ulrira_9_0 +ulrira:ulrira_d9:2 -> ulrira_9_1 + + +// fairy woods +fairy:0 -> [update_objects] -> [set:link_direction:1] -> fairy_0 + +// alligator +alligator:0 -> alligator_0 + +// owl +owl:x -> +// beach +owl:0 -> owl_1_0 -> [set:link_direction:1] -> [set:1_1] -> [set:maria_state:1] -> [set:tarin_state:1] -> [set:tarin:1] -> [set:maria:2] -> [set:map_owl_shore:1] +// woods entry +owl:1_1 -> owl_1_1 -> [set:x] -> [set:map_owl_woods_entry:1] +// woods chest getting the first dungeon key +owl:1_2 -> owl_1_2 -> [set:x] -> [set:map_owl_woods:1] + +// after defeating the first boss +owl:2_0 -> owl_2_0 -> [set:x] -> [set:map_owl_level_1:1] +// saving bowwow +owl:2_1 -> owl_2_1 -> [set:2_2] -> [set:map_owl_tal_tal_heights:1] + +// post dungeon 3 +owl:3_0 -> owl_3_0 -> [set:x] -> [set:map_owl_level_3:1] +// getting the key in the desert +owl:3_1 -> owl_3_1 -> [set:x] -> [set:map_owl_desert:1] + +// ghost grave +owl:5_0 -> owl_5_0 -> [set:x] -> [set:map_owl_prairie:1] + +// before entering the area above the right village +owl:6_0 -> owl_6_0 -> [set:x] -> [set:map_owl_level_6:1] +// owl infront of the shrine when the player leaves after having looked at the wall +owl_shrine:1 -> owl_6_1 -> [set:x] -> [set:map_owl_shrine:1] + +// after finishing dungeon 6 +owl:7_0 -> owl_7_0 -> [set:7_1] -> [set:map_owl_level_6_post:1] +owl:7_1 -> owl_7_1 -> [set:x] -> [set:map_owl_mountain:1] + +// after saving marin on the bridge +owl:8_0 -> owl_8_0 -> [set:link_direction:2] -> [set:map_owl_bridge:1] -> [set:maria_state:6] -> [set:x] + +// sitting on the stairs infront of the egg +owl_stairs:0 -> owl_stairs -> [set:map_owl_fish:1] -> [set:1] + +// after breaking open the egg +owl:9_0 -> owl_9_0 -> [set:link_direction:1] -> [set:x] + + +// map owl text +map_owl_shore:0 -> map_toronbo_shores +map_owl_shore:1 -> owl_1_0 + +map_owl_woods_entry:0 -> map_mysterious_woods +map_owl_woods_entry:1 -> owl_1_1 + +map_owl_woods:0 -> map_mysterious_woods +map_owl_woods:1 -> owl_1_2 + +map_owl_level_1:0 -> map_south_village +map_owl_level_1:1 -> owl_2_0 + +map_owl_tal_tal_heights:0 -> map_tal_tal_heights +map_owl_tal_tal_heights:1 -> owl_2_1 + +map_owl_level_3:0 -> map_ukuku_prairie +map_owl_level_3:1 -> owl_3_0 + +map_owl_desert:0 -> map_yarna_desert +map_owl_desert:1 -> owl_3_1 + +map_owl_prairie:0 -> map_koholint_prairie +map_owl_prairie:1 -> owl_5_0 + +map_owl_level_6:0 -> map_face_shrine +map_owl_level_6:1 -> owl_6_0 + +map_owl_shrine:0 -> map_face_shrine +map_owl_shrine:1 -> owl_6_1 + +map_owl_level_6_post:0 -> map_face_shrine +map_owl_level_6_post:1 -> owl_7_0 + +map_owl_mountain:0 -> map_tal_tal +map_owl_mountain:1 -> owl_7_1 + +map_owl_bridge:0 -> map_tal_tal +map_owl_bridge:1 -> owl_8_0 + +map_owl_fish:0 -> map_tal_tal +map_owl_fish:1 -> owl_stairs + + +// rabbit +rabbit_0:maria_state:3 -> rabbit_marin +rabbit_0:0 -> rabbit_0_0 +rabbit_0:1 -> rabbit_0_1 + +rabbit_1:maria_state:3 -> rabbit_marin +rabbit_1:0 -> rabbit_1_0 +rabbit_1:1 -> rabbit_1_1 + +rabbit_2:maria_state:3 -> rabbit_marin +rabbit_2:0 -> rabbit_2_0 +rabbit_2:1 -> rabbit_2_1 + +rabbit_3:maria_state:3 -> rabbit_marin +rabbit_3:0 -> rabbit_3_0 +rabbit_3:1 -> rabbit_3_1 + +rabbit_2_script:0 -> [set:rabbit_2Jump:533] + + +desert_bones:0 -> desert_bone_0 -> [set:desert_bones_powder:0] + +desertLanmola_enter:ow_desertLanmola:0 -> desertLanmola +desertLanmola_enter:ow_desertLanmola:1 -> + +// tracy +npc_tracy:0 -> npc_tracy_0 -> [check_item:potion:1:hasPotion] -> [set:1] +npc_tracy:hasPotion:0 -> [path:npc_tracy_offer] +npc_tracy:hasPotion:1 -> npc_tracy_6 -> [set:npc_tracy:0] + +npc_tracy_offer:npc_tracy_price:0 -> [dialog:choice:npc_tracy_1:tracy_give:tracy_dont] -> [path:npc_tracy_choice_0] +npc_tracy_choice_0:choice:0 -> [save_history:true] -> [remove_item:ruby:28:result] -> [path:npc_tracy_money] +npc_tracy_choice_0:choice:1 -> npc_tracy_7 -> [set:npc_tracy:0] + +npc_tracy_offer:npc_tracy_price:1 -> [dialog:choice:npc_tracy_2:tracy_give:tracy_dont] -> [path:npc_tracy_choice_1] +npc_tracy_choice_1:choice:0 -> [save_history:true] -> [remove_item:ruby:42:result] -> [path:npc_tracy_money] +npc_tracy_choice_1:choice:1 -> npc_tracy_7 -> [set:npc_tracy:0] + +npc_tracy_offer:npc_tracy_price:2 -> [dialog:choice:npc_tracy_3:tracy_give:tracy_dont] -> [path:npc_tracy_choice_2] +npc_tracy_choice_2:choice:0 -> [save_history:true] -> [remove_item:ruby:7:result] -> [path:npc_tracy_money] +npc_tracy_choice_2:choice:1 -> npc_tracy_7 -> [set:npc_tracy:0] + +// try to buy the potion +npc_tracy_money:result:0 -> npc_tracy_5 -> [save_history:false] +npc_tracy_money:result:1 -> [add_item:potion_show:1] -> npc_tracy_4 -> [set:npc_tracy:0] -> [fill_hearts] -> [save_history:false] -> [path:npc_tracy_heal] + +npc_tracy_heal:fullHearts:0 -> npc_tracy_8 +npc_tracy_heal:fullHearts:1 -> + +// in the original this dialog seems to be randomized +npc_hippo:0 -> [update_objects] -> npc_hippo_0 -> [set:1] +npc_hippo:1 -> [update_objects] -> npc_hippo_0 -> [set:2] +npc_hippo:2 -> [update_objects] -> npc_hippo_0 -> [set:3] +npc_hippo:3 -> [update_objects] -> npc_hippo_1 -> [set:4] +npc_hippo:4 -> [update_objects] -> npc_hippo_0 -> [set:5] +npc_hippo:5 -> [update_objects] -> npc_hippo_0 -> [set:6] +npc_hippo:6 -> [update_objects] -> npc_hippo_0 -> [set:7] +npc_hippo:7 -> [update_objects] -> npc_hippo_2 -> [set:0] + +npc_painter:0 -> npc_painter_0 +// player has the scale +npc_painter:1 -> npc_painter_1 +// player has the lense +npc_painter:2 -> npc_painter_2 + +// signpost game +signpost_failed:0 -> [sound:D360-29-1D] -> [freeze:250] -> signpost_TryAgain -> [set:sgame:0] + +shieldGame1:mamu_gone:1 -> signpost_Gone +shieldGame1:sgame:0 -> signpost_Down -> [set:sgame:1] +shieldGame1:sgame:1 -> signpost_Down -> [set:sgame:1] +shieldGame1:0 -> [path:signpost_failed] + +shieldGame2:mamu_gone:1 -> signpost_Gone +shieldGame2:sgame:1 -> signpost_Right -> [set:sgame:2] +shieldGame2:0 -> [path:signpost_failed] + +shieldGame3:mamu_gone:1 -> signpost_Gone +shieldGame3:sgame:2 -> signpost_Down -> [set:sgame:3] +shieldGame3:0 -> [path:signpost_failed] + +shieldGame4:mamu_gone:1 -> signpost_Gone +shieldGame4:sgame:3 -> signpost_Left -> [set:sgame:4] +shieldGame4:0 -> [path:signpost_failed] + +shieldGame5:mamu_gone:1 -> signpost_Gone +shieldGame5:sgame:4 -> signpost_Up -> [set:sgame:5] +shieldGame5:0 -> [path:signpost_failed] + +shieldGame6:mamu_gone:1 -> signpost_Gone +shieldGame6:sgame:5 -> signpost_Right -> [set:sgame:6] +shieldGame6:0 -> [path:signpost_failed] + +shieldGame7:mamu_gone:1 -> signpost_Gone +shieldGame7:sgame:6 -> signpost_Down -> [set:sgame:7] +shieldGame7:0 -> [path:signpost_failed] + +shieldGame8:mamu_gone:1 -> signpost_Gone +shieldGame8:sgame:7 -> signpost_Right -> [set:sgame:8] +shieldGame8:0 -> [path:signpost_failed] + +shieldGame9:mamu_gone:1 -> signpost_Gone +shieldGame9:sgame:8 -> signpost_Up -> [set:sgame:9] +shieldGame9:0 -> [path:signpost_failed] + +shieldGame10:mamu_gone:1 -> signpost_Gone +shieldGame10:sgame:9 -> signpost_Left -> [set:sgame:10] +shieldGame10:0 -> [path:signpost_failed] + +shieldGame11:mamu_gone:1 -> signpost_Gone +shieldGame11:sgame:10 -> signpost_Down -> [set:sgame:11] +shieldGame11:0 -> [path:signpost_failed] + +shieldGame12:mamu_gone:1 -> signpost_Gone +shieldGame12:sgame:11 -> signpost_Right -> [set:sgame:12] +shieldGame12:0 -> [path:signpost_failed] + +shieldGame13:mamu_gone:1 -> signpost_Gone +shieldGame13:sgame:12 -> signpost_Down -> [set:sgame:13] +shieldGame13:0 -> [path:signpost_failed] + +shieldGame14:mamu_gone:1 -> signpost_Gone +shieldGame14:sgame:13 -> signpost_Left -> [set:sgame:14] +shieldGame14:0 -> [path:signpost_failed] + +shieldGame15:mamu_gone:1 -> signpost_Gone +// spawn the stairs +shieldGame15:sgame:14 -> signpost_Great -> [wait:dialogOpen:0] -> [set:sgame:15] -> [set:frogStairs:1] +shieldGame15:0 -> [path:signpost_failed] + +shieldGameStairs:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:shieldGameStairs] +shieldGameStairs:1 -> + + +// == mamu == +// check if the player has the ocarina +mamu:0 -> [update_objects] -> [freeze:250] -> [set:link_direction:1] -> [check_item:ocarina:1:result] -> [path:mamu_ocarina] +mamu:1 -> [update_objects] -> ocarina_frog_song_end + +mamu_ocarina:result:0 -> mamu0 +mamu_ocarina:result:1 -> [dialog:choice:mamu1:choice_Pay:choice_Leave] -> [path:mamu_ocarina_choice] + +mamu_ocarina_choice:choice:0 -> [check_item:ruby:300:money] -> [path:mamu_ocarina_money] +mamu_ocarina_choice:choice:1 -> mamu2 + +// no money +mamu_ocarina_money:money:0 -> mamu2 +mamu_ocarina_money:money:1 -> [save_history:true] -> [remove_item:ruby:300:result] -> [set:mamu_sing:1] + +// finished playing the song +mamu_finished:0 -> mamu3 -> [add_item:ocarina_frog:1] -> [set:mamu:1] -> [set:mamu_gone:1] -> [set:ulrira_mamu:0] -> [music:-1:2] -> [save_history:false] + + +// == manbo == +manbo:0 -> [dialog:choice:manbo0:choice_Yes:choice_No] -> [path:manbo_song_choice] +manbo:1 -> manbo4 + +manbo_song_choice:choice:0 -> [check_item:ocarina:1:result] -> [path:manbo_ocarina] +manbo_song_choice:choice:1 -> manbo1 + +manbo_ocarina:result:0 -> manbo3 +manbo_ocarina:result:1 -> manbo2 -> [save_history:true] -> [wait:dialogOpen:0] -> [set:manbo_start_song:1] + +manbo_finished:0 -> [add_item:ocarina_manbo:1] -> [set:manbo:1] -> [save_history:false] + + +// ocarina songs +ocarina_frog_collected:0 -> ocarina_frog_song -> [wait:player_shows_item:0] -> ocarina_frog_song_end +ocarina_manbo_collected:0 -> ocarina_manbo_song + +ocarina_maria_collected:0 -> ocarina_maria_song -> [wait:player_shows_item:0] -> [path:marin_remember] +// @TODO: we show different messages depending on where marin stands; needs to be verified +marin_remember:maria_state:1 -> maria_1_6 +marin_remember:maria_state:4 -> maria_1_7 +marin_remember:maria_state:6 -> maria_1_6 + +// dungeon 1 key +dkey1:0 -> [set:owl:1_2] -> dkey1 +// dungeon 3 key +dkey2:0 -> dkey2 -> [set:ulrira_d3:1] -> [set:ulrira:seashells] +// dungeon 4 key +dkey3:0 -> dkey3 -> [set:owl:3_1] -> [set:ulrira_d4:2] + +dkey4:0 -> dkey4 -> [set:owl:6_1] + +dkey5:0 -> dkey5 -> [set:ulrira_d7:3] + +// hidden npc +// trade +npc_hidden:0 -> [dialog:choice:npc_hidden_0:choice_Okay:choice_No] -> [path:npc_hidden_choice] +// try to get the boomerang back +npc_hidden:1 -> [dialog:choice:npc_hidden_3:choice_Okay:choice_Not_Now] -> [path:npc_hidden_return] + +npc_hidden_choice:choice:0 -> [set:boomerang_trade:1] +npc_hidden_choice:choice:1 -> npc_hidden_2 + +npc_hidden_boomerang:0 -> npc_hidden_1 -> [wait:dialogOpen:0] -> [add_item:boomerang:1] -> [set:npc_hidden:1] + +npc_hidden_return:choice:0 -> [set:npc_hidden:0] -> [set:boomerang_trade_return:1] +npc_hidden_return:choice:1 -> npc_hidden_2 + +npc_hidden_reject:0 -> npc_hidden_5 + +ow_mountain_cave:0 -> [sound:D360-02-02] -> [set:1] -> [path:ow_mountain_cave] +ow_mountain_cave:1 -> [spawn:stairsCastle:] -> [spawn:door:16.16.bc2.caveBat2$map.bc2.0.1.True] + +ow_village_tunnel_spawn:0 -> [sound:D360-02-02] -> [set:1] -> [path:ow_village_tunnel_spawn] +ow_village_tunnel_spawn:1 -> [spawn:stairsCastle:] -> [spawn:door:16.16.cave9left.cave9$map.cave9left.3.1.True] + +// shrine image +shrine_message:0 -> [start_sequence:shrine] -> [freeze:2000] -> shrine_message -> [wait:dialogOpen:0] -> [freeze:2000] -> [path:owl_shrine_show] +// only spawn the owl one time +owl_shrine_show:0 -> [set:owl_shrine:1] -> [set:1] +owl_shrine_show:1 -> + +// shell mansion +shell_mansion_entry:0 -> shell_mansion_0 -> [set:1] +shell_mansion_entry:1 -> + +shell_mansion_nothing:0 -> shell_mansion_1 + +seashell:0 -> seashell -> [wait:dialogOpen:0] -> [check_item:shell:20:allShells] -> [path:seashellsFound] +seashellsFound:allShells:0 -> +// @HACK: we wait 175ms for the item to fade away because the chest will get deactivated and the sprite would get stuck (only a problem for the chest in the forest) +seashellsFound:allShells:1 -> [freeze:175] -> [set:shellsFound:1] + +shell_mansion_sword:0 -> [update_objects] -> [save_history:true] -> shell_mansion_2 -> [music:85:2] -> [wait:dialogOpen:0] -> [freeze:600] -> [set:spawnSwordParticle:1] -> [freeze:1300] -> [set:spawnSword:1] -> [save_history:false] + +// == dungeon one == + +// play soundeffect the first time the key gets spawned +d1k1spawn:0 -> [spawn:item:d.d1k1.smallkey.one] -> [sound:D360-02-02] -> [set:1] +d1k1spawn:1 -> [spawn:item:.d1k1.smallkey.one] + +d1_button_0:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d1_button_0] +d1_button_0:1 -> [spawn:chest:smallkeyChest.one.d1k2.0] + +d1c2:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d1c2] +d1c2:1 -> [spawn:chest:dmap.one.d1_map.0] + +d1c3:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d1c3] +d1c3:1 -> [spawn:chest:ruby20..d1_r20.0] + +d1_cave0:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d1_cave0] +d1_cave0:1 -> [spawn:dungeon_stairs:] -> [spawn:light:64.255.255.255.75] -> [spawn:door:16.16.d1s1.dungeon1_2d_1$map.d1s1.3.1.False] + +d1_moveStone:0 -> [sound:D360-02-02] -> [set:1] +d1_moveStone:1 -> + +d1_boys_sound:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d1_boys_sound] +d1_boys_sound:1 -> [spawn:chest:stonebeak.one.d1_beak.0] + +// people are worried about the village and bowwow is missing +sound_secrete:0 -> [sound:D360-02-02] + +d1_beak_1:0 -> [check_item:stonebeak:1:result] -> [path:d1_beak_1_result] +d1_beak_1_result:result:0 -> beak_nop +d1_beak_1_result:result:1 -> beak_d1_1 + +d1_beak_2:0 -> [check_item:stonebeak:1:result] -> [path:d1_beak_2_result] +d1_beak_2_result:result:0 -> beak_nop +d1_beak_2_result:result:1 -> beak_d1_2 + + +// nightmare +d1_n_enter_dialog:d1_n1_killed:0 -> [update_objects] -> [music:24:2] -> [freeze:250] -> nightmare1 -> [wait:dialogOpen:0] -> [set:d1_n_trigger:1] +d1_n_enter_dialog:0 -> + +// play music in the instrument room +d1_instrument_music:d1_instrument:0 -> [music:23:2] +d1_instrument_music:0 -> + +// trigger the bowWow missing part; update npc dialogs +instrument0:0 -> [update_objects] -> instrument0 -> [set:npc_boy_0:1] -> [set:npc_boy_1:1] -> [set:ulrira:2_0] -> [set:owl:2_0] -> [set:villageAttacked:1] -> [set:bowWow:1] -> [set:mc_enemies:1] -> [set:tarin:3] + + +// == dungeon two == +d2_open_door:0 -> [sound:D360-02-02] + +d2_beak_1:0 -> [check_item:stonebeak:1:result] -> [path:d2_beak_1_result] +d2_beak_1_result:result:0 -> beak_nop +d2_beak_1_result:result:1 -> beak_d2_1 + +d2_beak_2:0 -> [check_item:stonebeak:1:result] -> [path:d2_beak_2_result] +d2_beak_2_result:result:0 -> beak_nop +d2_beak_2_result:result:1 -> beak_d2_2 + +d2_beak_3:0 -> [check_item:stonebeak:1:result] -> [path:d2_beak_3_result] +d2_beak_3_result:result:0 -> beak_nop +d2_beak_3_result:result:1 -> beak_d2_3 + +d2_spawn_key_0:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d2_spawn_key_0] +d2_spawn_key_0:1 -> [spawn:chest:smallkeyChest.two.d2_smallkey_3.0] + +d2_spawn_key_1:0 -> [spawn:item:d.d2_key_1.smallkey.two] -> [sound:D360-02-02] -> [set:1] +d2_spawn_key_1:1 -> [spawn:item:.d2_key_1.smallkey.two] + +d2_spawn_key_3:0 -> [spawn:item:d.d2_key_3.smallkey.two] -> [sound:D360-02-02] -> [set:1] +d2_spawn_key_3:1 -> [spawn:item:.d2_key_3.smallkey.two] + +d2_spawn_compass:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d2_spawn_compass] +d2_spawn_compass:1 -> [spawn:chest:compass.two.d2_compass.0] + +d2_spawn_stairs_0:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d2_spawn_stairs_0] +d2_spawn_stairs_0:1 -> [spawn:dungeon_6_stairs:] -> [spawn:light:64.255.255.255.255] -> [spawn:door:16.16.d2c0r.dungeon2_2d_1$map.d2c0r.3.1.False] + +d2_spawn_stairs_1:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d2_spawn_stairs_1] +d2_spawn_stairs_1:1 -> [spawn:dungeon_6_stairs:] -> [spawn:light:64.255.255.255.75] -> [spawn:door:16.16.d2_cave_2_right.dungeon2_2d_3$map.d2_cave_2_right.3.1.False] + +d2_spawn_nkey:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d2_spawn_nkey] +d2_spawn_nkey:1 -> [spawn:chest:nightmarekey.two.d2_nkey.0] + +d2_spawn_stonelifter:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d2_spawn_stonelifter] +d2_spawn_stonelifter:1 -> [spawn:chest:stonelifter.two.d2_stonelifter.0] + +d2_boss:0 -> [music:24:2] -> [freeze:250] -> d2_boss_0 + +d2_instrument_music:d2_instrument:0 -> [music:23:2] +d2_instrument_music:0 -> + +// set bowwow to a state where it gets returned; make bomb buyable in the shop +instrument1:0 -> [update_objects] -> instrument1 -> [set:bowWow:3] -> [set:ulrira:3_0] -> [set:tarin:4] -> [set:tarin_state:3] -> [set:maria:1_1] -> [set:npc_boy_1:2] -> [set:shopLevel:1] + + +// == dungeon three == + +// first floor +d3_spawn_1:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d3_spawn_1] +d3_spawn_1:1 -> [spawn:chest:smallkeyChest.three.d3k2.0] + +d3_spawn_2:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d3_spawn_2] +d3_spawn_2:1 -> [spawn:chest:ruby200..d3_r200.0] + +// second floor +d3_spawn_3:0 -> [sound:D360-02-02] -> [set:1] +d3_spawn_3:1 -> + +d3_spawn_4:0 -> [sound:D360-02-02] -> [set:1] +d3_spawn_4:1 -> + +d3_spawn_5:0 -> [sound:D360-02-02] -> [set:1] +d3_spawn_5:1 -> + +// third floor +d3_spawn_6:0 -> [spawn:item:d.d3k8.smallkey.three] -> [sound:D360-02-02] -> [set:1] +d3_spawn_6:1 -> [spawn:item:.d3k8.smallkey.three] + +d3_spawn_7:0 -> [spawn:item:d.d3k6.smallkey.three] -> [sound:D360-02-02] -> [set:1] +d3_spawn_7:1 -> [spawn:item:.d3k6.smallkey.three] + +d3_spawn_8:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d3_spawn_8] +d3_spawn_8:1 -> [spawn:chest:ruby50..d3_r50.0] + +d3_spawn_9:0 -> [spawn:item:d.d3k7.smallkey.three] -> [sound:D360-02-02] -> [set:1] +d3_spawn_9:1 -> [spawn:item:.d3k7.smallkey.three] + +d3_spawn_10:0 -> [sound:D360-02-02] -> [set:1] +d3_spawn_10:1 -> + +d3_sound:0 -> [sound:D360-02-02] + +d3_instrument_music:d3_instrument:0 -> [music:23:2] +d3_instrument_music:0 -> + +d3_boss:0 -> [music:24:2] -> [freeze:250] -> d3_boss + +instrument2:0 -> [update_objects] -> instrument2 -> [set:owl:3_0] -> [set:ulrira_d3:0] -> [set:ulrira_d4:1] + +// dungeon breaks +d3_beak_1:0 -> [check_item:stonebeak:1:result] -> [path:d3_beak_1_result] +d3_beak_1_result:result:0 -> beak_nop +d3_beak_1_result:result:1 -> beak_d3_1 + +d3_beak_2:0 -> [check_item:stonebeak:1:result] -> [path:d3_beak_2_result] +d3_beak_2_result:result:0 -> beak_nop +d3_beak_2_result:result:1 -> beak_d3_2 + +d3_beak_3:0 -> [check_item:stonebeak:1:result] -> [path:d3_beak_3_result] +d3_beak_3_result:result:0 -> beak_nop +d3_beak_3_result:result:1 -> beak_d3_3 + +// only reshow the dialog after 600 seconds is passed +crystal_hard:0 -> [cooldown:600000:result] -> [path:crystal_hard_cooldown] +crystal_hard_cooldown:result:0 -> +crystal_hard_cooldown:result:1 -> crystal_hard + +cracked_rock:0 -> [cooldown:600000:result] -> [path:cracked_rock_cooldown] +cracked_rock_cooldown:result:0 -> +cracked_rock_cooldown:result:1 -> rock_cracks_message + +// == dungeon four == + +d4_beak_1:0 -> [check_item:stonebeak:1:result] -> [path:d4_beak_1_result] +d4_beak_1_result:result:0 -> beak_nop +d4_beak_1_result:result:1 -> beak_d4_1 + +d4k4spawn:0 -> [sound:D360-02-02] -> [set:1] +d4k4spawn:1 -> + +d4_nightmare:0 -> [music:24:2] -> [lock_player:500] -> d4_nightmare + +d4_instrument_music:d4_instrument:0 -> [music:23:2] +d4_instrument_music:0 -> + +instrument3:0 -> [update_objects] -> instrument3 -> [set:ulrira_d4:0] -> [set:ulrira_d5:1] -> [set:spawn_ghost:1] + + +// spawn the effect then the door +d4_spawn_stairs:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d4_spawn_stairs] +d4_spawn_stairs:1 -> [spawn:dungeon_6_stairs:] -> [spawn:light:64.255.255.255.75] -> [spawn:door:16.16.d4_2d_3r.dungeon4_2d_3$map.d4_2d_3r.-1.1.False] + + +// == dungeon five == + +beak_d5_1:0 -> [check_item:stonebeak:1:result] -> [path:beak_d5_1_result] +beak_d5_1_result:result:0 -> beak_nop +beak_d5_1_result:result:1 -> beak_d5_1 + +beak_d5_2:0 -> [check_item:stonebeak:1:result] -> [path:beak_d5_2_result] +beak_d5_2_result:result:0 -> beak_nop +beak_d5_2_result:result:1 -> beak_d5_2 + +master_stalfos_chest:0 -> [freeze:500] -> master_stalfos_3 + +d5_chest_0:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d5_chest_0] +d5_chest_0:1 -> [spawn:chest:stonebeak.five.d5_beak.0] + +d5_spawn_key_1:0 -> [spawn:item:d.d5_key_1.smallkey.five] -> [sound:D360-02-02] -> [set:1] +d5_spawn_key_1:1 -> [spawn:item:.d5_key_1.smallkey.five] + +slime_eel:0 -> [music:24:2] -> [freeze:250] -> slime_eel_0 + +d5_instrument_music:d5_instrument:0 -> [music:23:2] +d5_instrument_music:0 -> + +instrument4:0 -> [update_objects] -> instrument4 -> [set:ulrira_d5:0] -> [set:ulrira_d6:1] -> [set:owl:6_0] -> [set:ulrira_mamu:1] -> [set:npc_grandmother_moved:1] -> [path:instrument4Broom] + +// the trade could have already happend so we need to make sure to not set the again +instrument4Broom:missing_broom:0 -> [set:missing_broom:1] -> [path:grandma_gone_check] +instrument4Broom:0 -> [path:grandma_gone_check] + +// == dungeon six == + +d6_beak_1:0 -> [check_item:stonebeak:1:result] -> [path:d6_beak_1_result] +d6_beak_1_result:result:0 -> beak_nop +d6_beak_1_result:result:1 -> beak_d6_1 + +d6_beak_2:0 -> [check_item:stonebeak:1:result] -> [path:d6_beak_2_result] +d6_beak_2_result:result:0 -> beak_nop +d6_beak_2_result:result:1 -> beak_d6_2 + +d6_beak_3:0 -> [check_item:stonebeak:1:result] -> [path:d6_beak_3_result] +d6_beak_3_result:result:0 -> beak_nop +d6_beak_3_result:result:1 -> beak_d6_3 + +d6_etChest_0:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d6_etChest_0] +d6_etChest_0:1 -> [spawn:chest:dmap.six.d6_map.0] + +d6_smallkey_0_spawn:0 -> [sound:D360-02-02] -> [spawn:item:d.d6_smallkey_1.smallkey.six] -> [set:1] +d6_smallkey_0_spawn:1 -> [spawn:item:.d6_smallkey_1.smallkey.six] + +d6_smallkey_1_spawn:0 -> [sound:D360-02-02] -> [spawn:item:d.d6_smallkey_2.smallkey.six] -> [set:1] +d6_smallkey_1_spawn:1 -> [spawn:item:.d6_smallkey_2.smallkey.six] + +d6_button_sound_0:0 -> [sound:D360-02-02] -> [set:1] +d6_button_sound_0:1 -> + +d6_door_sound_0:0 -> [sound:D360-02-02] -> [set:1] +d6_door_sound_0:1 -> + +d6_door_sound_1:0 -> [sound:D360-02-02] -> [set:1] +d6_door_sound_1:1 -> + +// spawn a ladder +d6_ladder_spawn:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d6_ladder_spawn] +d6_ladder_spawn:1 -> [spawn:dungeon_6_stairs:.] -> [spawn:door:16.16.d6_2d_3R.dungeon6_2d_3$map.d6_2d_3R.0.1.False] -> [spawn:light:64.255.255.255.75] + +// start the boss music +d6_mboss_enter:d6_et_12:0 -> [music:79:2] +d6_mboss_enter:0 -> +// stop the boss music +d6_mboss_leave:0 -> [music:-1:2] +d6_mboss_killed:0 -> [music:-1:2] -> [sound:D360-02-02] + +facade_death:0 -> [countdown:750] -> [music:-1:-1] -> facade_death -> [wait:dialogOpen:0] -> [music:-1:2] + +d6_instrument_music:d6_instrument:0 -> [music:23:2] +d6_instrument_music:0 -> + +// change marin position +instrument5:0 -> [update_objects] -> instrument5 -> [set:owl:7_0] -> [set:hide_rabbit_0:0] -> [set:hide_rabbit_1:0] -> [set:hide_rabbit_2:0] -> [set:hide_rabbit_3:0] -> [set:rabbit_0:1] -> [set:rabbit_1:1] -> [set:rabbit_2:1] -> [set:rabbit_3:1] -> [maria:state:5] -> [set:npc_boy_0:1] -> [set:npc_boy_1:1] -> [set:npc_boy_2:2] -> [set:npc_boy_ball_left:1] -> [set:npc_boy_ball_right:1]-> [set:ulrira_d6:0] -> [set:ulrira_d7:1] -> [set:maria_state:hidden] + +// == dungeon seven == + +ow_d7_keyhole:0 -> [check_item:dkey5:1:result] -> [path:ow_d7_keyhole_check] +ow_d7_keyhole:1 -> + +ow_d7_keyhole_check:result:0 -> +ow_d7_keyhole_check:result:1 -> [set:ow_d7_tower:1] -> [set:d7_tower_keyhole:1] + +// why was this done like this??? +d7_et_0_init:0 -> [set:1] +d7_et_0_init:1 -> +d7_spawn_key_0:0 -> [sound:D360-02-02] -> [spawn:item:d.d7_smallkey_0.smallkey.seven] -> [set:1] +d7_spawn_key_0:1 -> [spawn:item:.d7_smallkey_0.smallkey.seven] + +d7_spawn_key_1:0 -> [sound:D360-02-02] -> [spawn:item:d.d7_smallkey_1.smallkey.seven] -> [set:1] +d7_spawn_key_1:1 -> [spawn:item:.d7_smallkey_1.smallkey.seven] + +d7_spawn_chest_0:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d7_spawn_chest_0] +d7_spawn_chest_0:1 -> [spawn:chest:dmap.seven.d7_map.0] + +d7_spawn_chest_1:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d7_spawn_chest_1] +d7_spawn_chest_1:1 -> [spawn:chest:compass.seven.d7_compass.0] + +d7_spawn_chest_2:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d7_spawn_chest_2] +d7_spawn_chest_2:1 -> [spawn:chest:bombChest.seven.d7_chestBomb.0] + +d7_spawn_chest_3_init:0 -> [set:1] +d7_spawn_chest_3_init:1 -> +d7_spawn_chest_3:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d7_spawn_chest_3] +d7_spawn_chest_3:1 -> [spawn:chest:nightmarekey.seven.d7_nkey.0] + +d7_spawn_chest_4:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d7_spawn_chest_4] +d7_spawn_chest_4:1 -> [spawn:chest:potion..d7_potion.0] + +beak_d7_1:0 -> [check_item:stonebeak:1:result] -> [path:beak_d7_1_result] +beak_d7_1_result:result:0 -> beak_nop +beak_d7_1_result:result:1 -> beak_d7_1 + +beak_d7_2:0 -> [check_item:stonebeak:1:result] -> [path:beak_d7_2_result] +beak_d7_2_result:result:0 -> beak_nop +beak_d7_2_result:result:1 -> beak_d7_2 + +beak_d7_3:0 -> [check_item:stonebeak:1:result] -> [path:beak_d7_3_result] +beak_d7_3_result:result:0 -> beak_nop +beak_d7_3_result:result:1 -> beak_d7_3 + +// tower collapse sequences +tower_collapse_sequence:0 -> [start_sequence:towerCollapse] -> [set:1] -> [set:seven_2_map:_alt] -> [set:seven_3_map:_alt] +tower_collapse_sequence:1 -> + +grim_creeper_enter:0 -> [freeze:250] -> grim_creeper_enter +grim_creeper_end:0 -> [freeze:250] -> grim_creeper_2 -> [wait:dialogOpen:0] -> [music:-1:2] + +grim_creeper_3:0 -> grim_creeper_3 -> [music:91:2] -> [wait:dialogOpen:0] -> [music:83:2] +grim_creeper_4:0 -> grim_creeper_4 -> [wait:dialogOpen:0] -> [music:-1:2] + +d7_instrument_music:d7_instrument:0 -> [music:23:2] +d7_instrument_music:0 -> + +beak_d8_1:0 -> [check_item:stonebeak:1:result] -> [path:beak_d8_1_result] +beak_d8_1_result:result:0 -> beak_nop +beak_d8_1_result:result:1 -> beak_d8_1 + +beak_d8_2:0 -> [check_item:stonebeak:1:result] -> [path:beak_d8_2_result] +beak_d8_2_result:result:0 -> beak_nop +beak_d8_2_result:result:1 -> beak_d8_2 + +beak_d8_3:0 -> [check_item:stonebeak:1:result] -> [path:beak_d8_3_result] +beak_d8_3_result:result:0 -> beak_nop +beak_d8_3_result:result:1 -> beak_d8_3 + +// remove the rooster +instrument6:0 -> [update_objects] -> instrument6 -> [remove_item:rooster:1:result] -> [set:has_rooster:0] -> [set:chicken_dude:2] -> [set:maria_state:5] -> [set:ulrira_d7:0] -> [set:ulrira_d8:1] + +// == dungeon eight == +turtle_rock_killed:0 -> [set:ulrira_d8:2] + +d8_et_0_sound:0 -> [set:1] -> [sound:D360-02-02] +d8_et_0_sound:1 -> + +d8_spawn_chest_0:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d8_spawn_chest_0] +d8_spawn_chest_0:1 -> [spawn:chest:ruby20..d8_ruby20.0] + +d8_spawn_chest_1:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [spawn:chest:smallkeyChest.eight.d8_smallkey_3.0] + +d8_spawn_chest_2:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d8_spawn_chest_2] +d8_spawn_chest_2:1 -> [spawn:chest:smallkeyChest.eight.d8_smallkey_5.0] + +d8_spawn_chest_3:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d8_spawn_chest_3] +d8_spawn_chest_3:1 -> [spawn:chest:nightmarekey.eight.d8_nkey.0] + +d8_spawn_key_0:0 -> [sound:D360-02-02] -> [set:1] -> [path:d8_spawn_key_0] +d8_spawn_key_0:1 -> [spawn:item:d.d8_smallkey_0.smallkey.eight] + +d8_spawn_key_1:0 -> [sound:D360-02-02] -> [set:1] -> [path:d8_spawn_key_1] +d8_spawn_key_1:1 -> [spawn:item:d.d8_smallkey_1.smallkey.eight] + +d8_spawn_key_2:0 -> [sound:D360-02-02] -> [set:1] -> [path:d8_spawn_key_2] +d8_spawn_key_2:1 -> [spawn:item:d.d8_smallkey_2.smallkey.eight] + +d8_spawn_key_3:0 -> [sound:D360-02-02] -> [set:1] -> [path:d8_spawn_key_3] +d8_spawn_key_3:1 -> [spawn:item:d.d8_smallkey_6.smallkey.eight] + +d8_secret_door:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:d8_secret_door] +d8_secret_door:1 -> [spawn:dungeon_6_stairs:] -> [spawn:light:64.255.255.255.75] -> [spawn:door:16.16.d8_2d_6L.dungeon8_2d_6$map.d8_2d_6L.0.1.False] + +// d8_smallkey_4 is in the chest with the block infront of + +hot_head:0 -> [music:79:2] -> [freeze:250] -> hot_head_0 +hot_head_death:0 -> hot_head_1 -> [wait:dialogOpen:0] -> [music:-1:2] + +d8_instrument_music:d8_instrument:0 -> [music:23:2] +d8_instrument_music:0 -> + +instrument7:0 -> [update_objects] -> instrument7 -> [set:ulrira_d8:0] -> [set:ulrira_d9:1] + +// == color dungeon == + +// entry npc blue +npc_color_blue:0 -> [dialog:choice:npc_color_0:choice_Red:choice_Blue] -> [path:npc_color_blue_chose] +npc_color_blue:1 -> +npc_color_blue_chose:choice:0 -> npc_color_1 +npc_color_blue_chose:choice:1 -> npc_color_2 -> [set:npc_color_blue:1] -> [path:npc_color_blue_m] + +// 0: start; 1: center; 2: side +npc_color_blue_m:npc_color_blue_state:0 -> [set:npc_color_blue_state:2] -> [set:npc_color_red_state:1] -> [set:npc_color_blue_move:1] -> [set:npc_color_red_move:1] +npc_color_blue_m:npc_color_blue_state:1 -> [set:npc_color_blue_state:2] -> [set:npc_color_blue_move:1] +npc_color_blue_m:npc_color_blue_state:2 -> + +// entry npc red +npc_color_red:0 -> [dialog:choice:npc_color_0:choice_Red:choice_Blue] -> [path:npc_color_red_chose] +npc_color_red:1 -> +npc_color_red_chose:choice:0 -> npc_color_2 -> [set:npc_color_red:1] -> [path:npc_color_red_m] +npc_color_red_chose:choice:1 -> npc_color_1 + +npc_color_red:0 -> [path:npc_color_red_m] +npc_color_red_m:npc_color_red_state:0 -> [set:npc_color_red_state:2] -> [set:npc_color_blue_state:1] -> [set:npc_color_red_move:1] -> [set:npc_color_blue_move:1] +npc_color_red_m:npc_color_red_state:1 -> [set:npc_color_red_state:2] -> [set:npc_color_red_move:1] +npc_color_red_m:npc_color_red_state:2 -> + +// both moved? +npc_color_3:npc_color_blue:1 -> npc_color_3 -> [sound:D360-02-02] +npc_color_3:0 -> npc_color_3 + +npc_color_4:npc_color_red:1 -> npc_color_4 -> [sound:D360-02-02] +npc_color_4:0 -> npc_color_4 + +// player cant move the last gravestone when he is with a follower +grave_locked:0 -> [cooldown:7500:result] -> [path:grave_locked_cooldown] +grave_locked_cooldown:result:0 -> +grave_locked_cooldown:result:1 -> grave_locked + +dc_entry:0 -> [sound:D360-02-02] -> [spawn:stairsCastle:.] -> [spawn:door:16.16..dungeon_color$map.dc_entry.3.1.False] + +dc_switch_1_sound:0 -> [sound:D360-02-02] -> [set:1] +dc_switch_1_sound:1 -> + +dc_spawn_chest_0:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:dc_spawn_chest_0] +dc_spawn_chest_0:1 -> [spawn:chest:compass.dColor.dc_compass.0] + +dc_spawn_chest_1:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:dc_spawn_chest_1] +dc_spawn_chest_1:1 -> [spawn:chest:stonebeak.dColor.dc_beak.0] + +dc_spawn_chest_2:0 -> [spawn:animatorL:3.Particles/spawn.run.True] -> [sound:D360-02-02] -> [set:1] -> [path:dc_spawn_chest_2] +dc_spawn_chest_2:1 -> [spawn:chest:dmap.dColor.dc_map.0] + +dc_spawn_key_0:0 -> [sound:D360-02-02] -> [set:1] -> [spawn:item:d.dc_smallkey_1.smallkey.dColor] +dc_spawn_key_0:1 -> [spawn:item:.dc_smallkey_1.smallkey.dColor] + +dc_spawn_key_1:0 -> [sound:D360-02-02] -> [set:1] -> [spawn:item:d.dc_smallkey_2.smallkey.dColor] +dc_spawn_key_1:1 -> [spawn:item:.dc_smallkey_2.smallkey.dColor] + +// beaks +beak_dc_1:0 -> [check_item:stonebeak:1:result] -> [path:beak_dc_1_result] +beak_dc_1_result:result:0 -> beak_nop +beak_dc_1_result:result:1 -> beak_dc_1 + +// hinox +stone_hinox:0 -> [update_objects] -> [music:79:2] -> [freeze:125] -> stone_hinox -> [wait:dialogOpen:0] + +// buzz blob +giant_buzz_blob_enter:0 -> [update_objects] -> [music:79:2] -> [freeze:125] -> giant_buzz_blob_enter -> [wait:dialogOpen:0] + +// nightmare +hardhit_beetle_enter:0 -> [update_objects] -> [music:24:2] -> [freeze:125] -> hardhit_beetle_0 -> [wait:dialogOpen:0] + +// fairy +color_fairy:0 -> [update_objects] -> [set:link_direction:1] -> [dialog:choice:color_fairy_0:choice_RED:choice_BLUE] -> [path:color_fairy_chose] +color_fairy_reask:0 -> [update_objects] -> [set:link_direction:1] -> [dialog:choice:color_fairy_1:choice_RED:choice_BLUE] -> [path:color_fairy_chose] + +// red +color_fairy_chose:choice:0 -> [update_objects] -> [dialog:choice:color_fairy_2:choice_NO:choice_YES] -> [path:color_fairy_red] +color_fairy_red:choice:0 -> [path:color_fairy_reask] +color_fairy_red:choice:1 -> [remove_item:cloakBlue:1:result] -> [add_item:cloakRed:1] + +// blue +color_fairy_chose:choice:1 -> [update_objects] -> [dialog:choice:color_fairy_2:choice_NO:choice_YES] -> [path:color_fairy_blue] +color_fairy_blue:choice:0 -> [path:color_fairy_reask] +color_fairy_blue:choice:1 -> [remove_item:cloakRed:1:result] -> [add_item:cloakBlue:1] + +cloak_blue:0 -> [update_objects] -> color_fairy_3 -> [set:cloak_transition:1] +cloak_red:0 -> [update_objects] -> color_fairy_3 -> [set:cloak_transition:1] + +// play music in the instrument room +dc_fairy_music:0 -> [music:11:2] + +// witch +// remove the toadstool and reactivate it again on the overworld +witch:0 -> [check_item:toadstool:1:hasToadstool] -> [set:ow_toadstool:0] -> [path:witchTrade] +witchTrade:hasToadstool:0 -> [update_objects] -> witch_0 +witchTrade:hasToadstool:1 -> [update_objects] -> [save_history:true] -> witch_1 -> [wait:dialogOpen:0] -> [remove_item:toadstool:1:result] -> [music_speed:2] -> [set:blockWitchDoor:1] -> [set:witchAnimation:mix] -> [freeze:witchFinished:1] -> [set:witchAnimation:idle] -> [set:witchFinished:0] -> [music_speed:1] -> witch_2 -> [wait:dialogOpen:0] -> [set:witch_lamp_lit:0] -> [set:blockWitchDoor:] -> [add_item:powderPD:20] -> [save_history:false] + +witch_lamp_lit:0 -> [update_objects] -> [countdown:350] -> witch_3 -> [set:1] +witch_lamp_lit:1 -> + +// cukeman +cukeman:0 -> cukeman_0 -> [set:1] +cukeman:1 -> cukeman_1 -> [set:2] +cukeman:2 -> cukeman_2 -> [set:3] +cukeman:3 -> cukeman_3 -> [set:0] + +// chicken dude in the mountains +chicken_dude:0 -> [update_objects] -> chicken_dude_0 +// link has the flying rooster +chicken_dude:1 -> [update_objects] -> chicken_dude_1 +chicken_dude:2 -> [update_objects] -> chicken_dude_2 + +// moblin cave +mc_entry:mc_enemies:1 -> [music:61:2] -> bow_wow_cave_entry -> [set:mc_room_1:0] -> [set:mc_room_2:1] -> [set:mc_room_3:1] +mc_entry:0 -> + +mc_boss_enter:0 -> [freeze:250] -> bow_wow_cave_boss +mc_boss_defeat:0 -> [set:mc_enemies:0] -> [music:-1:2] + +// save the bowwow if he is in the lost state +mc_bow_wow:bowWow:1 -> bow_wow_cave_bw -> [sound:D368-16-10] -> [set:villageAttacked:0] -> [set:ulrira:2_1] -> [set:npc_boy_ball_left:1] -> [set:npc_boy_ball_right:1] -> [set:bowWow:2] -> [set:has_bowWow:1] -> [set:owl:2_1] +mc_bow_wow:0 -> + +// monkey at the castle +castle_monkey:has_bowWow:0 -> [path:castle_monkey_start] +castle_monkey:has_bowWow:1 -> castle_monkey_bowwow + +castle_monkey_start:0 -> [check_item:trade3:1:result] -> [path:castle_monkey_trade] + +castle_monkey_trade:result:0 -> castle_monkey_hunger +castle_monkey_trade:result:1 -> [dialog:choice:castle_monkey_banana:choice_Yes:choice_No!] -> [path:castle_monkey_choice] + +castle_monkey_choice:choice:0 -> [save_history:true] -> [set:monkeyBusiness:1] -> [set:trade3:1] -> [remove_item:trade3:1:result] +castle_monkey_choice:choice:1 -> castle_monkey_hunger + +castle_monkey_business:0 -> castle_monkey_banana_yes -> [wait:dialogOpen:0] -> [music:53:2] -> [stop_music:16000:2] -> [set:1] -> [set:monkeyBusiness:2] +castle_monkey_business:1 -> castle_monkey_done -> [set:monkeyBusiness:3] -> [set:ulrira_banana:0] -> [set:ulrira_leafs:1] -> [save_history:false] + +// button that opens the front door +ow_castle_door:0 -> [freeze:500] -> [shake:1000:1:0:5:0] -> [sound:D378-17-11] -> [freeze:1250] -> castle_button -> [set:1] +ow_castle_door:1 -> + +castle_spawn_0:0 -> [spawn:item:d.goldLeaf0.goldLeaf.] -> [sound:D360-02-02] -> [set:1] +castle_spawn_0:1 -> [spawn:item:.goldLeaf0.goldLeaf.] + +// photo sequences +// tell the player how many photos are still left +photo_mouse_house:photo_count_increase:1 -> photo_left_11 +photo_mouse_house:photo_count_increase:2 -> photo_left_10 +photo_mouse_house:photo_count_increase:3 -> photo_left_9 +photo_mouse_house:photo_count_increase:4 -> photo_left_8 +photo_mouse_house:photo_count_increase:5 -> photo_left_7 +photo_mouse_house:photo_count_increase:6 -> photo_left_6 +photo_mouse_house:photo_count_increase:7 -> photo_left_5 +photo_mouse_house:photo_count_increase:8 -> photo_left_4 +photo_mouse_house:photo_count_increase:9 -> photo_left_3 +photo_mouse_house:photo_count_increase:10 -> photo_left_2 +photo_mouse_house:photo_count_increase:11 -> photo_left_1 +photo_mouse_house:photo_count_increase:12 -> photo_left_0 + +photo_count_increase:0 -> [set:1] +photo_count_increase:1 -> [set:2] +photo_count_increase:2 -> [set:3] +photo_count_increase:3 -> [set:4] +photo_count_increase:4 -> [set:5] +photo_count_increase:5 -> [set:6] +photo_count_increase:6 -> [set:7] +photo_count_increase:7 -> [set:8] +photo_count_increase:8 -> [set:9] +photo_count_increase:9 -> [set:10] +photo_count_increase:10 -> [set:11] +photo_count_increase:11 -> [set:12] + +// dont talk to the player when he has a follower +photo_mouse_house:has_bowWow:1 -> photo_mouse_follower +photo_mouse_house:has_ghost:1 -> photo_mouse_follower +photo_mouse_house:has_marin:1 -> photo_mouse_follower +photo_mouse_house:has_rooster:1 -> photo_mouse_follower + +// photo sequence 1 +photo_mouse_house:0 -> [update_objects] -> [save_history:true] -> [set:1] -> [set:photoMouseActive:1] -> [dialog:choice:photo_01_0:choice_YES:choice_NO] -> [path:photo_mouse_choice] +photo_mouse_house:1 -> photo_01_1 + +photo_mouse_choice:choice:0 -> photo_01_1 -> [set:photo_house_blocked:1] +photo_mouse_choice:choice:1 -> [dialog:choice:photo_01_5:choice_YES:choice_NO] -> [path:photo_mouse_2_choice] + +photo_mouse_2_choice:choice:0 -> photo_01_1 -> [set:photo_house_blocked:1] +photo_mouse_2_choice:choice:1 -> [update_objects] -> [set:photo_mouse_houseMove:-16,0,0.5] -> [freeze:50] -> [set:link_push:400] -> [dialog:choice:photo_01_5:choice_YES:choice_NO] -> [path:photo_mouse_3_choice] + +photo_mouse_3_choice:choice:0 -> photo_01_1 -> [set:photo_house_blocked:1] +photo_mouse_3_choice:choice:1 -> [update_objects] -> [set:photo_mouse_houseMove:-24,24,0.5] -> [freeze:1] -> [set:photo_mouse_houseMove:0,-28,0.5] -> [freeze:1650] -> [set:link_push:0,-18,400] -> [dialog:choice:photo_01_5:choice_YES:choice_NO] -> [path:photo_mouse_4_choice] + +photo_mouse_4_choice:choice:0 -> photo_01_1 -> [set:photo_house_blocked:1] +photo_mouse_4_choice:choice:1 -> [update_objects] -> [set:photo_mouse_houseMove:0,-16,0.5] -> [freeze:125] -> [set:link_push:0,-17,400] -> [dialog:choice:photo_01_5:choice_YES:choice_NO] -> [path:photo_mouse_5_choice] + +photo_mouse_5_choice:choice:0 -> photo_01_1 -> [set:photo_house_blocked:1] +photo_mouse_5_choice:choice:1 -> [update_objects] -> [set:photo_mouse_houseMove:0,-16,0.5] -> [freeze:150] -> [set:link_push:0,-17,400] -> [dialog:choice:photo_01_6:choice_Yes:choice_No_way] -> [path:photo_mouse_6_choice] + +photo_mouse_6_choice:choice:0 -> photo_01_1 -> [set:photo_house_blocked:1] +photo_mouse_6_choice:choice:1 -> [update_objects] -> photo_01_7 -> [wait:dialogOpen:0] -> [set:photo_mouse_houseMove:0,-16,0.5] -> [freeze:250] -> [set:link_push:0,-16,200] -> [freeze:250] -> [set:link_animation:pushed_over] -> photo_01_8 -> [wait:dialogOpen:0] -> [set:photo_1_alt:1] -> [set:photo_flash:1] -> [freeze:1000] -> [set:photo_mouse_houseMove:-26,0,1] -> [freeze:1] -> [path:photo_mouse_take_photo] + +photo_mouse_photo_0:0 -> [update_objects] -> [freeze:photo_mouse_houseMoving:0] -> [freeze:250] -> photo_01_2 -> [wait:dialogOpen:0] -> [set:photo_flash:1] -> [freeze:1000] -> [set:photo_mouse_houseMove:-26,0,1] -> [freeze:1] -> [set:photo_mouse_houseMove:0,-10,1] -> [path:photo_mouse_take_photo] +photo_mouse_take_photo:0 -> [update_objects] -> [freeze:photo_mouse_houseMoving:0] -> [set:photo_mouse_houseAnimation:stand_0] -> photo_01_3 -> [wait:dialogOpen:0] -> [set:spawned_photo_book:1] -> [freeze:500] -> [set:photo_mouse_houseAnimation:stand_2] -> photo_01_4 -> [set:photo_house_blocked:0] -> [wait:dialogOpen:0] -> [set:link_idle:1] -> [set:photo_1:1] -> [path:photo_count_increase] -> [save_history:false] + +// the player can not leave the house after triggering the sequence +photo_house_blockade:0 -> photo_01_9 + +// photo sequence Ulrich +photo_sequence_2:photoMouseActive:0 -> +photo_sequence_2:photoMouseActive:1 -> [path:photo_sequence_ulrich] + +photo_sequence_ulrich:0 -> [update_objects] -> [save_history:true] -> [set:1] -> [set:spawnMouseSeq2:1] -> [set:mouseSeq2Fade:-75] -> [set:mouseSeq2Move:-56,0,1] -> [freeze:mouseSeq2Moving:0] -> [freeze:500] -> [set:link_direction:2] -> photo_02_0 -> [wait:dialogOpen:0] -> [set:mouseSeq2Move:-10,0,1] -> [set:link_push:-10,0,200] -> [freeze:1] -> [freeze:mouseSeq2Moving:0] -> [set:mouseSeq2Animation:stand_1] -> [set:link_direction:1] -> photo_02_1 -> [wait:dialogOpen:0] -> [set:photo_flash:1] -> [freeze:350] -> [set:photo_5:1] -> [set:photoSequencePhoto:photo_5] -> [start_sequence:photo] -> [set:spawnMouseSeq2:0] -> [set:mouseSeq2Move:56,0,1] -> [freeze:350] -> [set:mouseSeq2Fade:75] -> [save_history:false] -> [path:photo_count_increase] +photo_sequence_ulrich:1 -> + +// photo sequence BowWow +start_BowWow_Seq:photoMouseActive:0 -> +start_BowWow_Seq:photoMouseActive:1 -> [path:photo_sequence_BowWow] +// check if BowWow is at the pool +photo_sequence_BowWow:bowWow:0 -> [path:photo_sequence_3] +photo_sequence_BowWow:bowWow:4 -> [path:photo_sequence_3] +photo_sequence_BowWow:0 -> + +photo_sequence_3:0 -> [save_history:true] -> [set:1] -> [set:photo_6:1] -> [start_sequence:bowWow] +photo_sequence_3:1 -> [set:2] -> photo_03_0 +photo_sequence_3:2 -> [set:3] -> photo_03_1 -> [freeze:1000] -> photo_03_2 +photo_sequence_3:3 -> [set:4] -> photo_03_3 +photo_sequence_3:4 -> [set:5] -> photo_03_4 -> photo_03_5 -> [path:photo_count_increase] +photo_sequence_3:5 -> [save_history:false] + +// photo castle sequence +photo_sequence_4:photoMouseActive:0 -> +photo_sequence_4:photoMouseActive:1 -> [path:photo_sequence_castle] + +photo_sequence_castle:1 -> +photo_sequence_castle:npc_frog_boy:1 -> [save_history:true] -> [set:1] -> [set:photo_10:1] -> [start_sequence:castle] -> [path:photo_count_increase] +photo_sequence_castle:0 -> + +castle_sequence:0 -> [music:63:2] -> [freeze:1000] -> [seq_lerp:castleLink:91:-35:0.325] -> [seq_play:castleLink:walk] -> [seq_lerp:castleMouse:22:0:0.255] -> [seq_play:castleMouse:walk_2] -> [freeze:castleMouseMoving:0] -> [seq_finish_animation:castleMouse:0] -> [freeze:1000] -> [seq_lerp:castleMouse:-32:0:0.25] -> [seq_play:castleMouse:walk_0] -> [freeze:castleMouseMoving:0] -> [seq_finish_animation:castleMouse:0] -> [freeze:castleLinkMoving:0] -> [seq_finish_animation:castleLink:0] -> photo_05_0 -> [wait:dialogOpen:0] -> [seq_lerp:castleBoy:-44:-14:0.325] -> [seq_play:castleBoy:walk] -> [freeze:castleBoyMoving:0] -> [seq_finish_animation:castleBoy:0] -> photo_05_1 -> [wait:dialogOpen:0] -> [seq_play:castleLink:forward] -> [seq_lerp:castleMouse:0:64:0.25] -> [seq_play:castleMouse:walk_3] -> [seq_lerp:castleBoy:-39:-11:0.325] -> [seq_play:castleBoy:walk] -> [freeze:castleBoyMoving:0] -> [seq_play:castleBoy:forward] -> photo_05_2 -> [wait:dialogOpen:0] -> [freeze:1000] -> [seq_play:castleLink:piece] -> [seq_play:castleBoy:piece] -> [freeze:750] -> [sound:D378-63-40] -> [seq_color:castleFlash:255:255:255:255:0] -> [freeze:125] -> [seq_color:castleFlash:0:0:0:0:150] -> [freeze:750] -> [seq_play:castleBoy:stand] -> photo_05_3 -> [wait:dialogOpen:0] -> [seq_play:castleLink:forward] -> [seq_lerp:castleBoy:-112:28:0.325] -> [seq_play:castleBoy:walk] -> [freeze:2500] -> [close_overlay] -> [music:-1:2] -> [save_history:false] + + +photo_sequence_grave:photoMouseActive:0 -> +photo_sequence_grave:photoMouseActive:1 -> [path:photo_sequence_grave_start] + +photo_sequence_grave_start:0 -> [save_history:true] -> [set:1] -> [set:photo_11:1] -> [start_sequence:gravestone] -> [path:photo_count_increase] +photo_sequence_grave_start:1 -> + +// photo sequence gravestone +seq_gravestone:0 -> [music:71:2] -> [seq_lerp:graveMouse:-64:0:0.325] -> [seq_play:graveMouse:walk_0] -> [freeze:graveMouseMoving:0] -> [seq_finish_animation:graveMouse:0] -> photo_06_0 -> [wait:dialogOpen:0] -> [seq_play:graveLink:right] -> photo_06_1 -> [wait:dialogOpen:0] -> [seq_lerp:graveMouse:-28:58:0.325] -> [seq_play:graveMouse:walk_0] -> [seq_lerp:graveLink:25:-5:0.325]] -> [seq_play:graveLink:walk] -> [freeze:graveLinkMoving:0] -> [seq_play:graveLink:forward] -> [freeze:graveMouseMoving:0] -> photo_06_2 -> [wait:dialogOpen:0] -> [seq_play:graveLink:lean] -> [freeze:1000] -> [sound:D378-63-40] -> [seq_color:gravePhotoFlash:255:255:255:255:0] -> [freeze:125] -> [seq_color:gravePhotoFlash:0:0:0:0:150] -> [seq_color:gravePhoto:255:255:255:255:0] -> [freeze:2000] -> [music:-1:2] -> [close_overlay] -> [save_history:false] + +// photo sequence zora +npc_zora_script:0 -> [check_item:trade13:1:result] -> [path:npc_zora_item_check] + +npc_zora_item_check:result:0 -> +npc_zora_item_check:result:1 -> [path:npc_zora_spawn] + +npc_zora_spawn:photoMouseActive:0 -> [path:npc_spawn_zora_normal] +npc_zora_spawn:photoMouseActive:1 -> [path:npc_zora_photo_sequence] + +npc_spawn_zora_normal:npc_spawn_zora:0 -> [update_objects] -> [set:npc_spawn_zora:1] -> [set:npc_zoraAnimation:spawn] -> [freeze:750] -> [set:npc_zoraAnimation:idle] +npc_spawn_zora_normal:0 -> + +npc_zora_photo_sequence:photo_9:0 -> [update_objects] -> [save_history:true] -> [set:1] -> [set:photo_9:1] -> [set:npc_spawn_zora:1] -> [set:npc_zoraAnimation:spawn] -> [freeze:750] -> [set:npc_zoraAnimation:idle] -> photo_11_0 -> [wait:dialogOpen:0] -> [set:spawnMouseZora:1] -> [set:mouseSeqZoraFade:-75] -> [set:mouseSeqZoraMove:0,-52,1] -> [freeze:1] -> [set:mouseSeqZoraMove:40,0,1] -> [freeze:mouseSeqZoraMoving:0] -> [set:mouseSeqZoraAnimation:stand_1] -> [freeze:500] -> photo_11_1 -> [wait:dialogOpen:0] -> [set:photo_flash:1] -> [freeze:1000] -> [set:photoSequencePhoto:photo_9] -> [start_sequence:photo] -> [set:spawnMouseZora:0] -> [set:mouseSeqZoraFade:75] -> [save_history:false] -> [path:photo_count_increase] +npc_zora_photo_sequence:photo_9:1 -> [path:npc_spawn_zora_normal] + +npc_zora:0 -> npc_zora + +// photo sequence mountain +mountain_mouse_seq:photoMouseActive:0 -> +mountain_mouse_seq:photoMouseActive:1 -> [path:start_mountain_seq] + +start_mountain_seq:0 -> [update_objects] -> [save_history:true] -> [freeze:500] -> [set:1] -> [set:photo_12:1] -> [set:mountain_beetle_hide:1] -> [set:spawnMouseMountain:1] -> [set:mouseSeqMountainFade:-75]] -> [set:mouseSeqMountainMove:96,0,1] -> [freeze:mouseSeqMountainMoving:0] -> [set:link_direction:0] -> photo_12_0 -> photo_12_1 -> photo_12_2 -> [freeze:dialogOpen:0] -> [set:mouseSeqMountainMove:-10,0,1] -> [set:mouseSeqMountainAnimation:walk_2] -> [freeze:1] -> [freeze:mouseSeqMountainMoving:0] -> photo_12_3 -> [freeze:dialogOpen:0] -> [set:mouseSeqMountainMove:-5,6,1] -> [set:mouseSeqMountainAnimation:duck] -> [freeze:1] -> [freeze:mouseSeqMountainMoving:0] -> photo_12_4 -> [freeze:dialogOpen:0] -> [set:mouseSeqMountainMove:0,48,1.5] -> [set:mouseSeqMountainAnimation:duck] -> [freeze:300] -> [set:photo_flash:1] -> [freeze:350] -> [set:photoSequencePhoto:photo_12] -> [start_sequence:photo] -> [set:spawnMouseMountain:0] -> [set:mouseSeqMountainFade:75] -> [set:mountain_beetle_hide:0] -> [save_history:false] -> [path:photo_count_increase] +start_mountain_seq:1 -> + + +// make sure to spawn the mouse before the real sequence is started when marin hits the ground +seq_fountain_mouse_spawn:1 -> +seq_fountain_mouse_spawn:has_marin:0 -> +seq_fountain_mouse_spawn:has_marin:1 -> [path:seq_fountain_mouse_spawn_2] +seq_fountain_mouse_spawn_2:photoMouseActive:0 -> +seq_fountain_mouse_spawn_2:photoMouseActive:1 -> [set:seq_fountain_mouse_spawn:1] -> [set:spawnMouseFountain:1] -> [set:mouseSeqFountainAnimation:stand_1] + +// photo sequence fountain: active when the player talked to the mouse and marin is following the player +seq_fountain:photoMouseActive:0 -> [path:sequence_fountain_marin] +seq_fountain:photoMouseActive:1 -> [path:photo_sequence_fountain] + +// marin falling on link +sequence_fountain_marin:fallen_on_link:0 -> [update_objects] -> [countdown:175] -> marin_fountain +sequence_fountain_marin:fallen_on_link:1 -> [update_objects] -> [set:link_animation:stunned] -> [freeze:500] -> photo_08_1 -> [wait:dialogOpen:0] -> [set:link_idle:1] + +// marin falling onto link; in the original the player can move and prevent the sequence from happening +photo_sequence_fountain:0 -> [update_objects] -> [save_history:true] -> [set:1] -> [set:photo_3:1] -> [set:link_animation:stunned] -> [freeze:500] -> photo_08_0 -> [wait:dialogOpen:0] -> [set:photo_flash:1] -> [freeze:250] -> photo_08_1 -> [wait:dialogOpen:0] -> [set:mouseSeqFountainMove:0,-48,1] -> [freeze:350] -> [set:link_idle:1] -> [freeze:mouseSeqFountainMoving:0] -> [set:spawnMouseFountain:0] -> [set:mouseSeqFountainFade:75] -> [save_history:false] -> [path:photo_count_increase] +photo_sequence_fountain:1 -> [path:sequence_fountain_marin] + + +// photo sequence weather bird +start_weather_bird_seq:photoMouseActive:0 -> +start_weather_bird_seq:photoMouseActive:1 -> [path:seq_weather_bird_marin] +seq_weather_bird_marin:has_marin:0 -> +seq_weather_bird_marin:has_marin:1 -> [path:photo_sequence_weather_bird] +photo_sequence_weather_bird:0 -> [save_history:true] -> [set:1] -> [set:photo_4:1] -> [start_sequence:weatherBird] -> [path:photo_count_increase] +photo_sequence_weather_bird:1 -> + +seq_weather_bird:0 -> [music:1:2] -> [seq_lerp:weatherBirdLink:130:0:0.5] -> [seq_lerp:weatherBirdMarin:133:0:0.5] -> [freeze:weatherBirdLinkMoving:0] -> [seq_play:weatherBirdLink:stand] -> [freeze:weatherBirdMarinMoving:0] -> [seq_play:weatherBirdMarin:stand] -> [seq_play:weatherBirdUlrich:walk] -> [seq_lerp:weatherBirdUlrich:-48:0:0.5] -> [freeze:weatherBirdUlrichMoving:0] -> [seq_play:weatherBirdUlrich:stopped] -> photo_09_0 -> [wait:dialogOpen:0] -> [seq_lerp:weatherBirdUlrich:-48:0:0.5] -> [seq_play:weatherBirdUlrich:walk] -> [freeze:weatherBirdUlrichMoving:0] -> [seq_play:weatherBirdUlrich:stand] -> [seq_lerp:weatherBirdLink:8:0:0.5] -> [freeze:100] -> [seq_lerp:weatherBirdMarin:-2:0:0.5] -> [freeze:100] -> [set:weatherBirdUlrichFront:1] -> photo_09_1 -> [wait:dialogOpen:0] -> [sound:D378-63-40] -> [seq_color:weatherBirdPhotoFlash:255:255:255:255:0] -> [freeze:125] -> [seq_color:weatherBirdPhotoFlash:0:0:0:0:150] -> [freeze:1000] -> photo_09_2 -> [wait:dialogOpen:0] -> [seq_lerp:weatherBirdUlrich:-128:0:0.5] -> [seq_play:weatherBirdUlrich:walk] -> [freeze:1500] -> [music:-1:2] -> [close_overlay] -> [save_history:false] + + +// photo sequence cliff +check_cliff_sequence:1 -> +check_cliff_sequence:photoMouseActive:1 -> [path:cliff_sequence_marin] +check_cliff_sequence:0 -> +cliff_sequence_marin:has_marin:0 -> +cliff_sequence_marin:has_marin:1 -> [save_history:true] -> [set:check_cliff_sequence:1] -> [set:photo_2:1] -> [start_sequence:marinCliff] + +seq_cliff:0 -> [music:77:2] -> [freeze:750] -> marin_cliff_0 -> [wait:dialogOpen:0] -> [freeze:125] -> marin_cliff_1 -> [wait:dialogOpen:0] -> [freeze:125] -> marin_cliff_2 -> [wait:dialogOpen:0] -> [freeze:125] -> marin_cliff_1 -> [wait:dialogOpen:0] -> [freeze:125] -> marin_cliff_3 -> [wait:dialogOpen:0] -> [freeze:125] -> marin_cliff_1 -> [wait:dialogOpen:0] -> [freeze:1500] -> marin_cliff_4 -> [wait:dialogOpen:0] -> [freeze:750] -> [sound:D378-63-40] -> [seq_color:cliffPhotoFlash:255:255:255:255:0] -> [freeze:125] -> [seq_color:cliffPhotoFlash:0:0:0:0:150] -> [freeze:750] -> marin_cliff_5 -> [wait:dialogOpen:0] -> [freeze:500] -> [music:-1:2] -> [close_overlay] -> [path:photo_count_increase] -> [save_history:false] + + +// photo sequence bridge +photo_sequence_bridge:photoMouseActive:0 -> npc_bridge_5 +photo_sequence_bridge:photoMouseActive:1 -> [save_history:true] -> [set:1] -> [set:bridge_photo:1] -> [set:photo_8:1] -> photo_10_0 -> npc_bridge_3 -> [wait:dialogOpen:0] -> [set:mouse_catch:1] -> [freeze:mouse_pulled:1] -> [music_speed:2] -> [freeze:1000] -> [set:npc_bridgeAnimation:pull] -> [freeze:750] -> npc_bridge_4 -> [wait:dialogOpen:0] -> [set:mousePullUp:1] -> [freeze:mousePulledUp:1] -> [set:npc_bridgeAnimation:pull_look] -> photo_10_1 -> [wait:dialogOpen:0] -> [freeze:1000] -> [set:fisherman_fall:1] -> [freeze:250] -> [set:photo_flash:1] -> [freeze:500] -> [set:photoSequencePhoto:photo_8] -> [start_sequence:photo] -> [freeze:125] -> [set:fisherman_reset:1] -> [path:photo_count_increase] -> [music_speed:1] -> [save_history:false] + + +// player enters the egg +egg_entry:0 -> map_wind_fishs_egg -> [set:ulrira_d9:2] + +// == final boss == +final_boss_intro:0 -> [music:92:2] -> [freeze:1000] -> final_boss -> [wait:dialogOpen:0] -> [music:34:2] + +// killed the final boss +final_boss_death:0 -> [save_history:true] -> [music:94:2] -> [countdown:1000] -> nightmareFinal1 -> [wait:dialogOpen:0] -> [countdown:750] -> [set:spawn_final_stairs:1] -> [set:1] -> [save_history:false] +final_boss_death:1 -> + +// final +// walk up into the final room +final_stairs:0 -> [save_history:true] -> [set:final_remove_wall:1] -> [set:link_move:0,-0.35] -> [lock_player:transition_ended:1] -> [set:hide_hud:1] + +// walk up the final room +final_stair_walk:0 -> [set:link_move_collision:0] -> [set:link_move:0,-0.5] -> [lock_player:link_move_collision:1] -> [path:final_stair_stand] +final_stair_stand:0 -> [set:link_animation:final_stand] -> [set:owl:final] + +owl:final -> [update_objects] -> owl_final -> [wait:dialogOpen:0] -> [path:final_windfish] + +final_windfish:0 -> [update_objects] -> [freeze:1000] -> [set:spawn_windfish:1] -> [freeze:4000] -> [sound:D370-23-17] -> final_windfish -> [wait:dialogOpen:0] -> [freeze:1000] -> [set:spawn_windfish:0] -> [freeze:4000] -> [path:final_instruments] +final_instruments:0 -> [update_objects] -> [sound:D370-23-17] -> final_instruments -> [wait:dialogOpen:0] -> [set:link_final:1] + +final:0 -> [start_sequence:final] + +final_show_map:0 -> [update_objects] -> [set:maria_sing_final:1] -> [freeze:17500] -> [set:tarinFinalAnimation:show]-> [set:tarinMushroomAnimation:show] + +// debug stuff +final_test_instrument:0 -> [set:link_final:1] + +final_test:0 -> [set:final_stair_stand:x] -> [start_sequence:final] +// [update_objects] -> [freeze:100] -> [set:link_final:1] +final_stair_stand:x -> diff --git a/bin/Data/ui.atlas b/bin/Data/ui.atlas new file mode 100644 index 0000000..a02e7e0 --- /dev/null +++ b/bin/Data/ui.atlas @@ -0,0 +1,8 @@ +1 +1 +inventory item selection:45,9,31,21,0,0 +save_icon:1,18,14,13,0,0 +ui heart:1,1,7,7,0,0 +ui letter:1,32,6,6,0,0 +ui ruby:1,9,7,7,0,0 +ui game over:0,39,78,24,0,0 diff --git a/bin/Data/ui.png b/bin/Data/ui.png new file mode 100644 index 0000000..1bbfdd0 Binary files /dev/null and b/bin/Data/ui.png differ diff --git a/bin/Debug/net6.0-windows/settings b/bin/Debug/net6.0-windows/settings new file mode 100644 index 0000000..25c7f52 --- /dev/null +++ b/bin/Debug/net6.0-windows/settings @@ -0,0 +1,35 @@ +b EnableShadows True +b Autosave True +b SmoothCamera True +b BorderlessWindowed True +b IsFullscreen False +b LockFPS True +i Version 1 +i GameScale 11 +i UIScale 0 +i MusicVolume 35 +i EffectVolume 35 +i CurrentLanguage 0 +i controlLeftkey0 37 +i controlLeftbutton0 4 +i controlRightkey0 39 +i controlRightbutton0 8 +i controlUpkey0 38 +i controlUpbutton0 1 +i controlDownkey0 40 +i controlDownbutton0 2 +i controlAkey0 83 +i controlAbutton0 4096 +i controlBkey0 68 +i controlBbutton0 8192 +i controlXkey0 65 +i controlXbutton0 16384 +i controlYkey0 87 +i controlYbutton0 32768 +i controlSelectkey0 32 +i controlSelectbutton0 32 +i controlStartkey0 13 +i controlStartbutton0 16 +f ControllerDeadzone 0.15 +s ContentPath ../../Data/ +s SavePath ../../SaveFiles/ diff --git a/packages.config b/packages.config new file mode 100644 index 0000000..6b7279b --- /dev/null +++ b/packages.config @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file